Implant-C2 HTTP API

These are the default endpoints for the implant HTTP server. These endpoints can and should be changed by modifying the server/config/profiles/default.yaml file.

Endpoint Verb Purpose Details
/c2/register POST Registers this implant  
/c2/checkin GET Checks in with the C2 to see if there are any tasks  
/c2/task POST Send the result of a task  

Crypto

All requests and responses after the initial registration are encrypted via libsodium Boxes. On the server side, each implant has a unique keypair. The server-side private key is stored in the the database, and the public key is sent to the implant during registration. All requests and responses with bodies are encrypted then Base64 encoded. Assume for all requests and response, the data has already been decoded and derypted.

This does not apply for registration

Examples

Authentication Implants can identify itself by setting the SESSID cookie to the implant’s ID. This value can be customized in the configuration file with the server.implant_id_cookie key.

/c2/register

This route allows implants to register with the server. The implant should send the following JSON object:

{
  "txid": "encrypted_base64_encoded_public_key"
}
Field Purpose
txid The Base64 encoded LibSodium public key to use for encryption from server -> implant, encrypted with the C2 registration password

Example responses:

  • 200:

    On successful registration:

    {
      "status": true,
      "k": "base64_encoded_server_public_key",
      "c": "base64_encoded_encrypted_maleable_config"
    }
    
    Field Purpose
    status true if registration was successful, false otherwise
    k The Base64 encoded LibSodium public key to use for encryption from implant -> server
    c The Base64 encoded maleable profile to use. This is encrypted with the key in k. See below and profile

    c decrypted would look something like:

    {
    "status": true,
    "id": "74a45dc8dbec3008e74f91da3d2d05fa",
    "config": {
        "cookie": "SESSID",
        "kill_date": "",
        "sleep_time": 60,
        "jitter": 0.1,
        ...
      }
    }
    
    Field Purpose
    status true if registration was successful, false otherwise
    id The implant ID
    config The maleable profile to use. See profile
  • 401: This can happen for a few reasons:

    • Empty request body or incorrect MIME type
    • Missing or invalid txid field
    • Improperly formatted public key
    • Public key already exists in the database

/c2/checkin

This endpoint is used to check in with the C2 server and pull down the next task, if there is one. The response will be encrypted with the key received during registration.

Example responses:

  • 200:

    If there are no tasks:

    {}
    

    If there is a task:

    {
    "args": ["ls", "-la"],
    "opcode": 0,
    "task_id": "8af2838e2d70e2222aeb66459cec096e"
    }
    

    See Task for more details on the job object. Results of a job should be sent back to the appropriate endpoint to mark the task as completed.

    For the meanining of opcodes, see opcodes.

/c2/task

This endpoint is used to send the results of a task back to the C2 server. The request body should be encrypted with the key received during registration, then base64 encoded.

Example request:

  {
    "status": true,
    "tid": "task_id_here",
    "output": "b64_output_here",
  }

If there is no output, set output to an empty string. If you’d like the output to be displayed in a table, output should be a JSON object (still base64 encoded).

Field Purpose
status true if the task was successful, false otherwise
tid The task ID
output The Base64 encoded output of the task

Example responses:

  • 200:
OK
  • 401:

This can happen for a few reasons:

  • Improperly formatted request body
  • Missing implant identification cookie
  • Implant with given ID doesn’t exist

Copyright © 2023 Carter Brainerd. All rights reserved.