wiki: archetypes, distro profiles, OS fingerprint spoofing
60
Archetypes.md
Normal file
60
Archetypes.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Archetypes
|
||||||
|
|
||||||
|
An **archetype** is a pre-packaged identity for a decky: a realistic combination
|
||||||
|
of services, a preferred distro rotation, and a TCP/IP OS fingerprint that makes
|
||||||
|
a decoy look like a specific class of machine without the user picking each piece
|
||||||
|
by hand.
|
||||||
|
|
||||||
|
Source of truth: `decnet/archetypes.py`.
|
||||||
|
|
||||||
|
## INI snippet
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[corp-desktops]
|
||||||
|
archetype=windows-workstation
|
||||||
|
amount=4
|
||||||
|
|
||||||
|
[edge]
|
||||||
|
archetype=deaddeck
|
||||||
|
amount=1
|
||||||
|
```
|
||||||
|
|
||||||
|
See [INI format](INI-Config-Format). Archetypes can also be selected via
|
||||||
|
`decnet deploy --archetype <slug>` or rotated automatically with
|
||||||
|
`--randomize-services`.
|
||||||
|
|
||||||
|
## Registered archetypes
|
||||||
|
|
||||||
|
| Slug | Display name | Services | Preferred distros | nmap_os |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `windows-workstation` | Windows Workstation | smb, rdp | debian, ubuntu22 | windows |
|
||||||
|
| `windows-server` | Windows Server | smb, rdp, ldap | debian, ubuntu22 | windows |
|
||||||
|
| `domain-controller` | Domain Controller | ldap, smb, rdp, llmnr | debian, ubuntu22 | windows |
|
||||||
|
| `linux-server` | Linux Server | ssh, http | debian, ubuntu22, rocky9, fedora | linux |
|
||||||
|
| `web-server` | Web Server | http, ftp | debian, ubuntu22, ubuntu20 | linux |
|
||||||
|
| `database-server` | Database Server | mysql, postgres, redis | debian, ubuntu22 | linux |
|
||||||
|
| `mail-server` | Mail Server | smtp, pop3, imap | debian, ubuntu22 | linux |
|
||||||
|
| `file-server` | File Server | smb, ftp, ssh | debian, ubuntu22, rocky9 | linux |
|
||||||
|
| `printer` | Network Printer | snmp, ftp | alpine, debian | embedded |
|
||||||
|
| `iot-device` | IoT Device | mqtt, snmp, telnet | alpine | embedded |
|
||||||
|
| `industrial-control` | Industrial Control System | conpot, snmp | debian | embedded |
|
||||||
|
| `voip-server` | VoIP Server | sip | debian, ubuntu22 | linux |
|
||||||
|
| `monitoring-node` | Monitoring Node | snmp, ssh | debian, rocky9 | linux |
|
||||||
|
| `devops-host` | DevOps Host | docker_api, ssh, k8s | ubuntu22, debian | linux |
|
||||||
|
| `deaddeck` | Deaddeck (Entry Point) | ssh | debian, ubuntu22 | linux |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- `deaddeck` exposes a real interactive SSH shell (not a honeypot emulation) and
|
||||||
|
is intended as the internet-facing entry point.
|
||||||
|
- `industrial-control` uses Conpot to simulate Modbus / S7 / DNP3.
|
||||||
|
- The `preferred_distros` list is rotated per-decky so a group of the same
|
||||||
|
archetype still looks heterogeneous.
|
||||||
|
- Each archetype's `nmap_os` is applied as network-namespace sysctls on the
|
||||||
|
decky's base container. See [OS fingerprint spoofing](OS-Fingerprint-Spoofing).
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Services catalog](Services-Catalog)
|
||||||
|
- [Distro profiles](Distro-Profiles)
|
||||||
|
- [Networking](Networking-MACVLAN-IPVLAN)
|
||||||
78
Distro-Profiles.md
Normal file
78
Distro-Profiles.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Distro profiles
|
||||||
|
|
||||||
|
Each distro profile maps a slug to a Docker image plus OS metadata used to make
|
||||||
|
deckies look like heterogeneous machines on the LAN. Profiles control the base
|
||||||
|
container image, the hostname convention, and the build base used for
|
||||||
|
service-container Dockerfiles.
|
||||||
|
|
||||||
|
Source of truth: `decnet/distros.py`.
|
||||||
|
|
||||||
|
## INI snippet
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[linux-fleet]
|
||||||
|
archetype=linux-server
|
||||||
|
distros=debian,ubuntu22,rocky9,fedora
|
||||||
|
amount=6
|
||||||
|
```
|
||||||
|
|
||||||
|
See [INI format](INI-Config-Format). At deploy time each decky draws a distro
|
||||||
|
from the comma-separated list (or from the archetype's preferred rotation when
|
||||||
|
omitted).
|
||||||
|
|
||||||
|
## Registered profiles
|
||||||
|
|
||||||
|
| Slug | Image | Display name | Hostname style | Build base |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `debian` | `debian:bookworm-slim` | Debian 12 (Bookworm) | generic | `debian:bookworm-slim` |
|
||||||
|
| `ubuntu22` | `ubuntu:22.04` | Ubuntu 22.04 LTS (Jammy) | generic | `ubuntu:22.04` |
|
||||||
|
| `ubuntu20` | `ubuntu:20.04` | Ubuntu 20.04 LTS (Focal) | generic | `ubuntu:20.04` |
|
||||||
|
| `rocky9` | `rockylinux:9-minimal` | Rocky Linux 9 | rhel | `debian:bookworm-slim` |
|
||||||
|
| `centos7` | `centos:7` | CentOS 7 | rhel | `debian:bookworm-slim` |
|
||||||
|
| `alpine` | `alpine:3.19` | Alpine Linux 3.19 | minimal | `debian:bookworm-slim` |
|
||||||
|
| `fedora` | `fedora:39` | Fedora 39 | rhel | `debian:bookworm-slim` |
|
||||||
|
| `kali` | `kalilinux/kali-rolling` | Kali Linux (Rolling) | rolling | `kalilinux/kali-rolling` |
|
||||||
|
| `arch` | `archlinux:latest` | Arch Linux | rolling | `debian:bookworm-slim` |
|
||||||
|
|
||||||
|
## Image vs. build base
|
||||||
|
|
||||||
|
`image` is the distro the decky's **base (IP-holder) container** runs. This is
|
||||||
|
what an attacker sees when they probe the host — package manager, `/etc/os-release`,
|
||||||
|
userland, and so on.
|
||||||
|
|
||||||
|
`build_base` is what DECNET's **service containers** are built `FROM`. Because
|
||||||
|
the service Dockerfiles use `apt-get`, non-Debian distros (Rocky, CentOS, Alpine,
|
||||||
|
Fedora, Arch) fall back to `debian:bookworm-slim` for their services. Debian,
|
||||||
|
Ubuntu, and Kali use their own image as the build base since they are apt-based.
|
||||||
|
|
||||||
|
This split keeps the attacker-facing surface diverse while keeping the service
|
||||||
|
implementations maintainable as a single Debian Dockerfile per service.
|
||||||
|
|
||||||
|
## /etc/os-release
|
||||||
|
|
||||||
|
DECNET does not template `/etc/os-release`. Each distro's file is whatever the
|
||||||
|
upstream image ships. Hostname style is set per-distro via `random_hostname()`:
|
||||||
|
|
||||||
|
- `generic` — `SRV-WORD-NN` (Debian, Ubuntu)
|
||||||
|
- `rhel` — `word{10..99}.localdomain` (Rocky, CentOS, Fedora)
|
||||||
|
- `minimal` — `word-NN` (Alpine)
|
||||||
|
- `rolling` — `word-word` (Kali, Arch)
|
||||||
|
|
||||||
|
## Default package manager
|
||||||
|
|
||||||
|
| Distro | Package manager |
|
||||||
|
|---|---|
|
||||||
|
| debian, ubuntu22, ubuntu20, kali | apt |
|
||||||
|
| rocky9, centos7, fedora | dnf / yum |
|
||||||
|
| alpine | apk |
|
||||||
|
| arch | pacman |
|
||||||
|
|
||||||
|
Service containers built for non-Debian deckies still ship apt-built payloads
|
||||||
|
because of the shared `build_base` fallback noted above.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Archetypes](Archetypes)
|
||||||
|
- [Services catalog](Services-Catalog)
|
||||||
|
- [OS fingerprint spoofing](OS-Fingerprint-Spoofing)
|
||||||
|
- [Networking](Networking-MACVLAN-IPVLAN)
|
||||||
87
OS-Fingerprint-Spoofing.md
Normal file
87
OS-Fingerprint-Spoofing.md
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# OS fingerprint spoofing
|
||||||
|
|
||||||
|
DECNET spoofs the TCP/IP stack fingerprint that nmap (and similar tools) use to
|
||||||
|
identify the remote operating system. Each archetype declares an `nmap_os` OS
|
||||||
|
family; the composer applies the matching sysctl set to the decky's base
|
||||||
|
container network namespace.
|
||||||
|
|
||||||
|
Source of truth: `decnet/os_fingerprint.py`. Injection site: `decnet/composer.py`.
|
||||||
|
|
||||||
|
## INI snippet
|
||||||
|
|
||||||
|
The OS family is chosen by the archetype, so simply picking an archetype is
|
||||||
|
enough:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[windows-hosts]
|
||||||
|
archetype=windows-workstation ; implies nmap_os=windows
|
||||||
|
amount=3
|
||||||
|
|
||||||
|
[ics]
|
||||||
|
archetype=industrial-control ; implies nmap_os=embedded
|
||||||
|
amount=1
|
||||||
|
```
|
||||||
|
|
||||||
|
See [INI format](INI-Config-Format) and [Archetypes](Archetypes) for the full
|
||||||
|
mapping.
|
||||||
|
|
||||||
|
## Supported OS families
|
||||||
|
|
||||||
|
| Slug | Default TTL | TCP timestamps | Window scaling | SACK | ECN | DF (pmtu) |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| `linux` | 64 | on | on | on | on (2) | off |
|
||||||
|
| `windows` | 128 | off | on | on | off | off |
|
||||||
|
| `bsd` | 64 | on | on | on | off | off |
|
||||||
|
| `embedded` | 255 | off | off | off | off | on |
|
||||||
|
| `cisco` | 255 | off | off | off | off | on |
|
||||||
|
|
||||||
|
Unknown slugs fall back to `linux`.
|
||||||
|
|
||||||
|
## How injection works
|
||||||
|
|
||||||
|
In `decnet/composer.py` the base (IP-holder) container of every decky receives:
|
||||||
|
|
||||||
|
```python
|
||||||
|
base["sysctls"] = get_os_sysctls(decky.nmap_os)
|
||||||
|
base["cap_add"] = ["NET_ADMIN"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Service containers attach with `network_mode: service:<base>`, so they share the
|
||||||
|
base container's network namespace and inherit the same fingerprint — no
|
||||||
|
`--privileged` required.
|
||||||
|
|
||||||
|
## What gets tuned
|
||||||
|
|
||||||
|
All sysctls in `OS_SYSCTLS` are network-namespace-scoped so they work per
|
||||||
|
container:
|
||||||
|
|
||||||
|
- `net.ipv4.ip_default_ttl` — primary TTL discriminator (Linux 64, Windows 128,
|
||||||
|
embedded/Cisco 255).
|
||||||
|
- `net.ipv4.tcp_syn_retries` — SYN retransmit count (nmap T2–T6 timing group).
|
||||||
|
- `net.ipv4.tcp_timestamps` — TCP timestamp option (nmap OPS group).
|
||||||
|
- `net.ipv4.tcp_window_scaling` — window scale option; off on embedded/Cisco.
|
||||||
|
- `net.ipv4.tcp_sack` — selective ACK option.
|
||||||
|
- `net.ipv4.tcp_ecn` — ECN negotiation; Linux offers (2), Windows off.
|
||||||
|
- `net.ipv4.ip_no_pmtu_disc` — DF bit on ICMP replies (nmap IE group).
|
||||||
|
- `net.ipv4.tcp_fin_timeout` — FIN_WAIT_2 duration.
|
||||||
|
- `net.ipv4.icmp_ratelimit` / `net.ipv4.icmp_ratemask` — ICMP reply pacing
|
||||||
|
(nmap IE / U1 groups).
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- `net.core.rmem_default` is a global (non-namespaced) sysctl and is not set
|
||||||
|
per container; the kernel default window size (64240) already matches
|
||||||
|
Windows, so this is mostly fine in practice.
|
||||||
|
- Only TCP/IP stack behaviour is tuned. Banner grabs, TCP option order outside
|
||||||
|
the listed set, and application-layer artefacts are handled by the individual
|
||||||
|
service implementations — see [Services catalog](Services-Catalog).
|
||||||
|
- The host kernel is still Linux, so nmap's deepest OS-detection probes can
|
||||||
|
sometimes correctly identify the underlying stack; the goal is to defeat the
|
||||||
|
common-case fingerprint, not to be indistinguishable.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [Archetypes](Archetypes)
|
||||||
|
- [Distro profiles](Distro-Profiles)
|
||||||
|
- [Networking](Networking-MACVLAN-IPVLAN)
|
||||||
|
- [Services catalog](Services-Catalog)
|
||||||
Reference in New Issue
Block a user