MANTIS is a multi-protocol network honeypot and threat intelligence platform. It deploys 14 realistic decoy services that mimic production systems, captures attacker credentials, commands, and payloads in real time, and presents everything through a live web dashboard with geolocation mapping and alerting.
Built entirely in Python with asyncio for high concurrency and zero threads per connection.
- 14 honeypot services with wire-protocol-level fidelity
- Real-time dashboard with WebSocket live feed, filterable event log, session tracking, and alert management
- Attack origin map with IP geolocation (ip-api.com)
- IP blocking / firewall — click any IP in the dashboard to block it via iptables, manage blocked IPs from the Firewall tab
- Automated alerts — reconnaissance detection, credential harvesting, SQL injection, shell commands
- Profile system — switch between minimal, database-trap, and full deployments with YAML configs
- SQLite storage with full-text search, JSON export, and database management
- Zero external dependencies for service emulation (pure Python protocol implementations)
| Service | Default Port | Protocol Detail |
|---|---|---|
| SSH | 2222 | Full Paramiko-based SSH server with shell emulation, command logging, and credential capture |
| Docker | 2375 | Docker Engine API v1.41 honeypot — captures container create/start, image pull, version/info probes from cryptominer bots |
| FTP | 21 | RFC 959 implementation with USER/PASS capture, fake directory listings, and file transfer logging |
| SMB | 4450 | SMB1/SMB2 negotiate + NTLM authentication capture with session setup |
| MySQL | 3306 | Full handshake (v10 protocol), authentication, and COM_QUERY logging |
| Telnet | 23 | Interactive shell with login prompt, command history, and fake filesystem responses |
| SMTP | 25 | RFC 5321 with EHLO, AUTH LOGIN/PLAIN (base64 credential decode), MAIL FROM/RCPT TO/DATA capture |
| MongoDB | 27017 | OP_QUERY + OP_MSG wire protocol, custom BSON codec, isMaster/saslStart auth, listDatabases |
| VNC | 5900 | RFB 3.8 handshake, VNC Auth (DES challenge/response capture), ServerInit with fake framebuffer |
| Redis | 6379 | RESP protocol parser, AUTH capture, INFO/KEYS/GET with fake sensitive data, threat detection for CONFIG SET/SLAVEOF/MODULE LOAD |
| ADB | 5555 | Android Debug Bridge binary protocol (CNXN/OPEN/WRTE/CLSE), fake Pixel 7 device, shell command responses |
| Elasticsearch | 9200 | REST API emulating open cluster — /_search (data theft), /_bulk (injection), /_scripts (RCE), /_snapshot (exfil), fake customer/transaction indices |
| Kubernetes | 6443 | Unauthenticated K8s API server — pod creation specs, secret reads (honey AWS keys, DB creds), pod exec RCE, namespace/node enumeration |
| MQTT | 1883 | Full MQTT v3.1.1 binary protocol — CONNECT credentials, SUBSCRIBE topic filters, PUBLISH payloads (C2, malware URLs) with QoS handling |
- Python 3.10+
- pip
git clone https://github.com/Syn2Much/MANTIS.git && cd MANTIS
pip install -r requirements.txtpython main.pyThis launches a single-screen interactive setup:
? Select services & configure ports (space = toggle, → = set port, enter = confirm)
❯ [x] SSH :2222
[x] DOCKER :2375
[x] FTP :21
[ ] SMB :4450
[x] MYSQL :3306
[x] TELNET :2323
[x] SMTP :25
[x] MONGODB :27017
[x] VNC :5900
[x] REDIS :6379
[x] ADB :5555
[x] ELASTIC :9200
[x] K8S :6443
[x] MQTT :1883
────────────────────────────
[x] DASHBOARD :8843
- Space — toggle a service on/off
- → — edit the port for the highlighted service inline
- a — toggle all on/off
- Enter — confirm and proceed to auth token prompt
The dashboard starts at http://localhost:8843 by default.
For scripts, systemd, Docker, or CI — skip all prompts:
# All defaults, no prompts
python main.py --headless
# Load from YAML config, no prompts
python main.py --headless --config profiles/default.yamlThe dashboard uses username/password authentication with session-based auth. Default credentials are admin:admin — change the password after first login. API requests can authenticate via:
- Cookie — set automatically after login
- Bearer token —
Authorization: Bearer <session_token> - WebSocket — session token passed as query parameter
python main.py [options]
Options:
--headless Non-interactive mode (all defaults)
-c, --config FILE YAML config file path
--db PATH Database file path
-v, --verbose Debug logging
-q, --quiet Errors only
python main.py stats
python main.py stats --db /path/to/honeypot.dbProfiles are YAML files that control which services are enabled and on which ports.
default.yaml — All 14 services enabled with standard banners:
ssh:
enabled: true
port: 2222
banner: "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6"
docker:
enabled: true
port: 2375
mysql:
enabled: true
port: 3306
banner: "5.7.42-0ubuntu0.18.04.1"
# ... all 14 servicesminimal.yaml — SSH + Docker only (lightweight):
ssh:
enabled: true
port: 2222
docker:
enabled: true
port: 2375
# all other services: enabled: falsedatabase_trap.yaml — Databases + file services:
mysql:
enabled: true
port: 3306
mongodb:
enabled: true
port: 27017
redis:
enabled: true
port: 6379
ftp:
enabled: true
port: 2121
smb:
enabled: true
port: 4450The dashboard exposes a REST API on the same port:
| Endpoint | Method | Description |
|---|---|---|
/api/stats |
GET | Aggregate statistics (events, sessions, IPs, alerts) |
/api/events |
GET | Event log with filters (service, type, ip, limit) |
/api/sessions |
GET | Session list with filters (service, ip, limit) |
/api/alerts |
GET | Alerts with severity/status filters |
/api/alerts/<id>/ack |
POST | Acknowledge an alert |
/api/geo/<ip> |
GET | GeoIP lookup |
/api/map |
GET | Map data with coordinates |
/api/config |
GET | Current service configuration |
/api/config/full |
GET | Config + extra schemas + banner presets for UI |
/api/config/global |
PUT | Update global settings (alerts, log level) |
/api/config/save |
POST | Persist running config to YAML |
/api/config/export |
GET | Download config as YAML file |
/api/ips |
GET | Unique source IPs |
/api/firewall/blocked |
GET | List currently blocked IPs |
/api/firewall/block |
POST | Block an IP via iptables ({"ip": "x.x.x.x"}) |
/api/firewall/unblock |
POST | Unblock an IP ({"ip": "x.x.x.x"}) |
/api/payload-stats |
GET | Payload intel — severity counts, pattern frequency, IOC totals, timeline |
/api/database/reset |
POST | Reset the database |
/ws |
WebSocket | Real-time event stream |
The included endpoint tester generates traffic across all 14 services and validates every dashboard API endpoint:
python test_endpoints.pyMANTIS Endpoint Tester
Target: 127.0.0.1
============================================================
Honeypot Service Probes
============================================================
[PASS] SSH banner: SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
[PASS] Docker /_ping: OK, /version: v20.10.24
[PASS] FTP banner: 220 FTP Server ready.
[PASS] MySQL handshake=95b, auth_resp=11b, query_resp=55b
[PASS] SMB negotiate response=133b
[PASS] Telnet banner received
[PASS] SMTP banner: 220 mail.example.com ESMTP Postfix (Ubuntu)
[PASS] SMTP AUTH auth: 235 2.7.0 Authentication successful
[PASS] MongoDB isMaster resp=186b, listDatabases resp=315b
[PASS] VNC version: RFB 003.008, auth_ok=True
[PASS] Redis ping: +PONG, auth: +OK
[PASS] ADB device: Pixel 7
[PASS] ADB shell uid=0(root) gid=0(root)
[PASS] Elastic cluster: elasticsearch, version: 8.12.0
[PASS] K8s /version: v1.28.2, /api/v1: 200
[PASS] MQTT CONNACK received, session established
...
36 passed, 0 failed out of 36 checks
main.py # Entry point
honeypot/
├── __init__.py # Package metadata
├── __main__.py # Module entry point
├── cli.py # Interactive CLI (questionary), headless mode, banner
├── config.py # YAML config loading, service extra schemas, banner presets
├── core.py # HoneypotOrchestrator — lifecycle, live config updates
├── database.py # Async SQLite with pub/sub for WebSocket
├── models.py # EventType enum, ServiceType enum
├── alerts.py # Alert engine (severity rules, webhook support)
├── dashboard/
│ ├── server.py # aiohttp web server + REST API + WebSocket
│ └── templates.py # Single-file HTML/CSS/JS dashboard
├── services/
│ ├── __init__.py # BaseHoneypotService ABC
│ ├── ssh.py # SSH (Paramiko)
│ ├── docker.py # Docker Engine API
│ ├── ftp.py # FTP
│ ├── smb.py # SMB/CIFS
│ ├── mysql.py # MySQL
│ ├── telnet.py # Telnet
│ ├── smtp.py # SMTP
│ ├── mongodb.py # MongoDB (custom BSON codec)
│ ├── vnc.py # VNC/RFB
│ ├── redis.py # Redis (RESP protocol)
│ ├── adb.py # Android Debug Bridge
│ ├── elasticsearch.py # Elasticsearch (REST API)
│ ├── kubernetes.py # Kubernetes API Server
│ └── mqtt.py # MQTT Broker (v3.1.1)
profiles/
├── default.yaml # All services
├── minimal.yaml # SSH + Docker
└── database_trap.yaml # Database services
Each service extends BaseHoneypotService and implements:
async start()— bind to port and begin accepting connectionsasync _handle_client()— protocol-specific interaction loop_create_session()/_log()/_end_session()— event pipeline to SQLite + WebSocket
MIT





