Created
September 9, 2022 17:28
-
-
Save passthehashbrowns/a6f46856219ef353be2e49bf323f173d to your computer and use it in GitHub Desktop.
This is a reimplementation of the bof_pack function in Aggressor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Custom function to pack our arguments for BOFs | |
#Usage: Call it the same way you would call bof_pack | |
sub custom_pack { | |
local('$beaconId $formatString $formatStringFixed @argsFixed $totalSize $shiftCounter $index $binarySize $packedData') | |
#We don't really need this but keeping it so the calling convention is the same | |
$beaconId = $1; | |
#Our original format string | |
$formatString = $2; | |
#Format string placeholder since we need to modify the values | |
$formatStringFixed = ''; | |
#Drop the beacon ID and format string from our args, so that we just have the args to be packed | |
#We could add a flatten call here if we wanted to pass in an array in the args too | |
@argsFixed = sublist(@_, 2); | |
#Calculate our total size, which gets packed at the end | |
$totalSize = 0; | |
#Whenever we add an item to the list we need to keep track of that to keep referencing the correct index | |
$shiftCounter = 0; | |
#Iterate through our format string and access the relevant data to be packed | |
for ($index = 0; $index < strlen($formatString); $index++){ | |
#If we have an int | |
if((charAt($formatString, $index) cmp "i") == 0){ | |
$totalSize += 4; | |
$formatStringFixed = $formatStringFixed . 'i'; | |
} | |
#If we have a short | |
if((charAt($formatString, $index) cmp "s") == 0){ | |
$totalSize += 2; | |
$formatStringFixed = $formatStringFixed . 's'; | |
} | |
#If we have binary data | |
if((charAt($formatString, $index) cmp "b") == 0){ | |
$binarySize = strlen(@argsFixed[$index + $shiftCounter]); | |
$totalSize += $binarySize; #Size of our binary data | |
#We need to pack the size of the data ahead of the data | |
$formatStringFixed = $formatStringFixed . 'i'; | |
add(@argsFixed, $binarySize, $index + $shiftCounter); | |
$shiftCounter++; | |
#Z indicates that we'll specify how many bytes to read | |
$formatStringFixed = $formatStringFixed . 'Z' . $binarySize; | |
} | |
#If we have a normal string | |
if((charAt($formatString, $index) cmp "z") == 0){ | |
$totalSize += strlen(@argsFixed[$index + $shiftCounter]) + 1; #Size of the string + a null terminator | |
#We need to pack the size of the string ahead of the actual string | |
$formatStringFixed = $formatStringFixed . 'i'; | |
add(@argsFixed, strlen(@argsFixed[$index + $shiftCounter]) + 1, $index + $shiftCounter); | |
$shiftCounter++; | |
#z is read characters until null byte | |
$formatStringFixed = $formatStringFixed . 'z'; | |
} | |
#If we have a wide string | |
if((charAt($formatString, $index) cmp "Z") == 0){ | |
$totalSize += strlen(@argsFixed[$index + $shiftCounter]) * 2 + 2; #Size of the string + a null terminator (2 since it's UTF-16) | |
#We need to pack the size of the string ahead of the actual string | |
$formatStringFixed = $formatStringFixed . 'i'; | |
add(@argsFixed, strlen(@argsFixed[$index + $shiftCounter]) * 2 + 2, $index + $shiftCounter); | |
$shiftCounter++; | |
#u is read UTF-16 characters until null byte, and it needs to be little endian | |
$formatStringFixed = $formatStringFixed . 'u-'; | |
} | |
} | |
#Add our total size to the args | |
push(@argsFixed, $totalSize); | |
#Add our size int to the format string | |
$formatStringFixed = $formatStringFixed . "i"; | |
#Need to reverse this, just how pack works I guess | |
@argsFixed = reverse(@argsFixed); | |
#Pack our data | |
$packedData = pack($formatStringFixed, @argsFixed); | |
#Not really sure why but we need to trim off the last 4 | |
$packedData = substr($packedData, 0, strlen($packedData) - 4); | |
return $packedData; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment