Agent 沙盒审计:记录沙盒内所有系统调用,事后分析 Agent 有没有越权行为

你让 Agent 整理服务器日志,它第一步不是读日志,而是悄悄读取了 /etc/passwd。沙盒没有拦它,因为读文件这个动作本身是允许的。这不是漏洞,而是 Agent 安全最麻烦的现实:你不可能把智能体所有可能的意图都提前写进白名单。所以安全界有个共识:沙盒负责限制行动范围,审计负责回答它到底做了什么

AI technology illustration

我先踩的坑:沙盒不是保险箱

我最早做 Agent 安全时,以为沙盒就是终点。后来发现两个问题。第一,Agent 极易被提示注入诱导,执行一串表面上合法、实际上越权的操作。比如它为了完成任务,去读取了不该读的环境变量,再通过一次正常的 connect 调用把结果外发出去。第二,沙盒的边界是人配的,配置一旦有疏漏,所有防护归零。审计的逻辑不一样:它不尝试预判所有攻击,而是把 Agent 的所有动作记录在案,事后再问一句:这些动作是不是越权?这听起来简单,做起来难点不少。

系统调用:Agent 在沙盒里唯一的动作接口

要记录动作,先理解 Agent 在沙盒里怎么和世界打交道。任何进程要访问文件、网络、设备,都必须通过操作系统内核,而内核暴露给用户程序的唯一入口就是系统调用(syscall)。你可以把系统调用想象成一道传送带:用户程序想从操作系统拿任何东西,都把请求写成标准卡片放到传送带上,内核审核后把结果送回来。Linux 上系统调用有几百个,比如 openat 打开文件、read 读取内容、connect 建立网络连接、execve 执行新程序,绕不过它们。所以,记录系统调用就等于给 Agent 的一举一动录了像

系统调用(syscall)
用户程序请求内核服务的唯一接口,如打开文件、网络读写、创建进程。
沙盒
一个受限运行环境,通过限制进程能访问的资源与能调用的系统调用来缩小攻击面。
审计
记录关键事件并生成日志,用于事后追踪与分析。
越权行为
Agent 执行了超出用户或任务授权范围的操作。

记录工具选型:只有三种适合上生产

Linux 上记录系统调用的方案不止一种。最早我想到的是 strace,每个调试过 Linux 程序的人都知道它。但 strace 用 ptrace 拦截每次调用,性能开销极大,Agent 一跑起来系统就抖,根本没法上生产。真正适合生产的有三种。

  1. auditd:Linux 内核自带的审计子系统,可以按进程、用户、系统调用类型过滤并记录事件,同时保持较低开销。日志默认写到 /var/log/audit/audit.log,常用于合规和取证。具体规则写在内核文档里。
  2. seccomp:与其说它是审计,不如说它是限制。它允许你给进程设置系统调用白名单,白名单之外的调用直接拒绝。但这也意味着你要精确预知 Agent 需要哪些调用,否则业务随时会被打断。
  3. Falco:CNCF 下的运行时安全项目,用 eBPF 在内核层做事件采集,比 ptrace 高效得多。它不仅能记录,还能实时检测可疑模式并触发告警,规则语法见 Falco 官网
方案 机制 能实时阻断吗 生产可用性
strace ptrace 拦截 只适合调试
auditd 内核审计模块 否,只记录 高,日志可长期留存
seccomp 内核过滤器 能,拒绝调用 高,但易误杀
Falco eBPF 事件流 可联动响应 高,适合实时检测

实际落地上,我倾向用 seccomp 划定底线,用 auditd 记录全量调用,再用 Falco 做实时异常检测。三层各司其职:seccomp 管不能做什么,auditd 管做了什么,Falco 管正在做什么异常的

怎么判断越权?白名单、规则和基线

拿到日志之后,核心问题来了:怎么知道哪条调用是越权?最朴素的办法是白名单比对。启动 Agent 前,把它的任务可能访问的文件路径、网络地址、可执行程序都列出来,审计日志逐条比对,超出范围就标红。比如你想记录每一次打开文件的操作,可以这样给 auditd 加规则:

