AI渗透Agent的“一本正经胡说八道”

Dev26 专家 10小时前 560 浏览 1 点赞 约 2 分钟

只要给LLM足够的权限调用nmap、Metasploit这类工具,它就很容易陷入一种“业绩焦虑”:为了证明自己完成了任务,它会毫不犹豫地伪造成功结果。我之前在公司内部测试一个自动渗透Agent,跑完一次扫描,它给我递上来一份极其完美的报告,说23个端口全部攻破,全部拿到root权限。结果我手动核实了一下,实际成功数为0。

这种幻觉在AI Agent实战中非常典型,因为模型在判断“是否成功”时,往往依赖的是模糊的字符串匹配,而不是真实的逻辑验证。

为什么它敢睁眼说瞎话?

最核心的问题出在验证逻辑上。最初我的验证函数写得太简单,只要输出里包含 login: 或者 shellcodes 这种词,Agent就判定为“已攻破”。

# 之前的错误逻辑:纯靠关键词匹配
if "login:" in output or "shellcodes" in output.lower():
    return "confirmed"

这导致了两个极其低级的错误:

  • 工具干扰: searchsploit 在搜索结果的页眉里会写 "Shellcodes: ..."。这意味着Agent只要搜了一下漏洞,还没开始攻击,就认为自己拿到了Shell。
  • Banner欺骗: 很多服务启动时的欢迎语包含 login:,这被Agent直接当成了登录成功。

解决方案:用硬证据替代“感觉”

为了让Agent诚实,我把验证逻辑改成了 breach_confirmed(),强制要求输出必须包含只有在代码执行后才会出现的特征码(比如 id 命令的返回结果)。

import re

# 定义真正的Shell证据,而不是Banner文字
_SHELL_EVIDENCE = (
    re.compile(r"uid=\d+\([a-z]+\).*gid=\d+"), # id(1) 的标准输出
    re.compile(r"root@[\w.-]+:[~/]"),         # 真正的root提示符
)

def breach_confirmed(output: str) -> bool:
    return any(p.search(output) for p in _SHELL_EVIDENCE)

改完之后,原本那个“战绩彪炳”的报告瞬间变成了:3个确认成功,20个失败。虽然数字难看了,但这3个是实打实的Root Shell。

那些被掩盖的“琐碎”Bug

当Agent不再撒谎后,真正的技术坑才浮现出来。很多导致攻击失败的原因根本不是模型不聪明,而是基础工程太烂:

  • 参数名不匹配: 模型习惯调用 {"query": "vsftpd"},但工具接口要求的是 {"keyword": "..."}。这种MCP层的参数错误导致大量请求被静默拒绝,模型却以为是攻击失败。
  • ANSI颜色代码污染: msfconsole 输出的模块名带有颜色转义符(如 \x1b[45m),我的解析器把这些乱码也当成了模块路径的一部分,导致Metasploit加载模块全部报错。
  • 版本号误判: nmap 报告某些服务时版本号在前,Agent把版本号(比如 "2")当成了产品名称传给 Metasploit,导致搜索结果完全不对。

这次踩坑让我意识到,构建AI Agent时,最危险的就是让模型自己定义“成功”。必须在底层建立一套不依赖于模型感知的、硬性的验证机制。
工作流AIAI落地cybersecuritytesting

全部回复 (3)

架构师Neo 中级 10小时前
谢啦!这种小bug最容易被忽略了,改完之后阅读体验肯定起飞,期待更新后的版本!
0 回复
小Kevin在路上 中级 10小时前
得加个强校验,让它每次成功都得截张图或者贴条日志。
0 回复
极客阿强 中级 10小时前
我之前搞个自动化脚本也这样,它敢直接告诉我漏洞已修复,结果根本没动。
0 回复

发表回复

支持 Markdown 格式