CitrixPot: NetScaler / Citrix ADC Gateway honeypot (initial public release)

This commit is contained in:
CitrixPot committed 2026-09-28 19:44:37 +02:00
commit 4491b42714
54 files changed
+4532

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""Run once on Proxmox after trusted cloud-init completes, before deploying payload code."""
import json
from pathlib import Path
import shlex
import subprocess
ROOT = Path('/var/lib/vz/honeypot')
PCAP = ROOT / 'execution.pcap'
if PCAP.exists():
raise SystemExit('Existing capture found: refusing a restart that would truncate evidence')
def guest(vm, command):
result = json.loads(subprocess.check_output(
['qm', 'guest', 'exec', str(vm), '--', '/bin/sh', '-c', command], text=True))
if result.get('exitcode') != 0:
raise RuntimeError(result)
return result.get('out-data', '')
for vm in (222, 223):
guest(vm, 'test -f /var/lib/decoy-bootstrap-complete && cloud-init status --long')
keys = {vm: guest(vm, 'cat /etc/ssh/ssh_host_ed25519_key.pub').strip() for vm in (222, 223)}
pub = guest(222, 'mkdir -p /root/.ssh; chmod 700 /root/.ssh; '
'test -f /root/.ssh/decoy_execution_ed25519 || '
'ssh-keygen -q -t ed25519 -N "" -f /root/.ssh/decoy_execution_ed25519; '
'cat /root/.ssh/decoy_execution_ed25519.pub').strip()
guest(223, 'printf "%s\\n" ' + shlex.quote(
'no-agent-forwarding,no-port-forwarding,no-X11-forwarding ' + pub) +
' >> /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys')
guest(222, 'printf "%s\\n" ' + shlex.quote('10.0.2.101 ' + keys[223]) +
' > /root/.ssh/known_hosts; chmod 600 /root/.ssh/known_hosts; '
'cp /root/.ssh/known_hosts /root/.ssh/decoy_execution_known_hosts')
config = ('Host decoy-execution\n HostName 10.0.2.101\n User root\n'
' IdentityFile /root/.ssh/decoy_execution_ed25519\n IdentitiesOnly yes\n'
' StrictHostKeyChecking yes\n BatchMode yes\n ConnectTimeout 5\n')
guest(222, 'printf "%s" ' + shlex.quote(config) +
' > /root/.ssh/config; chmod 600 /root/.ssh/config')
subprocess.run(['qm', 'shutdown', '223', '--timeout', '60'], check=True)
ROOT.chmod(0o700)
PCAP.touch(mode=0o600, exist_ok=False)
# -sandbox applies a QEMU seccomp filter: deny obsolete syscalls and privilege elevation.
args = ('-netdev user,id=decoy,restrict=on,hostfwd=tcp:127.0.0.1:19223-:22,'
'guestfwd=tcp:10.0.2.100:19090-cmd:/var/lib/vz/honeypot/forward-collector-telemetry '
'-device virtio-net-pci,netdev=decoy,mac=52:54:00:22:02:23 '
'-object filter-dump,id=decoycap,netdev=decoy,'
'file=/var/lib/vz/honeypot/execution.pcap,maxlen=512 '
'-sandbox on,obsolete=deny,elevateprivileges=deny')
subprocess.run(['qm', 'set', '223', '--args', args], check=True)
subprocess.run(['qm', 'start', '223'], check=True)
for vm, key in keys.items():
print(f'decoy-{vm} {key}') # Public host keys only.