Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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 odszyfrować przy użyciu następującego procesu.
Uruchom program PowerShell jako administrator. 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 zawierający szczegóły polecenia, dekoduje zakodowane polecenie i ponownie dodaje je do obiektu w celu dalszej analizy.
$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++
}