
High-interaction honeypot mimicking a vulnerable Laravel/Livewire app. Captures RCE exploits and webshells targeting CVE-2024-47823, CVE-2025-54068, and CVE-2025-14894, then analyzes them in sandboxed Docker containers to extract IOCs.
A high-interaction honeypot that masquerades as a vulnerable Laravel/Livewire application. It captures exploit attempts targeting known Livewire CVEs, stores uploaded malicious files (webshells) and remote code execution (RCE) payloads with SHA-256 deduplication, and optionally executes them in a sandboxed Docker container to extract indicators of compromise (IOCs) — URLs, IPs, and domains that the malware tries to contact.
The system runs as two separate processes for security: a web server that captures payloads (no Docker access) and a sandbox worker that analyzes them in isolated containers.
Attacker → Nginx → FastAPI → SQLite ← Sandbox Worker (Docker)
(capture) (polls jobs, writes IOCs)
Facade — Serves realistic Laravel login/register pages with Livewire wire: attributes, XSRF tokens, and X-Powered-By: PHP/8.3.12 headers. Automated scanners see what looks like a real vulnerable app.
Capture — Every HTTP request is logged to SQLite (IP, headers, body hash, timestamp) by an ASGI middleware layer, transparently, before any routing happens.
Traps — Livewire endpoints accept file uploads and component messages just like the real framework would. Payloads are classified (PHP code, serialized objects, shell commands) and stored with SHA-256 deduplication. Each interesting payload creates a durable job in the sandbox_jobs queue.
Sandbox — A separate worker process polls for pending jobs and executes each payload in an ephemeral Docker container (read-only filesystem, no network, cap_drop=ALL). An LD_PRELOAD shim intercepts libc network calls to log C2 (command-and-control) communication attempts. The analyzer extracts IOCs and scores potential C2 endpoints using heuristics.
| CVE | CVSS | Summary | Trap Endpoint |
|---|---|---|---|
| CVE-2024-47823 | 9.8 Critical | Livewire file upload RCE via MIME type bypass. File extensions are guessed from MIME type instead of validated from the filename, allowing .php uploads disguised as images. Affects Livewire < 2.12.7 and < 3.5.2. | POST /livewire/upload-file |
| CVE-2025-54068 | 9.2 Critical | Livewire prop hydration RCE. The hydration process fails to sanitize object types in component property updates, allowing injected payloads to execute server-side. Affects Livewire 3.0.0-beta.1 through 3.6.3. | POST /livewire/message |
| CVE-2025-14894 | Critical | Livewire Filemanager unrestricted upload RCE. Missing file type and MIME validation allows unauthenticated upload of executable PHP files. | POST /livewire/upload-file |
A *.php catch-all trap also captures post-exploitation probing for common webshell filenames (e.g. accesson.php, wp-login.php, admin.php).
Prerequisites: Python 3.11+ and uv.
git clone https://github.com/HelgeSverre/livewire-honeypot.git
cd livewire-honeypot
# Install dependencies
uv sync
# Start the web server (capture-only, no Docker needed)
DATA_DIR=./data uv run uvicorn honeypot.main:app --reload --port 8000
# In a second terminal — start the sandbox worker (requires Docker)
DATA_DIR=./data uv run python -m honeypot.worker
# Run tests
uv run pytest tests/ -v
The web server works standalone — it captures and stores everything even without the sandbox worker running. Start the worker when you want automated payload analysis.
Note: The
src/directory is on the Python path viapyproject.toml(src-layout), sohoneypot.main:appmaps tosrc/honeypot/main.py.
You will need:
The full deploy is a single command once the VPS exists. The script handles every step from "bare droplet" to "service running with TLS" — apt packages, users and groups, Python venv, sandbox image, nginx, certbot, and firewall rules.
# 1. Provision a $6/mo droplet (Ubuntu 24.04, 1 GB RAM is enough).
# On DigitalOcean:
doctl compute droplet create veritron-honeypot \
--size s-1vcpu-1gb \
--image ubuntu-24-04-x64 \
--region fra1 \
--ssh-keys "$(doctl compute ssh-key list --format ID --no-header | head -1)" \
--wait
# 2. Point your domain's A record at the droplet IP.
# Wait for DNS to resolve before continuing.
dig +short your-domain.example # should return the droplet IP
# 3. Copy the project onto the droplet.
rsync -az --exclude='.git' --exclude='.venv' --exclude='data' \
./ root@<droplet-ip>:/opt/honeypot/
# 4. Run the bootstrap script. Passing your domain enables TLS via certbot.
ssh root@<droplet-ip> 'cd /opt/honeypot && [email protected] \
bash deploy/setup.sh your-domain.example'
That's it. The honeypot is now serving a fake Laravel/Livewire login page over HTTPS, capturing every request to SQLite, and ready to analyse payloads in the Docker sandbox.
deploy/setup.sh is idempotent — re-running it is safe. In order, it:
honeypot (web) and sandbox (worker) service users, plus the shared honeypot-data group.uv sync --python /usr/bin/python3.12. We deliberately use the apt-installed Python rather than uv's bundled interpreter — uv's Python lives in /root/.local/share/uv/, which an unprivileged service user cannot traverse, and you get a confusing status=203/EXEC from systemd if you let uv pick the interpreter./var/honeypot/ with setgid bit and shared group ownership, so both services can read each other's writes.ExecStart to use the system Docker daemon (the shipped unit assumes rootless Docker, which is harder to set up).docker build -t honeypot-sandbox sandbox/).limit_req_zone directive into /etc/nginx/conf.d/ (it must be in the http {} block, not in server {}).certbot --nginx if a domain was passed.If you want to drive each step yourself instead of running setup.sh, the equivalent shell history lives in deploy/setup.sh as commented stages.