Reverse HTTP Listener for Built Agents
The HTTP Listener establishes an HTTP server on a specified port, managing data traffic with agents through HTTP or HTTPS connections. This provides secure and discreet communication channels between the C2 infrastructure and agents, blending with regular web traffic.
Plugin ID: shelldot.listener.agent-reverse-http
Configuration
The table below documents all available configuration parameters in a logical order:
Attribute | Explanation |
---|---|
port | Port number where the generated payload calls home. If bindToPort is set to null, it will also be the port that listener runs |
bindToPort | Port number where the listener actually runs. Default is "null", in that case the "port" variable is used |
https | Protocol flag (false = HTTP, true = HTTPS). |
startTime | Optional UTC start time (e.g., "2023-04-10T11:02:09Z"). |
getUri | URI used by the agent for GET requests when no data to send. |
postUri | URI used by the agent for sending data via POST (also receives data). |
stagedUri | URI requested for generating agent executable/dll/service/shellcode. |
stagedUriPayloadId | What GET parameter should containg id of the payload to download via stagedUri |
fileStorageUri | Base URI for retrieving files from file storage. |
metadataCookieName | Cookie name used to hold metadata. |
metadataPrefix | Prefix appended to metadata. |
metadataSuffix | Suffix appended to metadata. |
instantResponses | Boolean indicating if the agent sends data immediately or waits for the sleep timeout (for OPSEC). |
headers[ ] | Additional HTTP headers (array of objects with "name" and "value"). |
↳ name | Name of the header. |
↳ value | Value of the header. |
httpCallbacks[ ] | Array of callback configuration objects. |
↳ hosts[ ] | Array of IP addresses or hostnames the agent can use to connect. |
↳ sleep | Base sleep time (ms) between requests. |
↳ sleepRandom | Variation (ms) in the sleep time. |
↳ hostHeaders[ ] | Array of HTTP host header values used when connecting. |
↳ hostsRotation | Rotation rules for host selection. |
↳ type | Rotation method (FAILOVER, ROTATE, RANDOM). |
↳ counter | Numeric value indicating when to rotate hosts. |
↳ unit | Unit for the counter (TRIES, SECONDS, MINUTES, HOURS). |
↳ hostHeaderRotation | Rotation rules for host headers. |
↳ type | Rotation method for host headers (FAILOVER, ROTATE, RANDOM). |
↳ counter | Numeric value for header change frequency. |
↳ unit | Unit for the header counter (TRIES, SECONDS, MINUTES, HOURS). |
Rotation Rules
Rotation rules within the configuration are defined guidelines dictating when a listener's shellcode should alternate the host it connects to, or modify the HTTP host header within the request itself. This latter function is particularly useful for domain fronting, a technique employed to disguise the true destination of a web request.
Rule Type
This specifies the nature or category of the rotation rule. It determines the condition under which the rotation should occur, providing a contextual basis for the switch.
- FAILOVER - With this kind of rule, the switch to next host or host header will happen if agent is failed it's connection to C2 for given set of tries or given set of time.
- ROTATE - With this kind of rule, the switch to next host or host header will happen if agent is done (successful or not) given set of tries to connect to C2 or given set of time is passed.
- RANDOM - The switch to next host or host header happens in random. With this type, the unit value is not important and before every connection to C2, the listener shellcode will "throw a dice" and decides to switch or not. The chance for switching is 1/counter
Rule unit
This element provides a unit of measurement for the numeric value, offering a scale or dimension to the rule. It contextualizes the numeric value, whether it's time-based, or count-based.
- TRIES
- SECONDS
- MINUTES
- HOURS
Rule examples
Switch to next happens after 7 request to C2, no matter if they succeed or not
- type: ROTATE
- counter: 7
- unit: TRIES
Switch to next happens after 2 consecutive failed request to C2
- type: FAILOVER
- counter: 2
- unit: TRIES
Switch to next happens when there has been 3 minutes since last successful request to C2
- type: FAILOVER
- counter: 3
- unit: MINUTES
Switch to next happens when there has been 1 hour since last change
- type: ROTATE
- counter: 1
- unit: HOURS
Before every request there is 12.5% (1/8) possibility that switch is made
- type: RANDOM
- counter: 8
- unit: TRIES
Rotation Logic
The rotation logic in our system follows a specific workflow diagram, designed to guide the decision-making process for when and how the listener shellcode should switch its connection host or modify the HTTP host header.
Rotation Logic Example 1
In this simple example, let's consider a scenario where an agent is configured to alternate between two IP addresses for connection attempts, and it utilizes three different host header names. The rotation logic for this setup could be described as follows.
How it works:
- Agent starts with connection to IP 1.2.3.4 using host header "alpha"
- If connection to C2 fails 3 times straight (because hostHeaderRotation has "FAILOVER" type with counter 3)
- the host header "bravo" is now used
- connection to 1.2.3.4 remains same because hostsRotation rule is not yet reached
- If connection to C2 fails another 3 times straight (because hostHeaderRotation has "FAILOVER" type with counter 3)
- the host header "charlie" is now used
- connection to 1.2.3.4 still remains same because hostsRotation rule is still not yet reached
- If connection to C2 fails another 3 times straight then 2 rules are reached - the hostsRotation and hostHeaderRotation. In such situation hostHeaderRotation is ignored
- connection to 5.6.7.8 is now used
- hostHeaderRotation counters are reset and first value "alpha" is now used
- If connection to C2 fails another 3 times straight (because hostHeaderRotation has "FAILOVER" type with counter 3)
- the host header "bravo" is now used
- connection to 5.6.7.8 remains same because hostsRotation rule is not yet reached
- If connection to C2 fails another 3 times straight (because hostHeaderRotation has "FAILOVER" type with counter 3)
- the host header "charlie" is now used
- connection to 5.6.7.8 still remains same because hostsRotation rule is still not yet reached
- If connection to C2 fails yet another 3 times straight then 2 rules are again reached - the hostsRotation and hostHeaderRotation. Again hostHeaderRotation is ignored
- connection to 1.2.3.4 is now used - circular selection
- hostHeaderRotation counters are reset and first value "alpha" is now used
Extra notes
- The counters for host rotation and hostHeader rotations operate independently. In this scenario, if there are three failed connections followed by a successful connection, and then six subsequent failures, the connection will not switch to 5.6.7.8. This is because its counter resets after the successful connection. Similarly, the host header counters reset, but they are activated after every three consecutive failed connections. Consequently, in this specific case, the host header will have undergone three rotations, ultimately returning to the value "charlie."