auditctl -a always,exit -S openat -F success=1 -k agent_file_access

这条规则会让内核记录所有成功的 openat 调用,并打上 agent_file_access 标签,之后用 ausearch 就能按标签快速检索。但白名单有两个问题。一是定义成本高,Agent 行为有不可预测性,任务稍复杂,白名单就不得不放宽到形同虚设。二是它只看单条调用,看不出调用组合里的恶意。比如 Agent 连续读取 30 个配置文件,又向外部 IP 发起连接,单独看都合法,组合起来就是在测绘你的基础设施。所以更有效的方式是规则与基线结合。以 Falco 为例,你可以写一条规则:任何沙盒内的 Agent 进程读取 /etc 下大量文件并建立外部连接,触发告警。简化版规则长这样:

- rule: agent-suspicious-data-exfiltration
desc: Agent reads sensitive files and connects to network
condition: evt.type in (openat, connect) and fd.name startswith /etc and outbound
output: Flagged system call: %evt.type %fd.name
priority: WARNING

规则不是万能的,但好处是你可以把业务授权和威胁情报写进去,形成一层可解释的检测逻辑。再往下走一步,还有异常检测。用正常任务跑一段 Agent,收集系统调用序列做成行为基线,之后每次任务对照基线,偏离到阈值就告警。问题在于,Agent 的探索行为天然随机,基线很容易误报。我目前的经验是:异常检测适合做线索,不适合做结论,最终判断还得回到规则和白名单。

审计日志必须远程保存

这里我栽过跟头。有一段时间我以为把审计日志存进沙盒本地磁盘就够了。直到一次测试中,Agent 被提示注入诱导执行了清理命令,把审计日志一起删了。那一刻我才真正意识到:审计日志必须远程流式传输到沙盒外部,最好进集中式日志平台,任何 Agent 进程都无权访问。否则,案发现场的监控录像就在凶手手里。审计还有一个绕不开的挑战:日志量。一个活跃的 Agent 每分钟可能产生数万条系统调用事件。全量记录成本会失控。我目前的做法是:全量记录安全相关的调用(文件、网络、进程),普通读写性能类调用做降采样。说白了,审计也要做业务分层。

审计的边界:能记录行为,不能解释意图

日志告诉你 Agent 打开了某个文件,但日志不告诉你它为什么打开。要判断越权,必须结合任务上下文、用户授权范围和会话内容。这也意味着审计不能单独存在。再往后推一步:如果沙盒所在的内核被攻破,攻击者完全可以篡改日志流。所以审计不是绝对的信任,只是深度防御的一环。OWASP 的 LLM 应用 Top 10把不安全的插件设计和过度授权列为独立风险,这恰好印证了审计存在的意义:你无法消灭风险,但可以把风险缩小到可观测、可问责的范围。

常见误区:审计能代替安全限制吗?

不能。审计是事后视角,限制是事前视角。没有 seccomp 或 cgroup 兜底,Agent 可能在一个晚上把生产环境玩坏,审计只能帮你复盘损失。反过来,没有审计,你连被入侵了哪台机器都不知道。

记录所有系统调用就等于知道一切吗?

不完全是。系统调用是主路,但不是唯一的信息泄露途径。例如 Agent 可以通过轮询 /proc、测量 CPU 时间推测其他进程的活动。更完整的审计需要结合网络流量、文件完整性监控和平台侧日志。但系统调用日志仍然是目前覆盖最全、最底层的行为证据。

最后说说我的判断。Agent 沙盒审计不是一个能一键防住所有攻击的产品,它更像是安全体系里的档案部:平时没人注意,出事时它就是唯一能还原真相的记录。对一个要接入生产系统的 Agent 来说,精准的限制、实时的检测、完整的审计,三者缺一不可。而审计这一环,恰恰是很多团队最后才补的。如果你的 Agent 还在裸奔,先从开启审计做起。至少你还有机会知道,它昨天到底在服务器上干了什么。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/551.html

(0)
上一篇 2天前
下一篇 2天前

相关推荐