Artifact Kit
Cobalt Strike has various flavour of EXEs and DLLs that are used within its workflows. It's common for users to not realise that these payloads work by injecting Beacon shellcode (into themselves, with the exception of the Service EXE). The Artifact Kit is designed to facilitate the development of AV-safe variants of these payloads based on the premise of loading said shellcode in a manner in which AV engines cannot emulate. It works on a system of "bypass templates" which allow you to change existing bypass strategies for reading shellcode, or implement entirely new ones.
The kit can be found in C:\Tools\cobaltstrike\arsenal-kit\kits\artifact
.
src-main/main.c
is the entry point for the EXE artifacts. It does nothing more than run a function called start
and then just loops to prevent the process from closing.
\
src-common/bypass-template.c
is not a "bypass", but it serves to show how one can implement some logic inside that start
function.
\
We can see that it grabs the payload buffer, copies it into memory, calls a spawn
function and then frees the buffer. Spawn and other parts of the program can be found in patch.c
and injector.c
, although we don't have to go deep into modifying these for basic AV signature evasion.
One of the bypass strategies included in the kit is called bypass-pipe
.
\
First, sprintf
is used to create a pseudo-random pipe name called \\.\pipe\netsvc\X (where X is a random integer). server_thread
will start a new named pipe server and copy the shellcode buffer into it. client_thread
will read the shellcode from the pipe and then call those same spawn & free functions.
So, the only difference between bypass-template and bypass-pipe is that memcpy is replaced with named pipes. Although there is some scope for detecting other aspects of this specific bypass technique, such as the pipe name. That is, of course, trivial to change here.
The Artifact Kit is designed to be built on Linux via the included build.sh
script. Running it without any arguments will show the usage.
\
It looks a bit scary at first, but each option is explained in the help.
The "techniques" are the bypass templates that you wish to compile. You can provide just one or a space-separated list.
The "allocator" defines the API used to allocate memory for the shellcode. The out-of-the-box options are HeapAlloc, VirtualAlloc **** and MapViewOfFile. These compiler directives are in patch.c
, where the spawn function has #if USE_HeapAlloc
/ #elif USE_VirtualAlloc
/ #elif USE_MapViewOfFile
code blocks. If you wanted to build a custom allocation, it would be here.
"Stage size" allocates the space required for Beacon's reflective DLL loader. This loader can be modified using the User Defined Reflective Loader (UDRL) Kit (out of scope for this course). If you're using a custom loader which pushes the size over the default loader size of 5K, then you need to provide the larger stage size here.
The "RDLL Size" option is used to sanity-check the value you provided for the "stage size". For example, if you specified 271360 for the stage size, but 100 for the RDLL size, the build script will abort and tell you that 271360 is not large enough for a 100K loader. Note that the "minimum" stage size can change between CS versions.
The "resource file" allows you to build the artifact with custom metadata - there is an included resource file at src-main/resource.rc
. You can modify this file to give the artifact different version numbers, product name, company name, and even an icon.
"Stack spoof" is a simple true/false option, which enables call stack spoofing whilst the Beacon is sleeping. This goes beyond the scope of this course, does not matter whether it's enabled or not for basic AV evasion.
The "output directory" is the location where you want the build artifacts to go.
\
This will build each variant of the EXE and DLL - staged, stageless, 32, and 64-bit. It will also produce an artifact.cna
file that we need to load into the Cobalt Strike UI. Go to Cobalt Strike > Script Manager > Load and select the CNA file in your output directory. Any DLL and EXE payloads that you generate from hereon will use those new artifacts. Use Payloads > Windows Stageless Generate All Payloads to replace all of your payloads in C:\Payloads
.
\
We can now PsExec to the file server.
\
To revert back to the default payloads, unload the script from the Script Manager (and in my experience, close and re-open the UI).
Last updated