From a28a10478d42521d36d4a711915a6d2af021ab12 Mon Sep 17 00:00:00 2001 From: anti Date: Sat, 18 Apr 2026 06:05:00 -0400 Subject: [PATCH] Unit 5: Services catalog and per-service personas --- Service-Personas.md | 164 +++++++++++++++++++++++ Services-Catalog.md | 312 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 476 insertions(+) create mode 100644 Service-Personas.md create mode 100644 Services-Catalog.md diff --git a/Service-Personas.md b/Service-Personas.md new file mode 100644 index 0000000..b12f6bd --- /dev/null +++ b/Service-Personas.md @@ -0,0 +1,164 @@ +# Service Personas + +Every service plugin receives an optional `service_cfg` dict built from the +INI persona block `[decky.]`. This page lists **only** the knobs the +plugin source actually reads. Anything you find elsewhere and don't see here +is not wired in; file an issue or a plugin PR instead. + +See also: + +- [INI format](INI-Config-Format) — top-level INI schema +- [Services catalog](Services-Catalog) — slugs, ports, build context +- [Custom services](Custom-Services) — BYOS knobs +- [Writing a plugin](Writing-a-Service-Plugin) — adding new knobs + +Every snippet below is a `[decky.]` INI subsection — drop it under the +matching `[decky.]` block in your deployment INI. + +## Services with no INI knobs + +These plugins do not read anything from `service_cfg` in source. Declaring +them under `[decky.]` with `services = ` is enough; no persona +block is required. + +- `rdp` +- `vnc` +- `smb` +- `ftp` +- `tftp` +- `postgres` +- `mssql` +- `mongodb` +- `elasticsearch` +- `imap` +- `pop3` +- `ldap` +- `conpot` +- `mqtt` +- `sip` +- `snmp` +- `docker_api` +- `k8s` +- `llmnr` +- `sniffer` + +## ssh + +Reads from `service_cfg`: + +- `password` — root password baked into the sshd image (default `admin`) +- `hostname` — override container hostname (shown to attacker in the shell + prompt / `uname -n`) + +```ini +[decky.01.ssh] +password = P@ssw0rd2019! +hostname = mail-gw-03 +``` + +## telnet + +Reads from `service_cfg`: + +- `password` — root password (default `admin`) +- `hostname` — override container hostname + +```ini +[decky.02.telnet] +password = cisco +hostname = edge-rtr-07 +``` + +## http + +Reads from `service_cfg`: + +- `server_header` — value of the HTTP `Server:` response header +- `response_code` — default status code for the root path +- `fake_app` — label for the pretend application (served via the template) +- `extra_headers` — dict or JSON-encoded string of additional response headers +- `custom_body` — override response body text +- `files` — host path to a directory bind-mounted read-only at + `/opt/html_files` inside the container + +```ini +[decky.03.http] +server_header = Apache/2.4.41 (Ubuntu) +response_code = 200 +fake_app = phpMyAdmin 4.9.5 +custom_body =

It works!

