ถอดรหัสคำสั่ง PowerShell จากกระบวนการที่กำลังทำงานอยู่
ตัวอย่างนี้ทำงานบนแพลตฟอร์ม Windows เท่านั้น
ในบางครั้ง คุณอาจมีกระบวนการ PowerShell ที่ทำงานอยู่ซึ่งใช้ทรัพยากรจำนวนมาก กระบวนการนี้อาจทำงานในบริบทของงาน Task Scheduler หรืองาน SQL Server Agent ในกรณีที่มีกระบวนการ PowerShell หลายกระบวนการทำงานอยู่ อาจเป็นเรื่องยากที่จะทราบว่ากระบวนการใดแสดงถึงปัญหา บทความนี้แสดงวิธีการถอดรหัสบล็อกสคริปต์ที่กระบวนการ PowerShell กำลังทำงานอยู่
สร้างกระบวนการที่ใช้เวลานาน
เพื่อสาธิตสถานการณ์นี้ ให้เปิดหน้าต่าง PowerShell ใหม่และเรียกใช้รหัสต่อไปนี้ โดยจะรันคำสั่ง PowerShell ที่จะส่งออกตัวเลขทุกๆ นาทีเป็นเวลา 10 นาที
powershell.exe -Command {
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}
}
ดูกระบวนการ
เนื้อความของคำสั่งที่ PowerShell กำลังดำเนินการถูกจัดเก็บไว้ในคุณสมบัติ CommandLine ของคลาส Win32_Process หากคำสั่งเป็นคำสั่งที่เข้ารหัส คุณสมบัติ CommandLine จะมีสตริง "EncodedCommand" การใช้ข้อมูลนี้ คำสั่งที่เข้ารหัสสามารถยกเลิกการสร้างความสับสนได้โดยผ่านกระบวนการต่อไปนี้
เริ่ม PowerShell ในฐานะผู้ดูแลระบบ จำเป็นอย่างยิ่งที่ PowerShell จะทำงานในฐานะผู้ดูแลระบบ ไม่เช่นนั้นจะไม่มีการส่งคืนผลลัพธ์เมื่อสอบถามกระบวนการที่กำลังทำงานอยู่
ดำเนินการคำสั่งต่อไปนี้เพื่อรับกระบวนการ PowerShell ทั้งหมดที่มีคำสั่งที่เข้ารหัส:
$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'
คำสั่งต่อไปนี้สร้างวัตถุ PowerShell แบบกำหนดเองที่มี ID กระบวนการและคำสั่งที่เข้ารหัส
$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++
}