Naksyn

### TL;DR

Python might be used to run Cobalt Strike’s BOFs by using previous work from Trustedsec and FalconForce, one can pick a BOF and use BOF2Shellcode to embed the shellcode in a python injector. This brings some post-ex capabilities that could be added to existing frameworks or deployed from a gained foothold making use of a signed binary (python.exe) as a host process for running BOFs using local shellcode injection - PoC on my github.

### Intro

Python got great popularity as a C2 language in recent years and the offsec community brought many great projects like TrevorC2, WEASEL, pupy, etc. However, its popularity as a Windows-agent-language never really took off, mainly because of some significant limitations such as:

1. Final .exe size made huge because of Python interpreter dependencies to be included;
2. Ease of getting source code from Python artifacts;
3. Complexity of creating shellcode that executes python code.

This drawbacks stem from the fact that Python is an interpreted language, so you basically have to bring the python interpreter and its dependencies with you, wether you’re creating a stage(r) shellcode or an .exe to deliver. However, I would encompass these 3 big limitations under the “Getting Access” phase of an engagement since python will be basically ruled out if you’re trying to phish or exploit some vulnerability that requires stable and tiny shellcode.

But still, to me Python has so much yet to give during the “Post Exploitation” phase, because, well…“in the EDR era signed binaries are kings”, and it’s worth reminding that the official Python binary is signed indeed. It’s also worth mentioning that in enterprise environments devs do crazy stuff so Python is pretty common almost everywhere. Using python would be a viable way to blend-in on some machines, if we only had modern capabilities to leverage.

This thought has been placed in the backseats of my mind for quite some time, until I saw some recent brilliant projects that opened up some new avenues.

### PoC || GTFO

Earlier in 2021 Kevin Haubris from Trustedsec published a cool project called COFFloader, that basically lets you load and run Cobal Strikes Beacon Object Files (BOFs) outside of Cobalt Strike itself. Some weeks ago Gijs Hollestelle from Falconforce published BOF2Shellcode which essentially converts BOFs to raw shellcode and combines it with COFFLoader (converted too) in a way so that BOFs can be loaded by the same resulting shellcode.

Reading the FalconForce post (I highly encourage to do it also since Gijs described the whole process to get things working) I understood that one could simply run BOFs also with python by using the shellcode generated by BOF2Shellcode and the help of an injector. Let’s try this out. As an injector I opted for the local shellcode technique using HeapAlloc technique, to which I added a VirtualProtect to set execute-only permissions since this might be useful for evasion and shenanigans. Bear in mind that by using execute-only permissions you’re out in the cold if using self decoding shellcodes or more complex ones. This only works if the shellcode itself does not need WR permissions, and this might be the case with some BOFs. Here’s the python injector I used:

At this point one would just need to grab the shellcode from Bof2Shellcode using a BOF of our choice, so I opted for Trustedsec’s Tasklist and used bof2shellcode to generate the resulting shellcode, including the COFFLoader:

I then used msfvenom to make tasklist.x64.bin trivially embeddable in a python script:

So after pasting the shellcode into the python injector script let’s see the tasklist BOF coughed out by Python:

### Outro

I’ve always been amazed by crowdsourced capabilities and their integration into toolsets. Some time ago Joe Vest kickstarted a Community Kit, a central repository of extensions written by the user community to extend the capabilities of Cobalt Strike. These extensions are written by some of the smartest people in the industry and being able to leverage them into other C2s it’s undoubtedly a “must have” feature. Indeed, few days ago Moloch Added support for extensions/BOFs for the Sliver framework written in Go. The same capability could be leveraged with some effort on every C2 with Python-based agents and this post described one way to do it.