Skip to main content

RDP

Synopsis​

Creates a decoy RDP server that drives the X.224 and CredSSP/NLA handshake far enough to capture a client's NTLM credentials as a crackable Net-NTLMv2 response. Every connection is logged, along with the routing cookie and requested security protocols. Authentication always fails and no desktop is ever presented.

Schema​

- id: <numeric>
name: <string>
description: <string>
type: rdp
tags: <string[]>
pipelines: <pipeline[]>
status: <boolean>
properties:
address: <string>
port: <numeric>
os_flavor: <string>
tls:
cert_name: <string>
key_name: <string>
timeout: <numeric>

Configuration​

The following fields are used to define the device:

Device​

FieldRequiredDefaultDescription
idYUnique identifier
nameYDevice name
descriptionN-Optional description
typeYMust be rdp
tagsN-Optional tags
pipelinesN-Optional pre-processor pipelines
statusNtrueEnable/disable the device

Connection​

FieldRequiredDefaultDescription
addressN"0.0.0.0"Listen address
portYListen port
timeoutN20Deadline in seconds for each connection, set once when the client connects. Activity does not extend it, so a session is closed this long after it opened

Emulation​

FieldRequiredDefaultDescription
os_flavorNserver2019Windows version advertised in the NTLM challenge

Accepted values are server2012, server2012r2, server2016, server2019, and server2022. Each preset supplies the NetBIOS and DNS computer and domain names, plus the Windows version reported to the client. Scanners and client tools fingerprint the host from these, so the value determines which Windows Server build the honeypot appears to be.

An unrecognized or empty value falls back to server2019 without raising a configuration error.

TLS​

FieldRequiredDefaultDescription
tls.cert_nameN-Certificate name resolved from the certificate store
tls.key_nameN*key.pemKey name resolved from the certificate store

* = Read only when tls.cert_name is set.

warning

RDP does not read a tls.status key. TLS is unconditional — Network Level Authentication requires it — so a tls.status key in an RDP device configuration is silently ignored, including when set to false. When tls.cert_name is empty, a self-signed certificate is generated on each start; a non-empty tls.cert_name that cannot be resolved stops the device from starting.

Ingest Buffer​

FieldRequiredDefaultDescription
max_buffer_sizeN128MBIngest buffer admission cap. Also sizes this listener's ingest buffers: 3/8 of this value at start, growing to at most 3x
note

max_buffer_size is the ingest-buffer admission cap, and is distinct from any buffer_size field above, which sizes the network read buffer. Left unset it is 128MB, whose buffers take 48 MiB of heap per listener worker at start and grow to at most 384 MiB as bursts need the room — and with reuse: true a device runs one worker per listener. Size strings are binary, and 32MB and 32MiB are exact synonyms.

See Listener Memory Sizing for the arithmetic, the sizing table, and what happens when the cap is exhausted.

Details​

Handshake​

The honeypot reads the client's TPKT/X.224 Connection Request, parsing the mstshash= routing cookie and the requested-protocols bitmask, and logs a connection event. If the client does not offer HYBRID (NLA), the honeypot sends a Connection Confirm selecting SSL when offered, or plain RDP, and stops the connection there — no credential exchange takes place.

When the client offers HYBRID, the honeypot confirms it, upgrades the connection to TLS, and runs CredSSP: it reads the TSRequest carrying the client's NTLM NEGOTIATE message, replies with a CHALLENGE advertising the os_flavor preset's computer name, domain name, and Windows version, then reads the AUTHENTICATE message and captures the credential. The connection is then closed, which a brute-forcer reads as an authentication failure. No desktop, graphics channel, or screen content is ever served.

Logged Events​

Each connection produces one or both of the following event types:

event_typeEmitted when
connectionThe client sends its X.224 Connection Request
auth_attemptThe client completes the CredSSP/NTLM exchange after negotiating HYBRID (NLA)

Event Fields​

Every event carries timestamp, event_type, source_ip, source_port, and local_addr. The remaining fields depend on the event type:

FieldDescription
cookie_userUsername from the client's mstshash= routing cookie
requested_protocolsSecurity protocols offered in the Connection Request: RDP, SSL, HYBRID, HYBRID_EX
usernameUsername captured from the NTLM AUTHENTICATE message
domainNTLM domain captured from the AUTHENTICATE message
workstationNTLM workstation name captured from the AUTHENTICATE message
auth_methodAlways ntlm
netntlmv2Crackable Net-NTLMv2 response captured from the AUTHENTICATE message
os_flavorConfigured os_flavor preset for the session

Captured Hashes​

netntlmv2 is a hashcat -m 5600 Net-NTLMv2 string.

Examples​

The following are commonly used configuration types.

Basic​

Creating a minimal RDP honeypot on the standard port...

devices:
- id: 1
name: basic_rdp
type: rdp
properties:
port: 3389

Operator Certificate​

Presenting an operator-supplied certificate during NLA instead of a self-signed one...

devices:
- id: 2
name: rdp_operator_cert
type: rdp
properties:
port: 3389
tls:
cert_name: rdp-cert.pem
key_name: rdp-key.pem

With Pre-Processing​

Routing captured attempts through a pre-processing pipeline before ingestion...

devices:
- id: 3
name: rdp_preprocessed
type: rdp
pipelines:
- decoy-honeypot-enrich
properties:
port: 3389

A completed NLA exchange is logged with the captured Net-NTLMv2 response before pipeline processing...

{
"timestamp": "2026-08-03T09:14:22.481937204Z",
"event_type": "auth_attempt",
"source_ip": "203.0.113.44",
"source_port": "51422",
"local_addr": "10.0.4.12:3389",
"username": "administrator",
"domain": "CORP",
"workstation": "WIN-CLIENT01",
"auth_method": "ntlm",
"netntlmv2": "administrator::CORP:1122334455667788:9f8b3d2a1c4e5f6071829304152637a8:0101000000000000c0fa1b2e3d4f5a6b0000000002000c00430052004f005000",
"os_flavor": "server2019"
}