A secure API service for CTFd that allows players to spawn personal Linux webshell containers using their CTFd tokens.
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ CTFd Platform │────▶│ Webshell API │────▶│ Docker Engine │
│ (validates │ │ (manages │ │ (spawns │
│ tokens) │ │ containers) │ │ containers) │
│ │ │ │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌──────────────────┐
│ Traefik │
│ (reverse proxy, │
│ SSL, routing) │
└──────────────────┘
│
▼
┌──────────────────┐
│ Webshell Instance│
│ (ttyd + tools) │
└──────────────────┘
- CTFd Token Authentication: Validates player tokens against your CTFd instance
- Per-Team Containers: Each team gets their own isolated Linux environment
- Pre-installed CTF Tools: Python, pwntools, nmap, gdb, and more
- Automatic Cleanup: Expired containers are removed after 24 hours
- Resource Limits: Memory and CPU limits prevent resource abuse
- SSL/TLS: Automatic HTTPS via Let's Encrypt
cd webshell-api
cp .env.example .env
nano .env # Edit configurationchmod +x deploy.sh
sudo ./deploy.shPoint these domains to your droplet:
api.nullbytez.live→ Webshell APIwebshell.nullbytez.live→ Webshell instances (via Traefik)
| Variable | Description | Default |
|---|---|---|
CTFD_URL |
Your CTFd instance URL | https://2k26-rsuctf.nulbytez.live |
WEBSHELL_BASE_URL |
Base URL for webshell access | https://webshell.nullbytez.live |
CONTAINER_MEMORY_LIMIT |
Memory limit per container | 512m |
CONTAINER_CPU_LIMIT |
CPU limit (0.5 = 50%) | 0.5 |
CONTAINER_TIMEOUT_HOURS |
Container expiry time | 24 |
API_SECRET |
Admin API authentication | (generate random) |
ACME_EMAIL |
Email for Let's Encrypt | admin@nulbytez.live |
Validate a CTFd token and get user/team info.
// Request
{ "token": "ctfd_..." }
// Response
{
"success": true,
"user_id": 123,
"username": "player1",
"team_id": 45,
"team_name": "HackerSquad"
}Check if a team has an active container.
// Request
{ "team_name": "HackerSquad" }
// Response
{
"success": true,
"has_container": true,
"status": "running",
"webshell_url": "https://webshell.nullbytez.live/hackersquad"
}Create a new webshell container.
// Request
{
"team_name": "HackerSquad",
"username": "player1"
}
// Response
{
"success": true,
"message": "Container created successfully",
"webshell_url": "https://webshell.nullbytez.live/hackersquad"
}Stop and remove a container.
// Request
{ "team_name": "HackerSquad" }
// Response
{
"success": true,
"message": "Container stopped successfully"
}Requires X-API-Secret header.
List all active containers.
Remove expired containers.
Each container includes:
- Languages: Python 3, GCC, G++
- CTF Tools: pwntools, pycryptodome, z3-solver, angr, ropper
- Network: nmap, netcat, socat, tcpdump, curl, wget
- Binary: gdb, binutils, file, xxd, hexedit
- Editors: vim, nano
- Utilities: tmux, git, jq, unzip
- Container Isolation: Each container runs with dropped capabilities
- Resource Limits: Memory, CPU, and PID limits prevent DoS
- Network Isolation: Containers are on a separate Docker network
- No Privileged Mode: Containers cannot access host resources
- Token Validation: All requests require valid CTFd tokens
Edit webshell-instance/Dockerfile:
RUN apt-get install -y your-packageEdit .env:
CONTAINER_MEMORY_LIMIT=1g
CONTAINER_CPU_LIMIT=1.0
docker-compose logs -f webshell-api
docker-compose logs -f traefikdocker-compose restartdocker-compose build --no-cache
docker-compose up -dMIT License - RSU CTF 2026