Skip to content

Reverse DNS Listener for Built Agents

The DNS Listener establishes a DNS server on a specified port, managing data traffic with agents through DNS A & TXT requests. This provides very discreet communication channels between the C2 infrastructure and agents, blending with regular DNS traffic.

Plugin ID: shelldot.listener.agent-reverse-dns


Configuration Reference

Connection

Parameter Type Required Default Description
port int Yes - Port number the agent calls home to. Also the listener port unless bindToPort is set.
bindToPort int No null Port number the listener actually binds to. When null, the port value is used. Useful when a reverse proxy or redirector sits in front of the listener.
requestType string Yes - Type of DNS requests: A or TXT.
startTime string No - Optional UTC start time for the listener (e.g. 2025-04-10T11:02:09Z).
instantResponses bool No false When true, the agent sends data immediately. When false, the agent waits for the sleep timeout before responding - better OPSEC but higher latency.

Sleep

Parameter Type Required Default Description
sleep int Yes - Global base sleep time in seconds between agent requests. Can be overridden per callback group via dnsCallbacks[].sleep.
sleepRandom int No 0 Global jitter in seconds added to the sleep time. Can be overridden per callback group via dnsCallbacks[].sleepRandom.

Request Limits

Parameter Type Required Default Description
maxRequestPerCycle int No - Maximum number of DNS requests per one sleep cycle.
maxIpsPerResponse int No - For A type requests, maximum number of IP addresses per response.

Callback Groups (dnsCallbacks[])

Each callback group defines a set of domains the agent uses for DNS communication, along with independent sleep and rotation settings. Data is hidden in subdomain names of the configured domains.

Parameter Type Required Default Description
domains[] string[] Yes - Array of base domain names to use. Agent data is encoded as subdomain labels of these domains.
sleep int Yes - Base sleep time in seconds for this callback group.
sleepRandom int No 0 Jitter in seconds for this callback group.
resolver string No - Hardcoded endpoint for DNS requests. If not set, the system-wide resolver is used.
domainsRotation object No - Rotation rules for domain selection. See Rotation Rules.

Rotation Rules

Rotation rules define when the agent should switch to the next domain. This is used for resilience (failover to backup domains) and evasion (rotating through different domain names).

Rotation Object

Parameter Type Required Description
type string Yes Rotation strategy: FAILOVER, ROTATE, or RANDOM.
counter int Yes Numeric threshold that triggers a rotation. Interpretation depends on type.
unit string Yes Unit for the counter: TRIES, SECONDS, MINUTES, or HOURS.

Rotation Types

FAILOVER - Switch to the next domain after a number of consecutive failures.

  • Counter + TRIES: switch after N consecutive failed connection attempts
  • Counter + time unit: switch after N seconds/minutes/hours since the last successful connection

ROTATE - Switch to the next domain after a number of total attempts (successful or not).

  • Counter + TRIES: switch after every N connection attempts
  • Counter + time unit: switch after N seconds/minutes/hours since the last rotation

RANDOM - Switch randomly before each request.

  • The probability of switching is 1/counter per request
  • The unit value is ignored for this type

Rotation Examples

Scenario Type Counter Unit Behavior
Switch after 7 requests (success or fail) ROTATE 7 TRIES Cycles through domains every 7 attempts
Switch after 2 consecutive failures FAILOVER 2 TRIES Only switches when connectivity breaks
Switch after 3 min without success FAILOVER 3 MINUTES Time-based failover
Switch every hour ROTATE 1 HOURS Periodic rotation regardless of success
12.5% chance per request RANDOM 8 TRIES Random switching (1/8 probability)

Rotation Logic

The rotation logic mirrors the HTTP listener's approach, with reduced complexity. The HTTP listener supports rotation of both the host and the Host header; by contrast, the DNS listener can only rotate the domain name. For additional detail on the rotation model, see the HTTP listener documentation.

Counter independence

Each callback group maintains its own rotation counter independently. A successful connection resets the FAILOVER counter for that group but does not affect other groups.


Configuration Scenarios

Scenario 1 - Basic DNS Beaconing

The minimal configuration for an agent communicating over DNS. Suitable for lab environments or testing.

{
  "port": 53,
  "requestType": "TXT",
  "sleep": 30,
  "sleepRandom": 10,
  "instantResponses": false,
  "maxRequestPerCycle": 5,
  "maxIpsPerResponse": 3,
  "dnsCallbacks": [
    {
      "domains": ["c2.example.com"],
      "sleep": 30,
      "sleepRandom": 10
    }
  ]
}

Scenario 2 - Multi-Domain Failover

The agent rotates through multiple domains when connectivity fails. Designed for resilient operations where individual domains may get blocked or sinkholed.

{
  "port": 53,
  "requestType": "TXT",
  "sleep": 60,
  "sleepRandom": 20,
  "instantResponses": false,
  "maxRequestPerCycle": 3,
  "maxIpsPerResponse": 3,
  "dnsCallbacks": [
    {
      "domains": [
        "primary.example.com",
        "backup.example.com",
        "tertiary.example.com"
      ],
      "sleep": 60,
      "sleepRandom": 20,
      "resolver": "8.8.8.8",
      "domainsRotation": {
        "type": "FAILOVER",
        "counter": 3,
        "unit": "TRIES"
      }
    }
  ]
}

How it works:

  1. Agent sends DNS queries with data encoded as subdomains of primary.example.com
  2. After 3 consecutive failures, it switches to backup.example.com
  3. After 3 more consecutive failures, it moves to tertiary.example.com
  4. The cycle repeats - the agent keeps retrying all domains indefinitely
  5. A successful connection resets the failure counter for that domain

Tip

For maximum resilience, register domains across different registrars and TLDs. Combine with long sleep intervals to reduce detection surface during low-activity periods.


Scenario 3 - Periodic Domain Rotation

The agent periodically rotates through domains regardless of success, making traffic patterns harder to fingerprint.

{
  "port": 53,
  "requestType": "A",
  "sleep": 45,
  "sleepRandom": 15,
  "instantResponses": false,
  "maxRequestPerCycle": 4,
  "maxIpsPerResponse": 5,
  "dnsCallbacks": [
    {
      "domains": [
        "alpha.example.com",
        "bravo.example.com"
      ],
      "sleep": 45,
      "sleepRandom": 15,
      "domainsRotation": {
        "type": "ROTATE",
        "counter": 10,
        "unit": "TRIES"
      }
    }
  ]
}

Info

With ROTATE type, the agent switches domains every 10 requests whether they succeed or fail. This creates a more varied traffic pattern compared to FAILOVER, which only switches on failures.