PowerShell-parancs dekódolása futó folyamatbólDecode a PowerShell command from a running process

Időnként előfordulhat, hogy egy olyan PowerShell-folyamat fut, amely nagy mennyiségű erőforrást vesz fel.At times, you may have a PowerShell process running that is taking up a large amount of resources. Ez a [folyamat egy Feladatütemező][] feladat vagy egy SQL Server Agent feladat kontextusában futhat.This process could be running in the context of a Task Scheduler job or a SQL Server Agent job. Ha több PowerShell-folyamat fut, nehéz lehet megállapítani, hogy melyik folyamat jelenti a problémát.Where there are multiple PowerShell processes running, it can be difficult to know which process represents the problem. Ez a cikk bemutatja, hogyan lehet dekódolni egy olyan parancsfájl-blokkot, amelyen jelenleg fut egy PowerShell-folyamat.This article shows how to decode a script block that a PowerShell process is currently running.

Hosszú ideig futó folyamat létrehozásaCreate a long running process

A forgatókönyv bemutatásához nyisson meg egy új PowerShell-ablakot, és futtassa a következő kódot.To demonstrate this scenario, open a new PowerShell window and run the following code. Végrehajt egy PowerShell-parancsot, amely percenként 10 percen belül egy számot ad vissza.It executes a PowerShell command that outputs a number every minute for 10 minutes.

powershell.exe -Command {
    $i = 1
    while ( $i -le 10 )
    {
        Write-Output -InputObject $i
        Start-Sleep -Seconds 60
        $i++
    }
}

A folyamat megtekintéseView the process

Annak a parancsnak a törzse, amely a PowerShell-t futtatja, a Win32_Process osztály parancssori tulajdonságában tárolódik.The body of the command which PowerShell is executing is stored in the CommandLine property of the Win32_Process class. Ha a parancs egy kódolt parancs, a commandline tulajdonság a "EncodedCommand" karakterláncot tartalmazza.If the command is an encoded command, the CommandLine property contains the string "EncodedCommand". Ezeknek az információknak a használatával a kódolt parancs a következő folyamaton keresztül is eltorzítható.Using this information, the encoded command can be de-obfuscated via the following process.

Indítsa el a PowerShellt rendszergazdaként.Start PowerShell as Administrator. Létfontosságú, hogy a PowerShell rendszergazdaként fusson, ellenkező esetben a futó folyamatok lekérdezésekor nem ad vissza eredményt.It is vital that PowerShell is running as administrator, otherwise no results are returned when querying the running processes.

Hajtsa végre a következő parancsot, hogy beolvassa az összes olyan PowerShell-folyamatot, amely rendelkezik kódolt paranccsal:Execute the following command to get all of the PowerShell processes that have an encoded command:

$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'

A következő parancs egy egyéni PowerShell-objektumot hoz létre, amely a folyamat AZONOSÍTÓját és a kódolt parancsot tartalmazza.The following command creates a custom PowerShell object that contains the process ID and the encoded command.

$commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
@{
    name       = 'EncodedCommand'
    expression = {
        if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )
        {
            return $matches[1]
        }
    }
}

A kódolt parancs most dekódolható.Now the encoded command can be decoded. A következő kódrészlet megismétli a parancs részletei objektumát, dekódolja a kódolt parancsot, és további vizsgálat céljából visszaadja a dekódolt parancsot az objektumhoz.The following snippet iterates over the command details object, decodes the encoded command, and adds the decoded command back to the object for further investigation.

$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 $_.ProcessId } |
        Add-Member -MemberType NoteProperty -Name DecodedCommand -Value $decodedCommand
}
$commandDetails[0]

A dekódolású parancs mostantól áttekinthető a dekódolású Command tulajdonság kiválasztásával.The decoded command can now be reviewed by selecting the decoded command property.

ProcessId      : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
                 wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
                 AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
                 ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
                 IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
DecodedCommand :
                     $i = 1

                     while ( $i -le 10 )

                     {

                         Write-Output -InputObject $i

                         Start-Sleep -Seconds 60

                         $i++

                     }