Flare-On 8 Challenge 6 - PetTheKitty
Analysing TCP Stream
Looking through the wireshark capture, we can see a PNG file being transmitted.
We can extract the PNG file and keep it for use later.
Looking further into the stream, we notice an odd transmission going on:
The PA30
bytes stand out, and googling them reveals that they are binary deltas, and a blog post seemed to be interesting.
Within the blog, Jaime has kindly included a Python script that performs the binary patching using such delta files.
By using the provided script to apply the delta extracted from the packet capture with the PNG extracted earlier, it dumps out a DLL.
DLL Analysis
Analysing the DLL, a function that spawns a reverse shell is found.
A cmd.exe
process is created with the stdin and stdout handle redirected to the pipes create using CreatePipe
. This allows the DLL to act as the middleman between cmd.exe
and the socket, allowing for data to be passed between the 2.
Communication Mechanism
Within the reverse shell function, there exists 2 functions that handles the sending/receiving of data to/from the socket.
A deeper look into create_delta_and_send
reveals the following:
It encrypts the data being sent using simple XOR and calling CreateDeltaB
to generate delta patches.
The delta patches are then sent back to the C2 server via the socket.
For recv_and_apply_delta
:
Data is received from the socket, and ApplyDeltaB
is called to get back the plaintext command.
After getting back the plaintext command in v12
, it is then written into the stdin of the cmd.exe
process to be executed.
Decrypting the C2 Traffic
We now know that the data is encrypted via XOR being the delta is created. To get back the plaintext data, we can apply the delta, and perform the XOR with the array again, using the algorithm cipher ^ array[index%5]
.
A script can be adapted from delta_patch.py
to automate the patching and decryption of the traffic from the packet capture.
The script can be found on my github.
NOTE: I didn’t parse through the headers of the traffic to extract the size of each transmission/patch to dynamically build a buffer to hold the data. Hence, the resulting data from my script would include junk data at the end. I used grep
to search for the flag among all the data.