Dekodowanie polecenia programu PowerShell z uruchomionego procesu
Ten przykład działa tylko na platformach Windows.
Czasami może być uruchomiony proces programu PowerShell, który zajmuje dużą ilość zasobów. Ten proces może być uruchomiony w kontekście zadania harmonogramu zadań lub zadania agenta programu SQL Server. Jeśli jest uruchomionych wiele procesów programu PowerShell, trudno jest wiedzieć, który proces reprezentuje problem. W tym artykule pokazano, jak zdekodować blok skryptu, który jest obecnie uruchomiony przez proces programu PowerShell.
Tworzenie długotrwałego procesu
Aby zademonstrować ten scenariusz, otwórz nowe okno programu PowerShell i uruchom następujący kod. Wykonuje polecenie programu PowerShell, które generuje liczbę co minutę przez 10 minut.
powershell.exe -Command {
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}
}
Wyświetlanie procesu
Treść polecenia wykonywanego przez program PowerShell jest przechowywana we właściwości CommandLine klasy Win32_Process. Jeśli polecenie jest zakodowanym poleceniem, właściwość CommandLine zawiera ciąg "EncodedCommand". Korzystając z tych informacji, zakodowane polecenie można de-zaciemniać za pomocą następującego procesu.
Uruchom program PowerShell jako Administracja istrator. Ważne jest, aby program PowerShell był uruchomiony jako administrator. W przeciwnym razie podczas wykonywania zapytań dotyczących uruchomionych procesów nie są zwracane żadne wyniki.
Wykonaj następujące polecenie, aby pobrać wszystkie procesy programu PowerShell, które mają zakodowane polecenie:
$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'
Następujące polecenie tworzy niestandardowy obiekt programu PowerShell zawierający identyfikator procesu i zakodowane polecenie.
$commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
@{
name = 'EncodedCommand'
expression = {
if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )
{
return $matches[1]
}
}
}
Teraz zakodowane polecenie można dekodować. Poniższy fragment kodu iteruje obiekt szczegółów polecenia, dekoduje zakodowane polecenie i dodaje dekodowane polecenie z powrotem do obiektu w celu dalszego badania.
$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 *
Polecenie dekodowane można teraz przejrzeć, wybierając właściwość dekodowanego polecenia.
ProcessId : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
DecodedCommand :
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}