Skip to content

feat(curl): 自研 curl bash 工具 —— 出站自然化 + 证据一等公民 - #110

Open
M09Ic wants to merge 2 commits into
feat/traffic-namespacefrom
feat/curl-tool
Open

feat(curl): 自研 curl bash 工具 —— 出站自然化 + 证据一等公民#110
M09Ic wants to merge 2 commits into
feat/traffic-namespacefrom
feat/curl-tool

Conversation

@M09Ic

@M09Ic M09Ic commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

背景

Issue: chainreactors/cairn-platform#84。

Runner 出站流量"自报家门"(系统 curl 的 curl/x UA、缺浏览器头),一眼是自动化工具。本 PR 用 Go 重写一个 curl 工具(commands.Command名字就叫 curl,shadow 系统 curl,用户/模型无感),把出站规整成贴近真实浏览器,并作为证据一等公民的受控 HTTP 主路径,替代 cairn 侧自研的 http_request(其移除 + 提示词迁移在 cairn 侧后续 PR)。

uTLS 浏览器 JA3 伪装(改 mitmproxy fork 上游握手,覆盖全部工具)是独立后续 PR——因为 curl 走 hub,目标看到的 JA3 由 hub→目标 那一跳决定,落不到 curl 客户端上。本 PR 只做 header 层自然化

改动

新增 tools/curl/

  • parse.go — 手写 curl flag 解析:短 flag 捆绑(-sSL)、--k=v/--k v-d @file-H "Name:"(删默认头)/"Name;"(空值)。未识别 flag 明确报错,不静默忽略、不回退系统 curl。
  • client.go — 从 execution.Env 读 hub 代理(ALL_PROXY 带 tool-call id)+ CURL_CA_BUNDLE(信任被拦截的 HTTPS);自建 RootCAs;-L+--max-redirs 重定向;-G 原样拼 query;-i/-o/-w;浏览器 UA + 头集合仅补缺-A/-H 优先)。
  • cookies.go-b/-c Netscape cookie 往返。
  • curl.goCommand{toolargs.Base} + Run每调用无可变状态,并发安全。
  • register.gocapability.Register + RegisterFactory
  • skills/aiscan/okf/easm/curl.md — 工具 playbook。

接线:cmd/aiscan/imports.go + cmd/runner/main.go blank-import。

可观测性

curl 出站经 hub → aop/traffictool_id 捕获 → runner 侧规整为 http.exchange.v1 证据(脱敏复用)。curl 本身不建证据通道,复用现有机制。

支持的 flag(v1)

-X -H -d --data-raw --data-binary -G -b -c -L --max-redirs -A -e -u -o -i -s -S -w -v -k --connect-timeout --max-time --url

推迟 v1.1:-F(multipart)、--data-urlencode-x(未识别即报错;这些走真 shell 时仍经 env→hub 捕获,证据不丢)。

测试

  • go build ./tools/curlgo vet ./tools/curl
  • go test ./tools/curl — 22 单测(parser + httptest 验证方法/体/默认头/覆盖/重定向/cookie/basic-auth)✅
  • go test ./tools(注册)✅
  • 整机 go build ./cmd/aiscan ./cmd/runner

🤖 Generated with Claude Code

M09Ic and others added 2 commits August 19, 2026 05:13
Reimplement curl as an in-process aiscan bash command (shadowing the
system binary) so HTTP probing is evidence-first and does not announce
itself as automated tooling.

- curl-shaped flag surface: -X/-H/-d(+--data-raw/binary,@file)/-G/-b/-c/
  -L(--max-redirs)/-A/-e/-u/-o/-i/-s/-S/-w/-v/-k/--connect-timeout/--max-time;
  unsupported flags are rejected, never silently ignored.
- routes through the runner MITM hub read from execution.Env (ALL_PROXY
  carries the tool-call id; CURL_CA_BUNDLE trusts intercepted HTTPS), so
  flows attribute by tool_id and are captured as http.exchange evidence.
- browser-shaped User-Agent + header set (Chrome) applied only where the
  caller did not set them; -A/-H always win.
- cookie round-trip (-b/-c) in Netscape format; stateless per-call
  execution to stay safe under concurrent invocations.

Registered in the aiscan CLI and runner binaries; 22 unit tests cover the
parser and the client against httptest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
One model for one request/response pair: flat ordered header Pairs in
memory, the Flow proto as its wire view, and the http.exchange.v1 flow
element as its persisted JSON (headers as name→values map, byte
compatible). Consumers that mirrored the flow shape on both sides of the
wire can now alias this type instead.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant