Posh C2 - Command and Control


We have in the past decoded various C2 Frameworks like Empire, Koadic C3 and in this blog we are going to take a similar deep dive into understanding another popular C2 framework Posh C2. Posh is an open source framework available in Github, written in Python. It has been used by threat actors like APT33.

Posh C2 supports PowerShell and Dot Net based payloads and as for encryption techniques, it supports proper HTTP payload encryption (AES) with support for steganography on top of encryption for part of its communication. For our purpose, we will be taking a look at the HTTP based communincation and use the PowerShell payload provided by the framework for exploitation.


The PowerShell stager to be executed on the victim is base64 encoded. When we decode it we can see the server IP and the URI the stager needs to connect to embedded in it. Once executed, the staging phase of the C2 Communication starts.


The staging phase occurs over 3 pair of request and responses. We will call them Stage 0, Stage 1 and Stage 3 respectively -


The victim sends a GET request to the server, and the server responds with a base64 encoded payload.

When decoded, we observe the first base64 encoded 32 byte key “ICffT8NvMuaqdXxFprTGIjgSICyjLZE50NTm5pqAdYA=“ is embedded in the payload.

This is a small script which will be able to decrypt the next response from the server, since we see from the highlighted section above, it’s supposed to AES+CBC decrypt the response.


For the next pair of request and responses, the GET request from the victim has an encrypted and encoded cookie.

Since from the previous script we know the encryption technique to be followed is AES encryption. When we base64 decode and AES decrypt the cookie with the key exchanged earlier, we can examine the data.

So, the cookie is formed of various info about the victim machine

The server replies with a 35KB response, which is first base64 encoded then encrypted with the same technique and key and again base64 encoded.

When we decode and decrypt it, we can see it is has some more additional information embedded.


In the 3rd Request response, the victim sends GET request with the URI having the identifier assigned earlier (xtGKqmnvYbDG6wl). The server in responds with a ~70KB payload of the staging phase. This can also be decrypted with the same technique but with the second key which was exchanged in the previous exchange.

On decoding and decrypting, we can see, this large payload contains the logic for executing all the commands, tasks, and modules that will be commanded by the server. Instead of sending the command and task related scripts at the time of issuing a new task, POSHC2 has them preloaded on the victim.


After staging gets over, the victim starts sending out beacons to the server. In case the server doesn’t have any task for the victim, the server sends a default response to the beacon. There are a few default replies among which server sends back one randomly.

If the server does have some tasks, it issues tasks to the victim to execute. The victim executes them and returns the results. We will see it in detail in the next section.

Post Exploitation Commands Execution

This is the interaction where the server sends commands to the victim to execute some task. Let’s look at the network traffic in this scenario.


The victim sends a beacon to the server and the server sends the encrypted command payload.

If we Base64 decode and AES decrypt and then Base64 decode again, we can see the plaintext command. That's a lot of decoding and decrypting.

We can see two information in the decrypted command, first is the task number assigned to the task (00076), second is the actual module command (get-screenshot). One thing to note is that the payload only has the command name, not the script for executing the command, which indicates the script has been loaded beforehand on the victim itself (as we saw in Stage 2) unlike Koadic or Empire where the script for executing the command are sent in the payload at this stage.

Task Output

After executing the command the victim sends the output via POST request and the server sends a default reply.

The request has a cookie with a session ID. When we base64 decode and AES decrypt with the second key, we see the task ID (00076) to which the task output belongs.

The payload of the POST request which contains the task output is a bit complex to decrypt.

When we applied the corresponding decryption techniques in the reverse order, we can see the output getting decrypted.

This is the screenshot response, it’s a base64 encoded image. If we try to render it, we can see the image.

Some of the modules also send a POST request with payload - 123456PS C:\Users\ayan>654321, which seems to be like a message indicating the job has been started on the victim.

Decryption Flowchart

Here is a pictorial representation of the decryption process we discussed above -

Comprehensive Testing

ATI has released a very detailed implementations of Posh C2 Framework as part of BreakingPoint System’s updates.

The superflows released are heavily customizable allowing users from using their own keys for payload traffic encryption to using one of the many implemented post-exploitation modules supported by Koadic.

Use BreakingPoint’s huge collection of Security applications to do robust testing of your DUT against malicious traffic like Posh and much more. More Command-and-Control applications might be added in the future releases.

For more details about Keysight Breakingpoint, visit BreakingPoint. This concludes our little venture into understanding Posh C2.