Avkoda ett PowerShell-kommando från en process som körs
Det här exemplet körs bara på Windows-plattformar.
Ibland kan du ha en PowerShell-process som körs och som tar upp en stor mängd resurser. Den här processen kan köras i kontexten för en schemaläggaruppgift eller en SQL Server Agent-uppgift. Om det finns flera PowerShell-processer som körs kan det vara svårt att veta vilken process som representerar problemet. Den här artikeln visar hur du avkodar ett skriptblock som en PowerShell-process körs för närvarande.
Skapa en tidskrävande process
Om du vill demonstrera det här scenariot öppnar du ett nytt PowerShell-fönster och kör följande kod. Det kör ett PowerShell-kommando som matar ut ett tal varje minut i 10 minuter.
powershell.exe -Command {
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}
}
Visa processen
Brödtexten i kommandot som PowerShell kör lagras i egenskapen CommandLine för klassen Win32_Process. Om kommandot är ett kodat kommando innehåller egenskapen CommandLine strängen "EncodedCommand". Med den här informationen kan det kodade kommandot avdunklaras via följande process.
Starta PowerShell som administratör. Det är viktigt att PowerShell körs som administratör, annars returneras inga resultat när du kör frågor mot de processer som körs.
Kör följande kommando för att hämta alla PowerShell-processer som har ett kodat kommando:
$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'
Följande kommando skapar ett anpassat PowerShell-objekt som innehåller process-ID:t och det kodade kommandot.
$commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
@{
Name = 'EncodedCommand'
Expression = {
if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )
{
return $Matches[1]
}
}
}
Nu kan det kodade kommandot avkodas. Följande kodfragment itererar över kommandoinformationsobjektet, avkodar det kodade kommandot och lägger till det avkodade kommandot tillbaka till objektet för vidare undersökning.
$commandDetails | ForEach-Object -Process {
# Get the current process
$currentProcess = $_
# Convert the Base 64 string to a Byte Array
$commandBytes = [System.Convert]::FromBase64String($currentProcess.EncodedCommand)
# Convert the Byte Array to a string
$decodedCommand = [System.Text.Encoding]::Unicode.GetString($commandBytes)
# Add the decoded command back to the object
$commandDetails |
Where-Object -FilterScript { $_.ProcessId -eq $currentProcess.ProcessId } |
Add-Member -MemberType NoteProperty -Name DecodedCommand -Value $decodedCommand
}
$commandDetails[0] | Format-List -Property *
Det avkodade kommandot kan nu granskas genom att välja den avkodade kommandoegenskapen.
ProcessId : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
DecodedCommand :
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}