Skip to content
Faction HTTP Transport Server
HTML C# Dockerfile
Branch: development
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode
Common
Config
Services
wwwroot
.gitignore
.mergify.yml
Dockerfile
LICENSE
Program.cs
README.md
Startup.cs
azure-pipelines.yml
httpserver.csproj
httpserver.sln

README.md

Repository Build Status
Master Master Build Status
Development Development Build Status

Overview

Faction supports a "plug and play" like framework for Transports, this project is a simple HTTP Server written in .NET Core configured to run as a Docker Container. Like Faction, this transport is designed to be flexible and compatible with any Faction agent that has a corresponding module. We've written a module for Marauder, our .NET based Faction agent that can be found here.

Getting Started

To get started, ensure you have Docker installed on a host you intend to serve as the Http Transport, then git pull this repo.

git clone https://github.com/FactionC2/TransportHTTP.git

Using an SSL Certificate

If you want to use a valid SSL Certificate, create the certificate and if necessary convert it to a .pfx file named cert.pfx, otherwise the installation will create a self signed SSL certificate.

To convert from openssl to .pfx:

openssl pkcs12 -export -out cert.pfx -inkey privateKey.key -in certificate.crt

Configuring the HTTP Transport

Then create a new Transport within the Faction Console as documented here. Update the Config/server.json file with the correct TransportId, FactionAPIKey, and FactionAPISecret as well as the URL of your Faction instance and the URLs for this HTTP Transport instance. These can be a either DNS or IP address, but should be begin with the protocol to use (http:// or https://), specify the port number if not default (:8443), and should not have a trailing slash (/).

Default Response

The DefaultResponse section details what to do with requests that aren't a Faction message. The following are valid configuration options:

Proxy a website

This will render a website in response to an invalid request. Users will stay on the URL they navigated to.

{
  "Action": "PROXY",
  "Value": "<URL TO PROXY>"
}

Redirect to a website

This will redirect the user to a different website

{
  "Action": "REDIRECT",
  "Value": "<URL TO REDIRECT TO>"
}

Render HTML

This will return the contents of an HTML file

{
  "Action": "HTML",
  "Value": "</path/to/html/file>"
}

Example Server Configuration:

{
  "Hosts": [
    "https://transport-url-01",
    "https://transport-url-02",
    "etc"
  ],
  "DefaultResponse": {
    "Action": "PROXY",
    "Value": "http://www.example.com"
  },
  "Port": 443,
  "UseSSL": false,
  "FactionURL": "https://<THE_URL_FOR_YOUR_FACTION_INSTANCE>",
  "TransportId": TRANSPORT_ID,
  "FactionAPIKey": "<THE_API_KEY_PROVIDED_BY_FACTION>",
  "FactionAPISecret": "<THE_API_SECRET_PROVIDED_BY_FACTION>"
}

Running the Transport

Finally, build and run the Docker container.

docker build -t transporthttp .

# Replace [PORT] below with the port your server will be 
# listening on, the same port that you entered in config.json
docker run -p [PORT]:[PORT] transporthttp

If using a custom SSL certificate, you can override the default SSL Certificate Path and Secret within Docker by overriding the enviornment variables FACTION_PFX_FILE and FACTION_PFX_SECRET as such:

docker run -d -p 443:443 -e "FACTION_PFX_FILE=./opt/faction/cert.pfx" -e "FACTION_PFX_SECRET=Sup3rS3cr3t" transporthttp

Customization

The transport is designed to support customization of how the Http Server and agent module communicate with each other. Settings for both the server and agent are defined within the Config/profile.json file.

Note that you'll have to restart the HTTP Transport for changes to this file to take effect, and any agents or payloads using the old profile will no longer work.

Example Profile

(Comments in the example below are for documentation purposes only and are not present or required in the actual profile)

{
  "Server": {
    "_urls_comment": "This section defines what URLs the agent should use to communicate with the server.
      Marauder's HTTP transport module is designed to pick one of these at random, and then
      combine it with a random hostname (defined in Config/server.json)",
    "URLs": [
      "/status/",
      "/update/",
      "/heartbeat/"
    ],
    "Headers": {
      "_comment": "These headers are added to every Server response",
      "Accept": "application/json",
      "X-Frame-Options": "deny",
      "X-Cache": "Hit"
    },
    "Cookies": {
      "_comment": "These cookies are set with each Server response",
    },

    "MessageConfig": {
      "_comment": "The message config defines how the server sends messages to the client
        If there is no message for that agent, the default string is sent. If there is a message,
        it is wrapped in the Prepend and Append values",
      "Default": "{\"Status\":\"Updated\"}",
      "Prepend": "{\"Status\":\"",
      "Append": "\"}"
    }
  },
  "Agent": {
    "Headers": {
      "_comment": "These headers are added to each request from the agent",
      "Accept": "application/json",
      "User-Agent": "Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko",
      "Authorization": "RWxpIGlzIGEgdmVyeSB2ZXJ5IGdvb2QgZG9nLg=="
    },
    "Cookies": {
      "_comment": "These cookies are included in each request from the agent",
      "Timestamp": "1990-01-01T00:00:00.000Z"
    },
    "StagingIdentifier": {
      "_comment": "This section defines where the staging identifier for the payload
        is placed when it sends a staging message. Valid options for location are 
        Header or Cookie",
      "Location": "Cookie",
      "Name": "AuthStatus"
    },
    "CheckinIdentifier": {
      "_comment": "This section defines where the agent name is placed in each
        each checkin from the agent. Valid options for location are 
        Header or Cookie",
      "Location": "Cookie",
      "Name": "SessionId"
    },
    "MessageConfig": {
      "_comment": "This section defines how a request to the transport server
        is formated. If there are no task results, the Default message is sent. 
        If there are results from a task to be sent to Faction it is wrapped 
        in the Prepend and Append values.",
      "Default": "{}",
      "Prepend": "{\"Update\":\"",
      "Append": "\"}"
    }
  }
}

Issues

Please submit any issues you have with Faction here and use the provided templates if applicable.

If you find a security related issue in Faction, please email it to jared at c2 dot lol. It's preferred that you use the following PGP key to encrypt your message, but by no means required.

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: OpenPGP.js v4.5.1
Comment: https://openpgpjs.org

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
f7RzcW5jaOtDB6KpkU54jg==
=FL5R
-----END PGP PUBLIC KEY BLOCK-----

IBM Corporation and the author are not responsible or liable for this code or its use cases currently.

You can’t perform that action at this time.