Mendekode perintah PowerShell dari proses yang sedang berjalan

Terkadang, Anda mungkin memiliki proses PowerShell yang berjalan yang mengambil sejumlah besar sumber daya. Proses ini dapat berjalan dalam konteks pekerjaan Penjadwal Tugas atau pekerjaan SQL Server Agent. Di mana ada beberapa proses PowerShell yang berjalan, mungkin sulit untuk mengetahui proses mana yang mewakili masalah. Artikel ini memperlihatkan cara mendekode blok skrip yang sedang dijalankan proses PowerShell.

Membuat proses yang berjalan lama

Untuk menunjukkan skenario ini, buka jendela PowerShell baru dan jalankan kode berikut. Ini menjalankan perintah PowerShell yang menghasilkan angka setiap menit selama 10 menit.

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

Menampilkan proses

Isi perintah yang dijalankan PowerShell disimpan di properti CommandLine dari kelas Win32_Process . Jika perintah adalah perintah yang dikodekan, properti CommandLine berisi string "EncodedCommand". Dengan menggunakan informasi ini, perintah yang dikodekan dapat di-de-obfuscated melalui proses berikut.

Mulai PowerShell sebagai Administrator. Sangat penting bahwa PowerShell berjalan sebagai administrator, jika tidak, tidak ada hasil yang dikembalikan saat mengkueri proses yang sedang berjalan.

Jalankan perintah berikut untuk mendapatkan semua proses PowerShell yang memiliki perintah yang dikodekan:

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

Perintah berikut membuat objek PowerShell kustom yang berisi ID proses dan perintah yang dikodekan.

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

Sekarang perintah yang dikodekan dapat didekodekan. Cuplikan berikut mengulangi objek detail perintah, mendekode perintah yang dikodekan, dan menambahkan perintah yang didekodekan kembali ke objek untuk penyelidikan lebih lanjut.

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

Perintah yang didekodekan sekarang dapat ditinjau dengan memilih properti perintah yang didekodekan.

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