Share via


실행 중인 프로세스에서 PowerShell 명령 디코딩

이 샘플은 Windows 플랫폼에서만 실행됩니다.

경우에 따라 많은 양의 리소스를 차지하는 PowerShell 프로세스가 실행될 수 있습니다. 이 프로세스는 작업 스케줄러 작업 또는 SQL Server 에이전트 작업의 컨텍스트에서 실행될 수 있습니다. 실행 중인 PowerShell 프로세스가 여러 개 있는 경우 문제를 나타내는 프로세스를 알기 어려울 수 있습니다. 이 문서에서는 PowerShell 프로세스가 현재 실행 중인 스크립트 블록을 디코딩하는 방법을 보여줍니다.

장기 실행 프로세스 만들기

이 시나리오를 설명하기 위해 새 PowerShell 창을 열고 다음 코드를 실행합니다. 10분 동안 1분마다 숫자를 출력하는 PowerShell 명령을 실행합니다.

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

프로세스 보기

PowerShell이 실행 중인 명령의 본문은 Win32_Process 클래스의 CommandLine 속성에 저장됩니다. 명령이 인코딩된 명령인 경우 CommandLine 속성에는 문자열 "EncodedCommand"가 포함됩니다. 이 정보를 사용하면 다음 프로세스를 통해 인코딩된 명령을 난독 처리 해제할 수 있습니다.

관리자 권한으로 PowerShell을 시작합니다. PowerShell은 관리자 권한으로 실행 중이어야 합니다. 그렇지 않으면 실행 프로세스를 쿼리할 때 결과가 반환되지 않습니다.

다음 명령을 실행하여 인코딩된 명령이 있는 모든 PowerShell 프로세스를 가져옵니다.

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

다음 명령은 프로세스 ID 및 인코딩된 명령을 포함하는 사용자 지정 PowerShell 개체를 만듭니다.

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

이제 인코딩된 명령을 디코딩할 수 있습니다. 다음 코드 조각은 명령 세부 정보 개체에서 반복되고, 인코딩된 명령을 디코드하고, 추가 조사를 위해 디코드된 명령을 다시 개체에 추가합니다.

$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 *

이제 디코드된 명령 속성을 선택하여 디코드된 명령을 검토할 수 있습니다.

ProcessId      : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
                 wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
                 AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
                 ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
                 IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
DecodedCommand :
                     $i = 1
                     while ( $i -le 10 )
                     {
                         Write-Output -InputObject $i
                         Start-Sleep -Seconds 60
                         $i++
                     }