SeeTwo
Can you see who is in command and control? - by hadrian3689
Last updated
Can you see who is in command and control? - by hadrian3689
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
In this scenario, we take on the role of a member of the digital forensic team and are tasked with looking at some suspicious network activity. The zip file that is created in the room contains a PCAP file. In this, we can see traffic on port 22, possibly SSH, which we have no access to, and a single large HTTP request containing a lot of base64-encoded data.
When we exclude the ports mentioned first, we also find traffic on port 1337.
If we follow the TCP stream by clicking on one of those packets, we can see that the data that is transferred here is base64-encoded. Nothing is conspicuous at first glance. Scrolling through the following TCP stream, you will find some requests with two base64-encoded strings, recognizable by the padding string ==
.
If we decode this using CyberChef, it suggests that we generate a raw image from the decoded binary data. We can detect at least three images. A milk bottle...
A green bear,
... and a poke ball. But here we can see something else. At the end, we see the padding encoding two times. Interesting. But we move on, since that data seems to be just gibberish after decoding.
We head back to the HTTP request. We can see that a base64_client
endpoint was requested. Furthermore, we can assume that this might be binary data, bas64-encoded. As indicated in the room, this may be a C2: Can you see who is in command and control?
SeeTwo
A C2, or command and control, refers to a system used by attackers to maintain communications with compromised machines, allowing them to remotely control, exfiltrate data, or manage malware operations.
We can export the Object via the following path:
File -> Export Objects -> HTTP
After we have saved the file on our system, we decode it and then check it. It actually is an executable binary.
This appears to reference Python C API functions and error handling messages.
Using strings would have revealed this too...
It is not recommended, but the execution also points to a Python executable.
The binary might be packaged with PyInstaller. Then pyinstxtractor
can extract the .pyc
files, which we can then decompile.
We use pyinstxtractor
to extract the archive.
With that we are able to decompile the .pyc
files.
ChatGPT suggests to use uncompyle6, so we give it a try. First, we need to install it.
After that we can run uncompyle6
on client.pyc
. In client_extracted
should now be client.py.
After decompilation we are able to investigate what the client actually does. It sets up a socket connection to a remote server, to a host at IP address 10.0.2.64
on port 1337
. It functions as a remote command-and-control client that securely receives commands from a server, executes them locally, and transmits the encrypted results back. The data transmitted is somewhat obfuscated, an encoded image is concatenated with an encoded command, separated by "AAAAAAAAAA"
.
The command itself is XOR encrypted and base64 encoded.
We investigate the traffic on port 1337 again.
And follow the TCP stream on packet 1594 again. And we can see after AAAAAAAAAA
there is the command.
The following shows an example script that accepts base64, decodes it and decrypts the xor encoding. Here we can see its command id.
We have a total of two TCP streams, starting at 1594
and 1706
.
We follow both.
And save the content to a text file.
Checking the first base64 string of the data, we can see the magic bytes for a PNG file.
We know from the source of client.py that every AAAAAAAAAAAA
is followed by the command, which is then followed by the magic bytes of the image. From this, we can build a regex that filters out only the commands from the data stream. We then decode and decrypt the command using the key in client.py.
After running the script we are able to answer all questions from the task.