代理mcp
proxy-mcp是一个运行显式HTTP/HTTPS MITM代理(L7)的mcp服务器。它捕获请求/响应,允许您在运行中修改流量(标头/正文/模拟/转发/丢弃),支持上游代理链接,并记录与代理(JA3/JA4)以及可选上游服务器JA3S的连接的TLS指纹。通过代理发送“拦截器”来路由隐形浏览器(斗篷浏览器、源代码修补的Chromium)、CLI工具、Docker容器和Android设备/应用程序,以及Playwright驱动的浏览器自动化,包括基于定位器的点击、打字、滚动和ARIA快照。
目录
- 生命周期 - 上游代理 - 拦截规则 - 流量捕获 - 修改快捷方式 - TLS指纹识别 - 拦截器 - 浏览器工具等效工具 - 会话 - 人性化工具
设置
快速安装(克劳德代码)
claude mcp add proxy-mcp -- npx -y proxy-mcp@latest这将使用stdio传输将代理mcp安装为mcp服务器。每次克劳德代码重启时,它都会自动更新。
范围:
# Per-user (available in all projects)
claude mcp add --scope user proxy-mcp -- npx -y proxy-mcp@latest
# Per-project (shared via .mcp.json, commit to repo)
claude mcp add --scope project proxy-mcp -- npx -y proxy-mcp@latest先决条件
- Node.js 22+
来源(开发)
git clone https://github.com/yfe404/proxy-mcp.git
cd proxy-mcp
npm install
npm run build# stdio transport (default) — used by MCP clients like Claude Code
node dist/index.js
# Streamable HTTP transport — exposes /mcp endpoint for scripting
node dist/index.js --transport http --port 3001--transport 和 --port 也接受env变量 TRANSPORT 和 PORT.
手动MCP配置
克劳德代码CLI:
# stdio (default)
claude mcp add proxy-mcp -- npx -y proxy-mcp@latest
# From local clone
claude mcp add proxy-mcp -- node /path/to/proxy-mcp/dist/index.js
# HTTP transport for scripting
claude mcp add --transport http proxy-mcp http://127.0.0.1:3001/mcp.mcp.json (项目级,承诺回购):
{
"mcpServers": {
"proxy": {
"command": "npx",
"args": ["-y", "proxy-mcp@latest"]
}
}
}可流式HTTP传输:
{
"mcpServers": {
"proxy": {
"type": "streamable-http",
"url": "http://127.0.0.1:3001/mcp"
}
}
}HTTP代理配置
1) 启动代理并获取端点
proxy_start使用返回的 port 和终点 http://127.0.0.1: .
2) 浏览器设置(推荐:拦截器)
使用浏览器拦截器,以便自动配置代理标志和证书信任。发射 三叶草 --默认情况下,带有源代码级C++指纹补丁和人性化模式的隐形修补Chromium:
interceptor_browser_launch --url "https://example.com"使用Playwright支持的工具(无CDP,无sidecar)驱动页面-- target_id 这就是你所需要的):
interceptor_browser_navigate --target_id "browser_" --url "https://apify.com"
interceptor_browser_snapshot --target_id "browser_"
interceptor_browser_screenshot --target_id "browser_" --file_path "/tmp/shot.png"3) 浏览器设置(手动回退)
如果手动启动浏览器,请亲自传递代理标志:
google-chrome --proxy-server="http://127.0.0.1:
"4) CLI/进程设置
通过设置代理环境变量,通过代理mcp路由任何进程:
export HTTP_PROXY="http://127.0.0.1:
"
export HTTPS_PROXY="http://127.0.0.1:
"
export NO_PROXY="localhost,127.0.0.1"如果客户端验证TLS,则信任代理mcp CA证书(请参阅 proxy_get_ca_cert)或使用终端拦截器(interceptor_spawn)它设置了代理环境变量和常见的CA环境变量(curl、Node、Python请求、Git、npm/yarn等):
interceptor_spawn --command curl --args '["-s","https://example.com"]'明确的 curl 示例:
curl --proxy http://127.0.0.1:
http://example.com
curl --proxy http://127.0.0.1:
https://example.com5) 上游代理链
设置从代理mcp到另一个上游代理的可选代理链接(用于地理位置、身份验证或IP信誉):
Client/app → proxy-mcp (local explicit proxy) → upstream proxy (optional chaining layer)proxy_set_upstream --proxy_url "socks5://user:pass@upstream.example:1080"支持的上游URL方案: socks4://, socks5://, http://, https://, pac+http://.
典型的地理布线示例:
# Route ALL outgoing traffic from proxy-mcp via a geo proxy
proxy_set_upstream --proxy_url "socks5://user:pass@fr-exit.example.net:1080"
# Bypass upstream for local/internal hosts
proxy_set_upstream --proxy_url "http://user:pass@proxy.example.net:8080" --no_proxy '["localhost","127.0.0.1",".corp.local"]'
# Route only one hostname via a dedicated upstream (overrides global)
proxy_set_host_upstream --hostname "api.example.com" --proxy_url "https://user:pass@us-exit.example.net:443"
# Remove overrides when done
proxy_remove_host_upstream --hostname "api.example.com"
proxy_clear_upstream对于HTTPS MITM,在目标环境中必须信任代理CA(proxy_get_ca_cert).
6) 快速验证和排除故障
proxy_list_traffic --limit 20
proxy_search_traffic --query "example.com"常见问题:
- 来自错误浏览器实例的流量(修复:始终通过
target_id从interceptor_browser_launch) - 目标上缺少HTTPS证书信任
NO_PROXY绕过预期主机- 首次启动很慢:斗篷浏览器在首次使用时下载约200 MB的隐形Chromium二进制文件(之后缓存)
7) HAR 导入 + 重播
将HAR导入持久会话,然后使用现有的会话查询/发现工具进行分析:
proxy_import_har --har_file "/path/to/capture.har" --session_name "imported-run"
proxy_list_sessions
proxy_query_session --session_id SESSION_ID --hostname_contains "api.example.com"
proxy_get_session_handshakes --session_id SESSION_ID重播默认为模拟运行(仅预览)。执行需要显式模式:
# Preview what would be replayed
proxy_replay_session --session_id SESSION_ID --mode dry_run --limit 20
# Execute replay against original hosts
proxy_replay_session --session_id SESSION_ID --mode execute --limit 20
# Optional: override target host/base URL while preserving path+query
proxy_replay_session --session_id SESSION_ID --mode execute --target_base_url "http://127.0.0.1:8081"注意:导入的HAR条目(以及由创建的条目) proxy_replay_session)不携带JA3/JA4/JA3S握手元数据。使用实时代理捕获的流量来分析握手指纹。
移动捕获(透明代理)
对于具有忽略系统代理的自定义HTTP堆栈的移动应用程序(大多数现代Android应用程序——Shopee、SHEIN、TikTok、银行等),显式代理不会看到它们的流量。代理mcp发货 透明听众 它位于使用TLS SNI的iptables REDIRECT和MITM后面——不需要CONNECT隧道。
配对 代理ap卡 --一个广播WiFi AP的XIAO ESP32-S3(proxy-ap SSID默认),并作为USB-PCM以太网适配器呈现给笔记本电脑。该回购处理AP+NAPT端;代理mcp处理笔记本电脑端。
先决条件
- 笔记本电脑:Linux
iptables,sysctl,nmcli(网络管理器),ip(iproute2),adb.sudo用于网络配置(每个会话一个命令)。 - 硬件路由器一 代理ap卡 (XIAO ESP32-S3),固件已闪存。或者任何USB以太网/USB WiFi组合,其中笔记本电脑NAT手机子网的流量——通过
--ap_iface/--ap_subnet以覆盖默认值。 - 目标设备:安卓系统 根 (Magisk/KernelSU)。需要Root将CA注入系统证书存储。Android 14-16还需要此工具自动执行的合子挂载命名空间注入。
- ADB访问权限:目标设备必须出现在
adb devices(至少USB,配对后无线)。
首次演练
1.Flash+插入代理ap卡
跟随 代理ap卡README 构建+刷新XIAO。重新插入时,笔记本电脑应显示 cdc_ncm 接口(验证: ls /sys/class/net/*/device/uevent | xargs grep DRIVER | grep cdc_ncm).
2.通过USB将目标设备连接到笔记本电脑
每个设备只需要第一次推送CA。请用验证 adb devices。复制序列号。
3.运行安装工具
proxy_mobile_setup --android_serial 可选参数:
| 参数 | 默认值 | 何时覆盖 |
|---|---|---|
ap_iface | 自动检测(cdc_ncm) | 使用不同的USB以太网桥 |
ap_address | 192.168.99.2/24 | 匹配默认代理ap卡固件 |
ap_subnet | 192.168.4.0/24 | 匹配默认代理ap卡固件 |
egress_iface | 从默认路由自动检测 | 多宿主主机,或希望流量通过特定接口退出 |
explicit_port | 8080 | 港口碰撞 |
transparent_port | 8443 | 港口碰撞 |
block_quic | true | 需要QUIC/HTTP3(当时没有可用的MITM) |
upstream_proxy_url | -- | 通过住宅/ISP代理进行出站路由--见下文 |
android_serial | -- | 省略跳过CA注入(仅远程设置) |
inject_cert | true 如果 android_serial set | 设置 false 重复使用以前的安装 |
响应是JSON,有三个关键位:
{
"ap_iface": "enp195s0f3u1u4",
"cert_injected": true,
"android_target_id": "adb_HQ63C81CB2",
"sudo_command": "sudo bash /tmp/proxy-mcp-mobile-setup-.sh"
}保持 android_target_id 周围——拆卸时你需要它。
4.运行发出的sudo脚本
sudo bash /tmp/proxy-mcp-mobile-setup-.sh这是唯一需要的sudo。该脚本是幂等的,可以安全地重新运行。它探测路线 iptables 需要root:
# Static IP on the AP iface (skipped if already configured).
ip addr add 192.168.99.2/24 dev
# Forwarding + dedicated nat chain.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -N PROXY_MCP_PREROUTING
iptables -t nat -A PROXY_MCP_PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -A PROXY_MCP_PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443
iptables -t nat -A PREROUTING -i -j PROXY_MCP_PREROUTING
# Block QUIC so apps fall back to TCP/TLS.
iptables -A FORWARD -i -p udp --dport 443 -j DROP
# Masquerade out through the real egress.
iptables -t nat -A POSTROUTING -s 192.168.4.0/24 -o -j MASQUERADE为什么是脚本而不是直接执行?MCP以您的用户身份运行;iptables需要root; sudo 来自MCP工具的请求将需要NOPASSWD或polkit策略(脆弱的、特定于发行版的)。发出脚本是可审计的、可复制的和可移植的。
5.将手机连接到 proxy-ap 无线网络
凭据在代理ap卡固件中设置(默认SSID proxy-ap,该存储库中显示的默认密码)。连接后,手机可以从USB拔下——未来的会话不需要它。
6.开始捕捉
现在,来自手机的每个HTTP/HTTPS请求都会进入代理mcp的环形缓冲区:
proxy_list_traffic --source_filter transparent # iptables-redirected HTTPS
proxy_list_traffic --source_filter explicit # absolute-URL HTTP that arrived on :80
proxy_get_exchange --exchange_id # full headers + body preview
proxy_search_traffic --query "api.example.com" # full-text search每个条目都携带 source: "explicit" | "transparent" +TLS指纹(ja3, ja4).
后续会话(手机已配对)
跳过步骤2。运行:
proxy_mobile_setup # skip android_serial — cert already installed
sudo bash /tmp/proxy-mcp-mobile-setup-.sh然后手机加入AP并捕获简历。
上游链
集 upstream_proxy_url 通过住宅/ISP代理路由出站流量——目标服务器看到的是该代理的IP,而不是您的笔记本电脑的IP:
proxy_mobile_setup \
--upstream_proxy_url "http://user:pass@proxy.example.com:8000" \
--android_serial 适用于两位听众。使用 proxy_set_upstream 事后更改它而不重新启动。
验证每个步骤
| 检查 | 命令 | 需要 | |
|---|---|---|---|
| 听众起来 | proxy_status | running: true, transparentProxy.running: true | |
| Iface检测到 | proxy_mobile_detect_iface | found: true,如果名字 | |
| 证书已注入 | `adb shell "su -c 'nsenter --mount=/proc/\$(pidof zygote64)/ns/mnt -- ls /apex/com.android.conscrypt/cacerts/ \ | wc -l'"` | 144(或143+1) |
| iptables有线 | sudo iptables -t nat -L PROXY_MCP_PREROUTING -v -n | 2个重新排列规则,非零 pkts 手机产生流量后 | |
| 转发至 | cat /proc/sys/net/ipv4/ip_forward | 1 | |
| 手机看到AP | 手机设置→ WiFi节目 proxy-ap 已连接,IP输入 192.168.4.0/24 | ||
| 交通流量 | proxy_list_traffic --limit 5 打开任何应用程序后 | source: "transparent" 状态为200的条目 |
拆除
proxy_mobile_teardown --android_target_id
sudo bash /tmp/proxy-mcp-mobile-teardown-.shMCP调用会停止两个侦听器并停用Android目标。sudo脚本删除iptables规则,禁用 ip_forward,并将AP接口交还给NetworkManager。手机会一直连接到AP,直到您在手机WiFi设置中忘记它。
故障排除
| 症状 | 可能原因 | 修复 | ||
|---|---|---|---|---|
proxy_mobile_detect_iface 回报 found: false | 代理ap卡未插入,或 cdc_ncm 司机失踪 | `lsusb \ | grep '303a:'; dmesg \ | grep cdc_ncm`;重新插入卡 |
setup 错误 No such file or directory: /sys/class/net/.../device/uevent | iface名称显式传递但不存在 | 使用自动检测或验证 ip link | ||
手机连接到AP,但流量为零 proxy_list_traffic | sudo脚本未运行;或使用其他WiFi的手机 | 验证 cat /proc/sys/net/ipv4/ip_forward 回报 1;检查手机的活动SSID | ||
手机显示“没有互联网” proxy-ap | Forward+MASQUERADE规则缺失,或者如果面朝下则退出 | 重新运行sudo脚本;检查 ip route show default | ||
| HTTPS因“连接非私有”或类似原因失败 | 证书不受应用程序信任(Chrome捆绑了自己的CA并忽略了系统信任,应用程序有证书固定) | 使用另一个应用程序验证链是否正常工作;Chrome是例外,而不是规则(见下面的限制) | ||
| 有些应用程序会捕获,有些则不会 | 将证书锁定在失败的应用程序中 | 请参阅下面的限制;Frida/LS需要拆包模块 | ||
| 端口20346/20443/其他自定义端口未捕获 | 仅 :80 和 :443 被重定向 | 在sudo脚本中添加额外的REDIRECT规则,或将redsocks配对到 CONNECT-通过显式侦听器隧道传输任意端口 | ||
cert_injected: false 或受精卵 nsenter 失败 | 设备未根,或SELinux chcon 拒绝 | adb shell su -c 'id' 必须返回 uid=0;确认 zygisksu /Magisk处于活动状态 | ||
| 无线ADB端口每次会话都会更改 | Android的无线调试会随机化端口 | 重新配对;或者保持手机插电,以便控制飞机 |
没有代理ap卡
手机可以通过的任何USB-PCM或USB以太网桥都可以工作:
proxy_mobile_setup --ap_iface eth1 --ap_address 10.0.0.1/24 --ap_subnet 10.0.0.0/24或者通过以下方式使用笔记本电脑托管的WiFi AP hostapd 在USB WiFi适配器(MT76x2U、RTL8812AU等)上——通过 wlanN 接口as ap_iface.
局限性
- 证书固定 --即使安装了CA信任,锁定特定公钥的应用程序(Instagram、WhatsApp、银行、Shopee主页提要等)也会拒绝我们的mocktp证书。您可以看到部分捕获(跟踪/静态/取消固定端点成功,固定API调用失败)。修复:Frida或LSPosed为该特定应用程序取消绑定模块。看
interceptor_frida_attach在工具参考中,或 morrownr的USB WiFi指南 对于常见的模式。 - Android上的Chrome浏览器 --Chrome发布了自己的Mozilla CA捆绑包,并强制执行证书透明度。我们的CA是自签名的,不在任何CT日志中,因此Chrome会拒绝它,而不管系统信任度如何。使用任何其他应用程序(或任何基于OkHttp/Conscrypt的浏览器)来验证管道。
- QUIC/HTTP3 --透明侦听器仅是TCP/TLS。默认情况下,我们丢弃UDP/443,这样应用程序就会回退到TCP。集
block_quic: false如果你 *想要* QUIC通过未捕获(QUIC内容不会出现在流量日志中)。 - 非标准端口 --默认的iptables规则仅重定向TCP/80和TCP/443。Shopee的
:20346,自定义游戏协议等将绕过。在sudo脚本(或链)中添加更多REDIRECT规则redsocks通过显式监听器发出CONNECT隧道)。 - 本机TLS固定 --一些应用程序直接通过JNI使用BoringSLSL/OpenSSL,引脚嵌入在
.soJava层Frida钩子无法捕获这些;需要原生钩子。 - 需要根 --系统信任CA覆盖需要root。非root Android只信任用户安装的CA,这些CA用于通过明确选择加入的应用程序
network_security_config--这是没有航运应用程序可以做到的。没有根就没有旁路。
界限
- 只看到交通 配置为通过它进行路由 (不是网络窃听器或数据包嗅探器)
- 滑稽模仿 出站JA3+HTTP/2指纹+头顺序 (通过impit——原生Rust TLS模拟),而不是JA4(JA4仅用于捕获)
- 可以添加、覆盖或删除HTTP标头;输出标头 顺序 可以通过指纹欺骗进行控制
- 返回自己的CA证书-- 不 公开上游服务器证书链
TLS ClientHello Passthrough(通过拦截器访问浏览器)
当斗篷浏览器通过以下方式启动时 interceptor_browser_launch,代理mcp转发浏览器的 原始TLS客户端Hello 向上游服务器发送文档加载和同源子资源请求。目标服务器看到的是真实的Chrome TLS指纹,而不是代理的指纹。
这是与典型的MITM代理(mitmproxy、Charles、Fiddler)的一个关键区别,后者使用自己的指纹重新终止TLS,使反机器人系统通过JA3/JA4分析可以轻松检测到MITM。
如何验证passthrough是否正常工作:
proxy_list_tls_fingerprints --hostname_filter "example.com"- JA3各不相同 跨请求访问同一主机——这是意料之中的;Chrome随机化每个连接的密码套件顺序(Chrome 110+以来的功能)
- JA4保持稳定 --相同的密码/扩展集,只是顺序不同
- JA3变体+JA4稳定性=确认真实的Chrome TLS透传
当passthrough应用时与需要欺骗时:
| 流量源 | TLS行为 | 需要采取的行动 |
|---|---|---|
衣帽匠via interceptor_browser_launch (文档加载,同一来源) | 浏览器的原生ClientHello转发(passthrough) | 无——指纹是真实的 |
衣帽匠via interceptor_browser_launch (跨源子资源,当欺骗活动时) | 通过带有欺骗TLS的impit重新发布 | proxy_set_fingerprint_spoof 预设浏览器 |
非浏览器客户端(curl、Python、, interceptor_spawn) | 代理自己的TLS | proxy_set_fingerprint_spoof 或 proxy_set_ja3_spoof 必填项 |
重播(proxy_replay_session) | 代理自己的TLS | proxy_set_fingerprint_spoof 必填项 |
基于斗篷浏览器+剧作家
浏览器自动化使用 三叶草 --带有源代码级C++指纹补丁的隐形修补Chromium——由Playwright驱动。没有CDP表面,没有sidecar,没有手动滚动的隐形脚本。一 target_id 从 interceptor_browser_launch 是下游工具所需的一切。
| 能力 | 代理mcp |
|---|---|
| 查看/修改DOM,在页面中运行JS | interceptor_browser_evaluate (运行JS文件,返回值), interceptor_browser_inject_init_script (预文档挂钩,每次导航), interceptor_browser_add_script_tag (DOM可见——避免隐藏);加 interceptor_browser_snapshot ARIA阅读 |
| 读取Cookie、本地存储、会话存储 | 是-- interceptor_browser_list_cookies, interceptor_browser_list_storage_keys |
| 捕获HTTP请求/响应体 | 通过MITM代理(默认预览上限为4KB; full 持久会话上的捕获配置文件存储完整的正文) |
| 修改正在进行的请求(标头、正文、模拟、删除) | 是(声明性规则、热重载) |
| 上游代理链(地理、身份验证) | 全局+所有客户端(SOCKS4/5、HTTP、HTTPS、PAC)的每台主机上游 |
| TLS指纹捕获(JA3/JA4/JA3S) | 是 |
| JA3+HTTP/2指纹欺骗 | 代理端(impit重新发出具有欺骗TLS 1.3、HTTP/2帧和标头顺序的匹配请求) |
| 拦截非浏览器流量(curl、Python、Android应用程序) | 是(拦截器) |
| 类人鼠标/键盘/滚动输入 | humanizer_* 工具:贝塞尔曲线+鼠标的Fitts定律,WPM+二元组+打字的打字模型,简化的滚轮滚动——叠加在斗篷浏览器内置的人性化模式之上 |
| 基于定位器的交互 | humanizer_click 接受CSS/XPath选择器、ARIA角色+名称、可见文本或表单标签——无像素猜测 |
标准流量:
- 呼叫
proxy_start - 可选地为跨源子资源启用出站指纹欺骗:
proxy_set_fingerprint_spoof --preset chrome_136 - 呼叫
interceptor_browser_launch --url "https://example.com" - 驱动页面:
interceptor_browser_navigate,interceptor_browser_snapshot,humanizer_click --selector "...",humanizer_type --text "..." - 检查交通:
proxy_search_traffic --query ""
工具参考
生命周期(4)
| 工具 | 说明 |
|---|---|
proxy_start | 启动MITM代理,自动生成CA证书 |
proxy_stop | 停止代理(保留流量/证书) |
proxy_status | 运行状态、端口、规则/流量计数 |
proxy_get_ca_cert | CA证书PEM+SPKI指纹 |
透明/移动捕捉(6)
| 工具 | 说明 |
|---|---|
proxy_start_transparent | 在并行端口上启动第二个MITM侦听器(基于SNI,无CONNECT);与显式侦听器共享CA+规则+环形缓冲区 |
proxy_stop_transparent | 停止透明的监听器 |
proxy_transparent_status | 运行状态+端口+专用流量计数 |
proxy_mobile_setup | 一个命令移动捕获:启动两个监听器,通过adb将CA注入Android系统存储(tmpfs overlay+适用于Android 14+的合子ns),发出一个sudo可运行的iptables/sysctl/nmcli脚本 |
proxy_mobile_teardown | 反向设置:停用Android目标,停止透明监听器,发出拆解脚本 |
proxy_mobile_detect_iface | 探头 /sys/class/net 为了一个 cdc_ncm USB接口(与 代理ap卡 固件) |
上游代理(4)
| 工具 | 说明 |
|---|---|
proxy_set_upstream | 设置全局上游代理 |
proxy_clear_upstream | 删除全局上游 |
proxy_set_host_upstream | 每台主机上游覆盖 |
proxy_remove_host_upstream | 删除每台主机的覆盖 |
拦截规则(7)
| 工具 | 说明 |
|---|---|
proxy_add_rule | 使用匹配器+处理程序添加规则 |
proxy_update_rule | 修改现有规则 |
proxy_remove_rule | 删除规则 |
proxy_list_rules | 按优先级列出所有规则 |
proxy_test_rule_match | 测试哪些规则与模拟请求或捕获的交换相匹配,并进行详细的诊断 |
proxy_enable_rule | 启用已禁用的规则 |
proxy_disable_rule | 禁用而不删除 |
快速调试示例:
# Simulate a request and see which rule would win
proxy_test_rule_match --mode simulate --request '{"method":"GET","url":"https://example.com/api/v1/items","headers":{"accept":"application/json"}}'
# Evaluate a real captured exchange by ID
proxy_test_rule_match --mode exchange --exchange_id "ex_abc123"流量捕捉(4)
| 工具 | 说明 |
|---|---|
proxy_list_traffic | 带过滤器的分页流量列表 |
proxy_get_exchange | 按ID列出的完整交换详细信息 |
proxy_search_traffic | 跨流量的全文搜索 |
proxy_clear_traffic | 清除捕获缓冲区 |
修改快捷方式(3)
| 工具 | 说明 |
|---|---|
proxy_inject_headers | 在匹配的流量上添加/覆盖/删除标头(将值设置为 null 删除标题) |
proxy_rewrite_url | 重写请求URL |
proxy_mock_response | 为匹配的请求返回模拟响应 |
TLS指纹识别(9)
| 工具 | 说明 |
|---|---|
proxy_get_tls_fingerprints | 获取JA3/JA4客户指纹+JA3S进行单次交换 |
proxy_list_tls_fingerprints | 列出所有流量中唯一的JA3/JA4指纹及其计数 |
proxy_set_ja3_spoof | 传统:启用JA3欺骗(已弃用,请使用 proxy_set_fingerprint_spoof) |
proxy_clear_ja3_spoof | 禁用指纹欺骗 |
proxy_get_tls_config | 返回当前TLS配置(服务器捕获,JA3欺骗状态) |
proxy_enable_server_tls_capture | 切换服务器端JA3S捕获(猴子补丁 tls.connect) |
proxy_set_fingerprint_spoof | 通过impit启用完整的TLS+HTTP/2指纹欺骗。支持浏览器预设。 |
proxy_list_fingerprint_presets | 列出可用的浏览器指纹预设(例如。 chrome_131, chrome_136, chrome_136_linux, firefox_133) |
proxy_check_fingerprint_runtime | 检查指纹欺骗后端准备情况 |
指纹欺骗的工作原理是通过impit从代理重新发出请求(通过rustls进行本机Rust TLS/HTTP2模拟)。TLS 1.3和HTTP/2指纹(设置、WINDOW_UPDATE、优先级帧)通过构造与真实浏览器匹配。源服务器看到代理的伪造TLS、HTTP/2和标头顺序,而不是原始客户端的 user_agent 如果已设置(包括通过预设),代理mcp还会规范Chromium UA客户端提示标头(sec-ch-ua*)以匹配被欺骗的用户代理(转发相互矛盾的提示是一种常见的机器人信号)。 浏览器异常: 当斗篷浏览器通过以下方式启动时 interceptor_browser_launch,文档加载和同源请求使用浏览器的原生TLS(无impit),为机器人检测挑战保留指纹一致性。只有跨源子资源请求才会使用伪造的TLS重新发出。非浏览器客户端(curl、spawn、HAR重放)在所有请求上都会获得完整的TLS+UA欺骗。使用 proxy_set_fingerprint_spoof 浏览器预设为一个命令设置。 proxy_set_ja3_spoof 为了向后兼容而保留,但忽略了自定义JA3字符串(而是使用预设的impit浏览器目标)。捕获JA4指纹(只读),但不支持欺骗。
拦截器(21)
拦截器配置目标(浏览器、进程、设备、容器)以自动通过代理路由其流量。
探索(3)
| 工具 | 说明 |
|---|---|
interceptor_list | 列出所有拦截器的可用性和活动目标计数 |
interceptor_status | 特定拦截器的详细状态 |
interceptor_deactivate_all | 紧急清理:杀死所有类型的所有活动拦截器 |
浏览器(3)
| 工具 | 说明 |
|---|---|
interceptor_browser_launch | 启动带有代理标志、SPKI证书信任和内置人性化模式的隐形浏览器(隐形Chromium) |
interceptor_browser_navigate | 通过Playwright浏览绑定页面 page.goto 并验证代理捕获 |
interceptor_browser_close | 按目标ID关闭浏览器实例 |
隐形是源代码级别:斗篷浏览器提供48个C++补丁,因此ja3n/ja4/akamai与真正的Chrome相匹配, navigator.webdriver 如果为false,则音频/画布/WebGL指纹与真实硬件匹配。不需要JS隐形注射。首次启动会下载约200 MB的Chromium二进制文件(之后缓存)。
迷彩(4)——反检测火狐
| 工具 | 说明 |
|---|---|
interceptor_camoufox_launch | Spawn camofox作为Playwright WebSocket服务器,代理+NSS CA预连线。退货 wsUrl |
interceptor_camoufox_info | 准备好wsUrl+以粘贴TS/Python firefox.connect() 片段 |
interceptor_camoufox_list | 列出活动的迷彩实例及其指纹详细信息 |
interceptor_camoufox_close | 停止启动器,删除临时启动器目录+NSS配置文件 |
Camoufox是一款带有源代码级指纹控件(操作系统、WebGL供应商/渲染器、字体、区域设置、地理IP派生时区、WebRTC阻止、人性化光标)的修补版Firefox。与Chromium路径不同,camofox作为一个外部Python进程运行,并公开了一个Playwright WS端点——调用者使用以下命令驱动页面 await firefox.connect(wsUrl) 而不是通过MCP页面工具。
主机要求:
pip install "camoufox[geoip]"
python3 -m camoufox fetch # downloads patched Firefox binary (~200 MB)
# For TLS MITM trust (NSS profile is created per-launch and the proxy CA is imported):
sudo apt install libnss3-tools # Debian/Ubuntu
sudo dnf install nss-tools # Fedora/RHEL
# macOS: brew install nss (or use /Applications/Firefox.app/Contents/MacOS/certutil)如果 certutil 如果缺少,启动仍然成功,但代理CA不受信任——HTTPS页面将显示证书错误。代理流量仍被捕获。
用途:
proxy_start // start the MITM proxy
interceptor_camoufox_launch { headless: true } // returns { targetId, wsUrl, playwright_connect, ... }
// in your own Node code:
// import { firefox } from 'playwright-core';
// const browser = await firefox.connect(wsUrl);
// const page = await (await browser.newContext()).newPage();
// await page.goto('https://example.com');
interceptor_camoufox_close { target_id } // when doneplaywright-core 已经是代理mcp依赖项——Camoufox使用其 firefox 通过WebSocket访问命名空间;不需要额外的Node包。流量捕获、TLS指纹识别、规则、模拟、会话、上游链和JA3/JA4欺骗都会自动应用于camofox,因为代理位于其前面。
终端/工艺(2)
| 工具 | 说明 |
|---|---|
interceptor_spawn | 生成一个预先配置了代理环境变量(HTTP_proxy、SSL证书等)的命令 |
interceptor_kill | 杀死一个生成的进程并检索stdout/stderr |
设置18个以上的env变量,涵盖curl、Node.js、Python请求、Deno、Git、npm/yarn。
安卓ADB(4)
| 工具 | 说明 |
|---|---|
interceptor_android_devices | 通过ADB列出已连接的Android设备 |
interceptor_android_activate | 完全拦截:注入CA证书、ADB反向隧道、可选Wi-Fi代理 |
interceptor_android_deactivate | 删除ADB隧道并清除Wi-Fi代理 |
interceptor_android_setup | 快速设置:推送CA证书+ADB反向隧道(无Wi-Fi代理) |
注意事项: CA证书注入需要root访问权限。支持安卓14+(/apex/com.android.conscrypt/cacerts/).Wi-Fi代理是可选的(默认关闭)。
安卓Frida(3)
| 工具 | 说明 |
|---|---|
interceptor_frida_apps | 通过Frida列出设备上正在运行的应用程序 |
interceptor_frida_attach | 连接到应用程序并注入SSL unpening+代理重定向脚本 |
interceptor_frida_detach | 从应用程序中分离Frida会话 |
注意事项: 需要 frida-server 在设备上运行。用途 frida-js (纯JS,主机上没有本机二进制文件)。SSL取消绑定包括OkHttp、BoringSSL、TrustManager、系统TLS,但可能不适用于QUIC或自定义TLS堆栈。
Docker(2)
| 工具 | 说明 |
|---|---|
interceptor_docker_attach | 将代理env变量和CA证书注入正在运行的容器中 |
interceptor_docker_detach | 从容器中删除代理配置 |
两种模式: exec (实时注射,现有流程需要重新启动)和 restart (停止+重新启动容器)。用途 host.docker.internal 用于代理URL。
浏览器开发工具等效工具(12)
浏览器目标的剧作家驱动工具。每个都需要一个 target_id directly——没有会话绑定,没有sidecar。适用于两种斗篷浏览器(browser_* ID)和迷彩服(camoufox_* ID)目标通过共享 getPageForTarget() 解析器。
| 工具 | 说明 |
|---|---|
interceptor_browser_snapshot | 页面(或选择器子树)的ARIA/role YAML快照——针对LLM页面推理进行了优化 |
interceptor_browser_screenshot | 屏幕截图。写信给 file_path 如果提供;否则仅报告字节数 |
interceptor_browser_list_console | 自启动以来,使用类型/文本过滤器和分页缓冲控制台消息 |
interceptor_browser_list_cookies | 带有过滤器、分页、截断值预览的Cookie列表 |
interceptor_browser_get_cookie | 在以下时间获得一块饼干 cookie_id (值被限制以保持输出有界) |
interceptor_browser_list_storage_keys | localStorage/session带有值预览的存储密钥列表 |
interceptor_browser_get_storage_value | 通过以下方式获取一个存储值 item_id |
interceptor_browser_list_network_fields | 自浏览器启动以来,代理捕获的流量的标题字段列表 |
interceptor_browser_get_network_field | 通过以下方式获取一个完整的标题字段值 field_id |
interceptor_browser_evaluate | 在页面中运行一个JS文件(文件体包装为 (__args) => { ... });返回结果。 world: "isolated" (默认,隐形)或 world: "main" (仅迷彩服,需要 main_world_eval: true 发射时) |
interceptor_browser_inject_init_script | 将JS文件注入为 page.addInitScript --在下一个导航的每个页面脚本之前运行。斗篷浏览器上最安全的隐形原语;camofox在Juggler特权范围内运行,不修补主世界(迷彩服#48) |
interceptor_browser_add_script_tag | 附录a `` 转到当前页面。 DOM可见——避免隐藏。 用于良性有效载荷,其中主世界执行+页面可见性是有意的 |
网络数据来自MITM代理,而不是浏览器端协议——无论浏览器报告什么,代理都会看到每个有线请求。
JS注入的隐形权衡:
| 方法 | Cloakbrowser | 迷彩 |
|---|---|---|
evaluate isolated | Safe(隔离实用程序世界)--reCAPTCHA之前的速率限制,每个调用都是CDP流量 | Safe |
evaluate main | 不受Playwright API支持 | 通过支持 mw: 前缀,需要 main_world_eval: true 发射时;从页面上完全可观察到 |
add_script_tag | 可检测(DOM节点、MutationObserver、CSP) | 可检测(相同) |
参考文献 剧作家评价, 剧作家addInitScript, 迷彩主要世界eval, 迷彩隐形.
世界和孤立——你的JS能看到什么,不能看到什么
这两个后端提供不同的世界模型。选择错误的工具是迷彩上最常见的隐形脚枪,因此边界很重要。
Cloakbrowser(Chromium)。 剧作家 evaluate 在一个孤立的“公用事业”世界中运行 *与页面的主世界共享全局*一 addInitScript 补丁到 navigator.webdriver 对(a)您的后续用户可见 evaluate 探测和(b)网站加载的反机器人代码。这是大多数“隐形剧本”所假设的模型。检测向量位于CDP侧(Runtime.evaluate chatter)——clokebrowser的C++补丁缓解了这些问题。48个源代码补丁清除了JS可观察到的泄漏(__playwright__binding__,堆栈跟踪 sourceURL 提示)。
迷彩服(Firefox通过Juggler)。 两个严格分离的JS堆:
- 主要世界 --页面是真实的
window.站点脚本、反机器人指纹代码和通过注入的标签addScriptTag跑这里。 - 孤立/杂耍世界 --剧作家的私人视野。不同
window对象,相同的DOM。evaluate(无mw:)以及addInitScript两者均在此着陆。
后果:a addInitScript 那确实 Object.defineProperty(navigator, 'webdriver', { get: () => false }) 补丁 *孤立的* navigator.你的后续 evaluate 探头读取 *相同* 隔离作用域,查看修补后的值,并返回 false.测试通过。 但该网站的检测代码在主世界中运行,并读取未修补的 navigator. 补丁是看不见的。这正是 迷彩服#48.
| 读取 | 读取 | 看到初始化脚本补丁了吗? |
|---|---|---|
interceptor_browser_evaluate (没有 world) | 孤立 | 是 |
interceptor_browser_evaluate world: "main" (迷彩) | 主 | 不 |
| 网站加载的反bot JS | main | 不 |
这不是迷彩服的虫子;这是设计。迷彩伪装指纹 C++二进制 (在启动时通过配置 os, fonts, webgl_config, humanize等),所以主世界JS看到了欺骗的值 *就好像它们是真的一样*Chromium时代“通过运行时补丁”的剧本 addInitScript“这就是迷彩所取代的。
实用规则:
| 用例 | Cloakbrowser | 迷彩服 |
|---|---|---|
| 读取DOM/提取数据 | interceptor_browser_evaluate (孤立) | interceptor_browser_evaluate (孤立) |
| 修改页面状态,通过JS点击 | interceptor_browser_evaluate (隔离;共享全局) | interceptor_browser_evaluate 随着 world: "main" +发射 main_world_eval: true |
| 假导航器/窗口指纹 | interceptor_browser_inject_init_script | 启动时配置(os, fonts, webgl_config, humanize, firefox_user_prefs). inject_init_script 它看起来像是从孤立的探测器中工作的,但页面不会看到它 |
| 将第三方JS库加载到页面中 | interceptor_browser_add_script_tag (页面看到它——如果有意的话,通常可以) | Same——在主世界中运行(对用例有利),但DOM节点是可检测的 |
伪装的强大隐形推论:反机器人代码在主世界运行 简直无法观察 你的 evaluate 阅读。不 Function.toString 泄漏,页面脚本中没有堆栈帧,没有影子全局变量。这是一个不同的世界。同样的隔离使 addInitScript “失败”使刮擦变得不可观察。
会议(13)
持久、可查询的磁盘上捕获,用于长时间运行和崩溃后分析。
| 工具 | 说明 |
|---|---|
proxy_session_start | 开始持续会话捕获(预览或全身模式) |
proxy_session_stop | 停止并完成活动持久会话 |
proxy_session_status | 持久性的运行时状态(活动会话、字节、磁盘上限错误) |
proxy_import_har | 将HAR文件从磁盘导入新的持久会话 |
proxy_list_sessions | 从磁盘列出录制的会话 |
proxy_get_session | 获取一个会话的清单/详细信息 |
proxy_query_session | 对记录的交易所进行索引查询 |
proxy_get_session_handshakes | 报告会话条目的JA3/JA4/JA3S握手元数据可用性 |
proxy_get_session_exchange | 从会话中获取一个交换(可选完整正文) |
proxy_replay_session | 对所选会话请求进行模拟运行或执行重播 |
proxy_export_har | 将完整会话或筛选的子集导出到HAR |
proxy_delete_session | 删除已存储的会话 |
proxy_session_recover | 在不干净关闭后从记录重建索引 |
proxy_get_session_exchange 和 proxy_export_har 根据存储的数据自动解压缩响应体(gzip、deflate、brotli) content-encoding 头球回归 responseBodyText 和 responseBodyBase64 包含解压缩的内容。原始压缩字节保留在磁盘上,以获得精确的重放保真度。
注意 proxy_start 随着 persistence_enabled: true:此自动创建会话。A后续 proxy_session_start() 调用返回现有的活动会话,而不是失败——不需要停止并重新启动。
人性化——剧作家输入(5)
通过Playwright进行类人浏览器输入 page.mouse / page.keyboard,叠加在斗篷浏览器内置的人性化模式之上。绑定到 target_id 从 interceptor_browser_launch.
| 工具 | 说明 |
|---|---|
humanizer_move | 使用Fitts定律速度缩放和简化计时功能沿贝塞尔曲线移动鼠标 |
humanizer_click | 单击定位器(selector / role + name / text / label)或生的 x,y。单击前,自动等待视图中可见+启用+稳定+ |
humanizer_type | 键入文本,每个字符的延迟以WPM、二元组频率、移位惩罚、单词停顿和可选的拼写错误注入为模型 |
humanizer_scroll | 通过多个车轮事件轻松滚动InOutQuad加速/减速 |
humanizer_idle | 通过鼠标微抖动和偶尔的微滚动来模拟空闲行为,以击败空闲检测 |
所有工具都需要 target_id 从先前 interceptor_browser_launch。该引擎在调用过程中保持跟踪鼠标位置,因此 humanizer_move 紧随其后 humanizer_click 产生连续的路径。
行为细节:
- 鼠标路径:具有随机控制点的三次贝塞尔曲线,Fitts定律距离/大小缩放,可选过冲+校正弧
- 打字:WPM的基本延迟,由二元组频率修改(像“th”这样的常见对更快),移位键惩罚,单词边界暂停。可选的拼写错误注入使用带退格校正的QWERTY邻居图
- 滚动:根据easeInOutQuad速度曲线,在多个车轮事件中分布的总增量
- 闲置:周期性微抖动(±3px微妙/±8px正常)和可配置强度的随机微滚动
资源
| URI | 描述 |
|---|---|
proxy://status | 代理运行状态和配置 |
proxy://ca-cert | CA证书PEM |
proxy://traffic/summary | 流量统计:方法/状态细分、顶级主机名、TLS指纹统计 |
proxy://interceptors | 所有拦截器元数据和激活状态 |
proxy://sessions | 持久会话目录+运行时持久状态 |
proxy://browser/primary | 最近启动的浏览器实例的当前页面URL/标题 |
proxy://browser/targets | 所有活动浏览器实例的当前页面状态 |
proxy://camoufox/targets | 带有wsUrl和指纹详细信息的活动camofox实例 |
proxy://sessions/{session_id}/summary | 聚合一个已记录会话的统计数据(资源模板) |
proxy://sessions/{session_id}/timeline | 带时间戳的请求/错误时间线(资源模板) |
proxy://sessions/{session_id}/findings | 顶级错误/慢速交换/主机错误率(资源模板) |
使用示例
# Start the proxy
proxy_start
# Optional: start persistent session recording
proxy_session_start --capture_profile full --session_name "reverse-run-1"
# Configure device to use proxy (Wi-Fi settings or interceptors)
# Install CA cert on device (proxy_get_ca_cert)
# Or use interceptors to auto-configure targets:
interceptor_browser_launch # Launch stealth browser with proxy
interceptor_spawn --command curl --args '["https://example.com"]' # Spawn proxied process
interceptor_android_activate --serial DEVICE_SERIAL # Android device
# Set upstream proxy for geolocation
proxy_set_upstream --proxy_url socks5://user:pass@geo-proxy:1080
# Mock an API response
proxy_mock_response --url_pattern "/api/v1/config" --status 200 --body '{"feature": true}'
# Inject auth headers (set value to null to delete a header)
proxy_inject_headers --hostname "api.example.com" --headers '{"Authorization": "Bearer token123"}'
# View captured traffic
proxy_list_traffic --hostname_filter "api.example.com"
proxy_search_traffic --query "error"
# TLS fingerprinting
proxy_list_tls_fingerprints # See unique JA3/JA4 fingerprints
proxy_set_ja3_spoof --ja3 "771,4865-..." # Spoof outgoing JA3 (for non-browser clients)
proxy_set_fingerprint_spoof --preset chrome_136 --host_patterns '["example.com"]' # Full fingerprint spoof
proxy_list_fingerprint_presets # Available browser presets
# Human-like browser interaction (requires interceptor_browser_launch target)
humanizer_move --target_id "browser_" --x 500 --y 300
humanizer_click --target_id "browser_" --selector "#login-button"
humanizer_click --target_id "browser_" --role "button" --name "Sign in"
humanizer_type --target_id "browser_" --text "user@example.com" --wpm 45
humanizer_scroll --target_id "browser_" --delta_y 300
humanizer_idle --target_id "browser_" --duration_ms 2000 --intensity subtle
# Run / inject JS in the page (cloakbrowser + camoufox)
interceptor_browser_evaluate --target_id "browser_" --script_path /tmp/probe.js
interceptor_browser_evaluate --target_id "camoufox_" --script_path /tmp/probe.js --world main # camoufox + main_world_eval=true
interceptor_browser_inject_init_script --target_id "browser_" --script_path /tmp/hook.js # applies on next navigation
interceptor_browser_add_script_tag --target_id "browser_" --script_path /tmp/lib.js # DOM-visible — avoid for stealth
# Query/export recorded session
proxy_list_sessions
proxy_query_session --session_id SESSION_ID --hostname_contains "api.example.com"
proxy_export_har --session_id SESSION_ID建筑
- 国家:
ProxyManagersingleton管理mocktp服务器、规则和流量 - 规则重建:必须在mocktttp之前设置规则
start(),因此规则更改会触发停止/重新创建/重新启动循环 - 流量捕获:
on('request')+on('response')按请求ID关联的事件 - 环形缓冲区:最多1000个条目,正文预览上限为4KB
- TLS捕获:来自mocktttp套接字元数据的客户端JA3/JA4;服务器JA3S通过
tls.connect猴子补丁 - TLS欺骗:impit(通过rustls进行原生Rust TLS/HTTP2模拟);正在处理中,不需要容器
- 拦截器:由管理
InterceptorManager,每种类型独立注册 - 浏览器:通过Playwright驱动的斗篷浏览器(隐形Chromium,首次启动时自动下载约200 MB二进制文件)
BrowserContext/Page - 人性化工具:使用Playwright的Singleton引擎
page.mouse/page.keyboard自定义定时层(贝塞尔路径、费茨定律、二元组输入)为Playwright提供数据,位于斗篷浏览器内置的顶部humanize: true
测试
npm test # All tests (unit + integration)
npm run test:unit # Unit tests only
npm run test:integration # Integration tests
npm run test:e2e # E2E fingerprint tests (requires cloakbrowser + internet)学分
核心库
| 项目 | 角色 |
|---|---|
| mocktp | MITM代理引擎、规则系统、CA生成 |
| impit | 原生TLS/HTTP2指纹模拟(Rust通过NAPI-RS) |
| 弗里达js | 用于Android仪器的纯JS Frida客户端 |
| 三叶草 | 使用源代码级C++指纹补丁进行隐形修补的Chromium |
| 剧作家核心 | 浏览器自动化API驱动隐形浏览器 |
| @模型上下文协议/sdk | MCP服务器框架 |
供应商Frida脚本
中的所有脚本 src/frida-scripts/vendor/ 源自 httptoolkit/frida拦截和解包 (MIT):
config-template.js--代理/证书配置注入android-certificate-unpinning.js--TrustManager+OkHttp+BoringSSL挂钩android-system-certificate-injection.js--通过KeyStore注入运行时证书android-proxy-override.js--ProxySelector猴子补丁native-tls-hook.js--BoringSLSL/OpenSSL原生挂钩native-connect-hook.js--libcconnect()重定向