+files = /srv/decnet/fake-www/corp-intranet +``` + +## https + +Reads from `service_cfg` — same as `http`, plus TLS overrides: + +- `server_header` +- `response_code` +- `fake_app` +- `extra_headers` +- `custom_body` +- `files` +- `tls_cert` — path or PEM material for the TLS certificate +- `tls_key` — path or PEM material for the TLS key +- `tls_cn` — Common Name for a self-signed cert generated at startup + +```ini +[decky.04.https] +server_header = nginx/1.18.0 +response_code = 403 +fake_app = Jenkins 2.387.3 +tls_cn = portal.corp.local +``` + +## mysql + +Reads from `service_cfg`: + +- `version` — advertised MySQL server version string + +```ini +[decky.05.mysql] +version = 5.7.38-log +``` + +## redis + +Reads from `service_cfg`: + +- `version` — advertised Redis version +- `os_string` — advertised OS string in `INFO server` output + +```ini +[decky.06.redis] +version = 6.2.7 +os_string = Linux 5.15.0-101-generic x86_64 +``` + +## smtp + +Reads from `service_cfg`: + +- `banner` — SMTP `220` greeting banner +- `mta` — advertised MTA software / version + +```ini +[decky.07.smtp] +banner = mail.corp.local ESMTP Postfix (Debian/GNU) +mta = Postfix 3.5.13 +``` + +## smtp_relay + +Inherits the `smtp` template with `SMTP_OPEN_RELAY=1` hard-wired. Reads from +`service_cfg`: + +- `banner` — SMTP `220` greeting banner +- `mta` — advertised MTA software / version + +```ini +[decky.08.smtp_relay] +banner = relay.corp.local ESMTP +mta = Sendmail 8.15.2 +``` diff --git a/Services-Catalog.md b/Services-Catalog.md new file mode 100644 index 0000000..c5455cd --- /dev/null +++ b/Services-Catalog.md @@ -0,0 +1,312 @@ +# Services Catalog + +DECNET ships 29 built-in honeypot service plugins under `decnet/services/`. Each +plugin is a `BaseService` subclass auto-discovered by +`decnet/services/registry.py` at import time. This page is the canonical +inventory: slug, default ports, underlying image / build context, a one-line +description, and a link to the per-service persona knobs. + +Related pages: + +- [INI format](INI-Config-Format) — how persona blocks are parsed +- [Custom services](Custom-Services) — BYOS from INI +- [Writing a plugin](Writing-a-Service-Plugin) — subclassing `BaseService` +- [Service personas](Service-Personas) — per-service INI knobs + +All services are built from a local Dockerfile under `templates//` unless +noted otherwise. `default_image = "build"` in the catalog below means +"build from `templates//Dockerfile`". + +## Summary table + +| Category | Slug | Ports | Image / Build context | Description | +|---|---|---|---|---| +| Remote access | [ssh](#ssh) | 22/tcp | `templates/ssh/` | Real OpenSSH sshd with rsyslog forwarding and SFTP file-catcher | +| Remote access | [telnet](#telnet) | 23/tcp | `templates/telnet/` | Interactive telnetd with password capture | +| Remote access | [rdp](#rdp) | 3389/tcp | `templates/rdp/` | RDP front-end decoy | +| Remote access | [vnc](#vnc) | 5900/tcp | `templates/vnc/` | VNC authentication decoy | +| File sharing | [smb](#smb) | 445, 139/tcp | `templates/smb/` | Samba share bait | +| File sharing | [ftp](#ftp) | 21/tcp | `templates/ftp/` | FTP login decoy | +| File sharing | [tftp](#tftp) | 69/udp | `templates/tftp/` | TFTP read/write decoy | +| Web | [http](#http) | 80, 443/tcp | `templates/http/` | HTTP persona with configurable Server header, body, fake app | +| Web | [https](#https) | 443/tcp | `templates/https/` | HTTPS persona, TLS cert/key overridable | +| Databases | [mysql](#mysql) | 3306/tcp | `templates/mysql/` | MySQL handshake decoy, version spoofable | +| Databases | [postgres](#postgres) | 5432/tcp | `templates/postgres/` | PostgreSQL decoy | +| Databases | [mssql](#mssql) | 1433/tcp | `templates/mssql/` | Microsoft SQL Server decoy | +| Databases | [mongodb](#mongodb) | 27017/tcp | `templates/mongodb/` | MongoDB decoy | +| Databases | [redis](#redis) | 6379/tcp | `templates/redis/` | Redis decoy, version/OS string spoofable | +| Databases | [elasticsearch](#elasticsearch) | 9200/tcp | `templates/elasticsearch/` | Elasticsearch REST decoy | +| Mail | [smtp](#smtp) | 25, 587/tcp | `templates/smtp/` | SMTP MTA decoy with banner/MTA spoofing | +| Mail | [smtp_relay](#smtp_relay) | 25, 587/tcp | `templates/smtp/` | SMTP open-relay bait (reuses smtp template with `SMTP_OPEN_RELAY=1`) | +| Mail | [imap](#imap) | 143, 993/tcp | `templates/imap/` | IMAP mailstore decoy | +| Mail | [pop3](#pop3) | 110, 995/tcp | `templates/pop3/` | POP3 mailstore decoy | +| Directory/auth | [ldap](#ldap) | 389, 636/tcp | `templates/ldap/` | LDAP/LDAPS directory decoy | +| IoT / ICS | [conpot](#conpot) | 502, 161, 80 | `templates/conpot/` (wraps `honeynet/conpot:latest`) | ICS/SCADA honeypot (Modbus, SNMP, HTTP) | +| IoT / ICS | [mqtt](#mqtt) | 1883/tcp | `templates/mqtt/` | MQTT broker decoy | +| IoT / ICS | [sip](#sip) | 5060/udp | `templates/sip/` | SIP/VoIP decoy | +| IoT / ICS | [snmp](#snmp) | 161/udp | `templates/snmp/` | SNMP agent decoy | +| Cloud / orchestration | [docker_api](#docker_api) | 2375, 2376/tcp | `templates/docker_api/` | Exposed Docker daemon socket bait | +| Cloud / orchestration | [k8s](#k8s) | 6443, 8080/tcp | `templates/k8s/` | Kubernetes API server decoy | +| Others | [llmnr](#llmnr) | 5355, 5353/udp | `templates/llmnr/` | LLMNR/mDNS/NBNS poisoning detector | +| Others | [sniffer](#sniffer) | — (passive) | `templates/sniffer/` | Passive MACVLAN TLS/JA3 sniffer (fleet singleton) | + +## Remote access + +### ssh + +- **Slug**: `ssh` +- **Ports**: 22/tcp +- **Image**: build from `templates/ssh/` +- **Description**: Real OpenSSH sshd (not Cowrie) with rsyslog-to-stdout RFC 5424 + forwarding, sudo and command auditing, plus a bind-mounted file-catcher + quarantine under `/var/lib/decnet/artifacts//ssh` that masquerades + inside the container as `/var/lib/systemd/coredump`. +- **Persona**: see [ssh persona](Service-Personas#ssh). + +### telnet + +- **Slug**: `telnet` +- **Ports**: 23/tcp +- **Image**: build from `templates/telnet/` +- **Description**: Interactive telnetd honeypot. Captures credentials and + commands entered after login. +- **Persona**: see [telnet persona](Service-Personas#telnet). + +### rdp + +- **Slug**: `rdp` +- **Ports**: 3389/tcp +- **Image**: build from `templates/rdp/` +- **Description**: RDP front-end decoy — accepts connection attempts and logs + credentials from the negotiation phase. +- **Persona**: no INI knobs wired in code. + +### vnc + +- **Slug**: `vnc` +- **Ports**: 5900/tcp +- **Image**: build from `templates/vnc/` +- **Description**: VNC authentication decoy. +- **Persona**: no INI knobs wired in code. + +## File sharing + +### smb + +- **Slug**: `smb` +- **Ports**: 445/tcp, 139/tcp +- **Image**: build from `templates/smb/` +- **Description**: Samba share bait. Logs all SMB sessions and file-access + attempts. +- **Persona**: no INI knobs wired in code. + +### ftp + +- **Slug**: `ftp` +- **Ports**: 21/tcp +- **Image**: build from `templates/ftp/` +- **Description**: FTP login decoy. +- **Persona**: no INI knobs wired in code. + +### tftp + +- **Slug**: `tftp` +- **Ports**: 69/udp +- **Image**: build from `templates/tftp/` +- **Description**: TFTP read/write decoy, records filenames and payloads. +- **Persona**: no INI knobs wired in code. + +## Web + +### http + +- **Slug**: `http` +- **Ports**: 80/tcp, 443/tcp +- **Image**: build from `templates/http/` +- **Description**: HTTP persona with configurable `Server` header, response + code, body, fake-app label, extra headers, and an optional static-file + directory bind-mounted into the container. +- **Persona**: see [http persona](Service-Personas#http). + +### https + +- **Slug**: `https` +- **Ports**: 443/tcp +- **Image**: build from `templates/https/` +- **Description**: HTTPS persona, same knobs as `http` plus TLS cert/key/CN + overrides. +- **Persona**: see [https persona](Service-Personas#https). + +## Databases + +### mysql + +- **Slug**: `mysql` +- **Ports**: 3306/tcp +- **Image**: build from `templates/mysql/` +- **Description**: MySQL handshake decoy. Version string spoofable. +- **Persona**: see [mysql persona](Service-Personas#mysql). + +### postgres + +- **Slug**: `postgres` +- **Ports**: 5432/tcp +- **Image**: build from `templates/postgres/` +- **Description**: PostgreSQL decoy. +- **Persona**: no INI knobs wired in code. + +### mssql + +- **Slug**: `mssql` +- **Ports**: 1433/tcp +- **Image**: build from `templates/mssql/` +- **Description**: Microsoft SQL Server decoy. +- **Persona**: no INI knobs wired in code. + +### mongodb + +- **Slug**: `mongodb` +- **Ports**: 27017/tcp +- **Image**: build from `templates/mongodb/` +- **Description**: MongoDB wire-protocol decoy. +- **Persona**: no INI knobs wired in code. + +### redis + +- **Slug**: `redis` +- **Ports**: 6379/tcp +- **Image**: build from `templates/redis/` +- **Description**: Redis decoy. Version and OS string spoofable. +- **Persona**: see [redis persona](Service-Personas#redis). + +### elasticsearch + +- **Slug**: `elasticsearch` +- **Ports**: 9200/tcp +- **Image**: build from `templates/elasticsearch/` +- **Description**: Elasticsearch REST decoy. +- **Persona**: no INI knobs wired in code. + +## Mail + +### smtp + +- **Slug**: `smtp` +- **Ports**: 25/tcp, 587/tcp +- **Image**: build from `templates/smtp/` +- **Description**: SMTP MTA decoy. Banner and advertised MTA name spoofable. +- **Persona**: see [smtp persona](Service-Personas#smtp). + +### smtp_relay + +- **Slug**: `smtp_relay` +- **Ports**: 25/tcp, 587/tcp +- **Image**: build from `templates/smtp/` (same context as `smtp`; + `SMTP_OPEN_RELAY=1`) +- **Description**: SMTP open-relay bait — accepts any `RCPT TO`, used to + identify spam-relay abuse attempts. +- **Persona**: see [smtp_relay persona](Service-Personas#smtp_relay). + +### imap + +- **Slug**: `imap` +- **Ports**: 143/tcp, 993/tcp +- **Image**: build from `templates/imap/` +- **Description**: IMAP mailstore decoy. +- **Persona**: no INI knobs wired in code. + +### pop3 + +- **Slug**: `pop3` +- **Ports**: 110/tcp, 995/tcp +- **Image**: build from `templates/pop3/` +- **Description**: POP3 mailstore decoy. +- **Persona**: no INI knobs wired in code. + +## Directory / auth + +### ldap + +- **Slug**: `ldap` +- **Ports**: 389/tcp, 636/tcp +- **Image**: build from `templates/ldap/` +- **Description**: LDAP/LDAPS directory decoy. +- **Persona**: no INI knobs wired in code. + +## IoT / ICS + +### conpot + +- **Slug**: `conpot` +- **Ports**: 502/tcp, 161/udp, 80/tcp +- **Image**: build from `templates/conpot/` wrapping + `honeynet/conpot:latest` +- **Description**: ICS/SCADA honeypot covering Modbus, SNMP, and HTTP. The + custom build context fixes Modbus binding on port 502. +- **Persona**: no INI knobs wired in code. + +### mqtt + +- **Slug**: `mqtt` +- **Ports**: 1883/tcp +- **Image**: build from `templates/mqtt/` +- **Description**: MQTT broker decoy. +- **Persona**: no INI knobs wired in code. + +### sip + +- **Slug**: `sip` +- **Ports**: 5060/udp +- **Image**: build from `templates/sip/` +- **Description**: SIP/VoIP decoy. +- **Persona**: no INI knobs wired in code. + +### snmp + +- **Slug**: `snmp` +- **Ports**: 161/udp +- **Image**: build from `templates/snmp/` +- **Description**: SNMP agent decoy. +- **Persona**: no INI knobs wired in code. + +## Cloud / orchestration + +### docker_api + +- **Slug**: `docker_api` +- **Ports**: 2375/tcp, 2376/tcp +- **Image**: build from `templates/docker_api/` +- **Description**: Exposed Docker daemon socket bait — attackers love an + open `/var/run/docker.sock`. +- **Persona**: no INI knobs wired in code. + +### k8s + +- **Slug**: `k8s` +- **Ports**: 6443/tcp, 8080/tcp +- **Image**: build from `templates/k8s/` +- **Description**: Kubernetes API server decoy. +- **Persona**: no INI knobs wired in code. + +## Others + +### llmnr + +- **Slug**: `llmnr` +- **Ports**: 5355/udp (LLMNR), 5353/udp (mDNS) +- **Image**: build from `templates/llmnr/` +- **Description**: LLMNR/mDNS/NBNS poisoning detector. Incoming + name-resolution queries are a strong indicator of Responder-style tooling + on the LAN. +- **Persona**: no INI knobs wired in code. + +### sniffer + +- **Slug**: `sniffer` +- **Ports**: none (passive) +- **Image**: build from `templates/sniffer/` +- **Description**: Passive network sniffer deployed alongside deckies on the + MACVLAN. Extracts JA3/JA3S hashes and connection metadata. Requires + `NET_RAW` + `NET_ADMIN`. Marked `fleet_singleton = True` — one instance + fleet-wide. +- **Persona**: no INI knobs wired in code.