做过几年安全审计的人大概都有同一个感受:手工翻包翻到后半夜,眼睛盯着十六进制和一堆嵌套 JSON,脑子早就木了,真正有价值的那几条线索,往往是在你已经快放弃的时候才蹦出来的。这两年大模型能力上来了,很多人第一反应是"能不能让模型帮我一起看流量"。答案是能,但前提是你得把整条链路搭对——模型选错,插件配错,提示词写崩,最后得到的只会是一屏看起来很像那么回事、实际上全是幻觉的"高危漏洞"。这套东西我在本地环境里来来回回折腾了很久,从模型选型、量化参数、提示词模板到插件接入、靶场隔离,踩过的坑能写满两页纸。这篇就把 AI 辅助漏洞挖掘这套组合拳拆开讲清楚:Prompt 工程怎么写才不飘,Ollama 本地模型怎么选怎么调,BurpGPT 怎么接进去不把目标打挂,Docker 靶场怎么搭怎么重置,以及最容易被忽略但最容易出事的一环——合规红线在哪里。适合已经有一点 Web 安全基础、想把 AI 真正塞进日常工作流的人,也适合完全没碰过本地大模型、想知道从哪台机器开始动手的新手。
1. 整体方案设计与选型:为什么是"本地模型 + 抓包插件 + 隔离靶场"
先把结论摆前面:一套能长期用下去的 AI 辅助审计环境,核心不是"用最强的模型",而是"让数据不出机器、让请求可控、让实验可回滚"。这三条决定了后面所有的技术选型。我第一次搭的时候图省事,直接调云端接口,跑了两天就发现问题一大堆:流量里带的 Cookie、Token、内网地址全出去了,公司合规那边根本过不了;接口按 token 计费,一个中等规模的站点扫下来账单很难看;更麻烦的是网络抖动,批量请求里断几次,结果就不完整了。后来改成全本地,世界清净了。
1.1 三层能力边界:AI 到底能替你干什么
很多人对 AI 辅助漏洞挖掘的期待是"输入一个域名,输出一堆可利用漏洞"。这个预期必须当场打碎。模型在整条链路里的真实定位是一个不知疲倦的初审员,它擅长的是"读"和"猜",不擅长"证明"。
具体拆成三层比较清楚。第一层是语义理解:把一段 HTTP 请求和响应翻译成人话,指出"这个参数看起来是拼进 SQL 语句的""这个返回体的错误信息泄露了框架版本""这个接口的鉴权字段是放在 URL 里的"。这类判断模型做得又快又准,因为它本质是文本归纳。第二层是模式联想:给它一个参数名和上下文,让它列出"如果这里存在越权,可能的表现形式有哪些",相当于帮你穷举测试方向,避免思路枯竭。第三层是报告撰写:把验证过的结果整理成规范描述,这块是纯体力活的替代。
模型做不了的是:判断漏洞是否真实存在(它只能提出假设)、构造需要绕过特定 WAF 的复杂载荷、理解业务逻辑里的隐含约束。所以正确的工作流永远是AI 提出假设 → 人工或工具验证 → 结果回填给 AI 整理。跳过中间那步,你得到的报告就是一堆经不起复现的垃圾。
注意:任何由模型生成的漏洞结论,在未经实际请求验证之前,都不能写进交付文档。这条底线守不住,整套流程就是负资产。
1.2 为什么优先本地推理而不是云端接口
抛开合规不谈,纯从工程角度看,本地模型在这个场景下有三个实打实的优势。
延迟和并发可控。抓包分析是高频短请求,一个页面几十个资源请求,如果每个都要走公网往返,光排队就够呛。本地推理虽然单次速度不如大厂集群,但没有网络开销,而且并发上限完全由你手里的显卡决定,不会被别人的限流策略牵连。
上下文可以随便喂。为了让模型判断准确,你经常需要把整个请求体、响应头、甚至相邻几个请求一起塞进去。云端接口按 token 收费的模式下,你会不自觉地裁剪上下文,裁着裁着关键信息就没了。本地模型这块成本是固定的电费,num_ctx 开到 8K、16K 都无所谓。
数据不出内网。这是最硬的一条。实际的流量里什么都可能有,账号密码、会话凭证、业务数据、内部接口路径。这些东西一旦离开你的控制范围,性质就变了。本地部署意味着所有推理都在自己机器上完成,日志也可以选择不落盘。
代价当然也有:本地小模型的推理能力和顶级闭源模型差距明显,尤其在需要多步推理的场景下容易跑偏。我的处理办法是分级使用——日常批量初筛用本地 7B 到 14B 级别的模型,遇到疑难样本再人工介入,不指望一个模型包打天下。
1.3 靶场先行的实验纪律
第三个选型是靶场。这里我要强调一个很多人忽视的点:AI 辅助工具本身是有攻击性的。插件会对目标发起主动请求,模型可能生成带有破坏性的测试载荷(比如带DROP字样的注入测试、超大 payload 造成资源耗尽)。如果直接在真实业务上跑,出了问题不是道歉能解决的。
所以整套环境的搭建顺序必须是:先起靶场 → 在靶场上把模型、提示词、插件参数全部调到稳定 → 再考虑接入任何有授权的真实目标。靶场的作用不只是"练手",更是给你的工具链做回归测试。你改了提示词、换了模型版本、调了并发数,都应该先在靶场上跑一遍标准用例,确认结果没有退化。这个习惯我坚持了挺久,救过好几次——有一次升级模型后,它对某类报错信息的敏感度骤降,如果在真实环境里才发现,等于白扫一轮。
2. Prompt 工程:把"找漏洞"拆成模型能消化的任务
这是整篇文章里最容易被低估的部分。大部分人说"AI 找漏洞不好用",真实原因不是模型不行,是问法不对。你让模型"分析这个请求有没有漏洞",它给你的必然是一堆模棱两可的车轱辘话,因为它面对的是一个开放式问题,而开放式问题的答案空间太大。
提示词工程在这个场景下的本质,是把模糊的安全判断拆解成结构化的、有边界的子任务。就像你带新人,你不会说"你看看这个站有什么问题",你会说"你重点看这三个参数,判断它们有没有可能被拼进数据库查询,如果有,说明理由"。
2.1 通用提问为什么必然失效
先看一个反面例子,这也是绝大多数人的第一版提示词:
帮我分析这个 HTTP 请求有没有安全问题 [请求内容]这个提示词的失败原因有三层。第一,任务无边界,模型不知道你关心的是注入、越权、信息泄露还是业务逻辑,它只能泛泛而谈。第二,输出无结构,每次返回格式都不一样,你没法批量处理,也没法做统计。第三,缺少判定标准,模型不知道在你的语境里什么叫"高危",它只能按训练数据里的通用倾向给个模糊结论。
还有一个隐蔽的坑:模型倾向于迎合。如果你在提示词里写了"这个参数看起来可能有注入",它大概率会顺着你说"是的,可能存在注入风险"。这叫谄媚偏差,在安全场景下极其致命,因为它会把你的错误假设放大成"结论"。
2.2 四类核心提示词模板
我在实际使用中沉淀下来四类模板,覆盖了从初筛到成文的全流程。这些模板的共同特征是:角色明确、任务单一、输出结构化、强制要求给出依据。
第一类:请求语义解析。目的是让模型把一段原始流量翻译成结构化描述,为后续判断打基础。
你是一名 Web 应用安全审计员。下面是一段 HTTP 请求与响应。 请只做客观描述,不要下漏洞结论。按以下结构输出: 1. 接口功能推测(一句话) 2. 所有用户可控输入点(参数名 + 位置:URL/Header/Body/Cookie) 3. 响应中泄露的敏感信息(版本号、路径、堆栈、内部字段名) 4. 值得进一步测试的输入点(最多 3 个,按可疑度排序) 如果某项信息在内容中不存在,写"无",不要编造。 请求: --- {request} --- 响应: --- {response} ---注意几个设计细节。"不要下漏洞结论"这句是必须的,否则模型会在描述阶段就开始瞎猜,污染后面的判断。"不存在就写无,不要编造"是防幻觉的关键约束,实测能显著降低它凭空捏造参数名的情况。"最多 3 个"是强制收敛,不设上限的话它会把所有参数都列一遍,等于没排序。
第二类:单点深度研判。拿到第一类的输出后,挑可疑度最高的输入点单独问,上下文更聚焦。
上下文:这是一个 {GET/POST} 接口,参数 {name} 位于 {位置}, 业务功能推测为 {功能}。 请判断参数 {name} 最可能存在哪一类安全风险,并给出推理链: 1. 该参数最可能被服务端如何使用(拼接到查询/作为文件路径/作为重定向目标/仅做展示) 2. 支持这个判断的响应侧证据是什么(引用原文片段) 3. 如果假设成立,应该观察什么样的响应差异来验证 4. 该风险的可能影响范围 只输出有证据支持的判断。如果证据不足,明确说明"证据不足,无法判断"。这个模板里最重要的是第 3 点——让模型告诉你验证方法,而不是直接给载荷。这既符合"假设→验证"的工作流,也避免模型输出一堆没法用的通用 payload。第 2 点要求引用原文片段,是抑制幻觉的有效手段,模型被要求"引用"时,编造的概率会明显下降。
第三类:测试方向穷举。当你对一个接口完全没思路时用,目的是打开思路而不是给答案。
接口信息如下: {结构化描述} 请以安全测试清单的形式,列出针对该接口应当尝试的测试方向, 每个方向给出:测试目的、观察点、判断依据。 按"最可能出问题"到"最不可能"排序,最多 6 条。 不要给出具体攻击载荷,只给测试思路。明确禁止给具体载荷,是有意为之。一来避免模型输出过时或错误的 payload 带偏你,二来降低工具本身的风险属性。你要的是思路,不是武器。
第四类:结果成文。验证完成之后,把事实喂给模型让它整理。
以下是一个已确认的安全问题,事实如下: - 位置:{接口} - 现象:{手工验证时观察到的具体响应} - 复现步骤:{步骤} - 影响:{实际影响} 请整理为规范的问题描述,包含:问题概述、影响范围、复现步骤、修复建议。 严格要求:只能使用我提供的事实,不得补充任何我没有提到的细节或推测。 修复建议请给出通用方向,不要涉及具体产品配置。最后那句"不得补充任何我没有提到的细节"必须加。不然后果很严重——模型会自作主张地"完善"复现步骤,加进去一些你没做过的操作,报告的可信度直接归零。
2.3 让输出稳定的四个参数技巧
光有模板还不够,模型的输出稳定性很大程度上取决于调用参数和上下文管理。
温度(temperature)压到 0.1 到 0.2。安全判断要的是确定性,不是创造性。温度高了,同一个请求跑两次给你两个不同结论,你根本没法用。实测 0.1 在结构化输出任务上最稳,偶尔会有点死板,但比飘忽强。
输出格式用强约束代替请求。与其写"请用 JSON 格式输出",不如直接给一个空模板让它填。更进一步,如果模型支持结构化输出或 JSON 模式,一定要开。解析失败的成本很高,一次格式错乱可能导致整批结果作废。
上下文做裁剪而不是堆砌。一个响应体动辄几十 KB,全塞进去不仅慢,还会稀释关键信息。我的做法是:响应体超过一定长度时,只保留前 2KB 和后 2KB,中间用省略标记;Header 只保留与安全相关的字段(认证、内容类型、自定义头、安全策略头)。这套裁剪规则写死在预处理脚本里,统一执行。
批量任务加序号和分隔符。如果你一次让模型分析多个请求,务必用清晰的分隔标记(比如### 请求 1 开始 ###),并要求它按序号逐条输出。不加分隔的话,模型很容易把两个请求的信息混在一起,产出一段完全错误的"综合分析"。
2.4 提示词也要版本管理和回归测试
这一点很少有人做,但我觉得是分水岭。提示词本质上是你这套系统的核心代码,改一个字可能影响全部输出质量。我的做法是:所有提示词存在独立文件里,用编号管理(p01_parse.md、p02_judge.md……),每次修改记录改了什么、为什么改。
更重要的是建一个小型回归集:从靶场里挑 20 到 30 个有代表性的请求样本,每个样本人工标注"正确答案"(比如"这个参数存在注入可能"或"这个接口无风险")。每次改提示词或换模型,跑一遍这个集合,看准确率和误报率的变化。没有这个集合,你永远不知道自己的调整是变好了还是变差了,全凭感觉。
我自己的经验是,提示词优化的收益在前几轮非常明显(从一堆废话到能用的结构化输出),但到某个点之后就进入平台期,继续微调措辞的边际收益很低。这时候瓶颈往往不在提示词,而在模型本身的能力上限,该考虑换更大的模型或者换思路了。
3. Ollama 本地模型部署:选型、量化与调优
本地模型这块,工具链的选择其实不多。Ollama 的优势在于把模型下载、加载、服务化、API 暴露这几件事打包成了一条命令,对于不想折腾推理框架细节的人来说是最省心的路径。它的接口同时提供原生 API 和 OpenAI 兼容端点,这意味着绝大多数支持自定义 API 地址的客户端和插件都能直接对接。
3.1 硬件与模型规格的匹配计算
选模型之前先算账,这步跳过了后面全是坑。核心公式是:
显存占用 ≈ 参数量 × 每参数字节数 × 1.2(KV Cache 与框架开销)每参数字节数取决于量化精度。常见的几档:
| 量化格式 | 大致比特数 | 每参数字节 | 7B 模型体积 | 14B 模型体积 | 32B 模型体积 |
|---|---|---|---|---|---|
| FP16 | 16 bit | 2.0 | 约 14 GB | 约 28 GB | 约 64 GB |
| Q8_0 | 8 bit | 1.0 | 约 7 GB | 约 14 GB | 约 32 GB |
| Q5_K_M | 约 5.5 bit | 约 0.69 | 约 5 GB | 约 10 GB | 约 22 GB |
| Q4_K_M | 约 4.8 bit | 约 0.6 | 约 4.5 GB | 约 9 GB | 约 20 GB |
再加上 1.2 的开销系数,实际数字还要往上抬一点。举例:14B 模型用 Q4_K_M 量化,权重约 9 GB,加上开销大概 11 GB 左右能跑起来;如果 num_ctx 开到 16K,KV Cache 还要再吃 1 到 2 GB。所以一张 12 GB 显存的卡跑 14B Q4 是比较紧的,16 GB 会舒服很多。
这里有个反直觉的点:安全分析任务对模型规模的要求,比对通用对话任务更高。因为它需要理解协议语义、推断数据流向、识别异常模式,这些都需要一定的推理深度。我试过 3B 级别的模型,输出流畅但判断力明显不足,经常把正常的业务参数标成高危,误报率高到没法用。7B 到 14B 是一个比较现实的平衡点,再往上收益递减但硬件成本陡增。
如果没有独立显卡怎么办?CPU 推理也能跑,7B Q4 在主流桌面 CPU 上大概每秒几个 token,单个请求等十几秒。对于离线批量分析(比如晚上跑一批样本)可以接受,但对于交互式的抓包分析就太慢了。我的建议是:CPU 只用来验证流程,真正日常用还是得有张像样的卡。
3.2 安装与服务化
安装过程本身不复杂,Linux 下用官方脚本一把梭,macOS 和 Windows 也有对应的客户端包。装完之后先确认服务起来了:
# 检查服务状态 ollama --version curl http://127.0.0.1:11434/api/tags第二条命令返回一个 JSON 列表就说明服务正常。默认监听在 11434 端口,只绑本地。
拉取模型按需选择规模,先拉一个小体积的验证链路是否通,再拉你要用的主力模型:
# 先验证链路 ollama pull <小型通用模型> # 再拉主力模型(7B~14B 级别的通用指令模型) ollama pull <主力模型> # 查看本地已有模型与体积 ollama list命令行交互测试一下,确认能正常对话:
ollama run <模型名> "用一句话说明什么是 HTTP 请求走私"如果这一步卡住或者报错,先别急着往下走,问题一定在模型加载层面,最常见的原因是显存不足导致回落到 CPU 但速度极慢,或者模型文件下载不完整。
再验证一下 OpenAI 兼容端点,后面插件对接要用:
curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ollama" \ -d '{ "model": "<模型名>", "messages": [{"role":"user","content":"回复 OK"}], "temperature": 0.1 }'注意:这里的 Authorization 头是占位性质的,本地端点不做真实鉴权,随便填一个非空值即可。但有些客户端在 header 为空时会直接报错,所以别省略。
3.3 用 Modelfile 固化系统提示词
这是我认为最有价值的一个技巧。前面写的四类提示词模板,如果每次调用都拼在用户消息里,既浪费上下文又容易出错。更好的做法是把固定的角色设定和输出约束写进 Modelfile,做成一个专用模型。
新建一个文件,比如sec-auditor.Modelfile:
FROM <你的基础模型> PARAMETER temperature 0.1 PARAMETER top_p 0.9 PARAMETER num_ctx 8192 PARAMETER repeat_penalty 1.1 SYSTEM """ 你是一名 Web 应用安全审计员,只做基于证据的客观分析。 工作原则: 1. 只依据用户提供的请求与响应内容做判断,不引入外部假设。 2. 信息不足时必须明确说明"证据不足",禁止编造参数名、字段名、错误信息。 3. 不下绝对结论,所有风险判断以"可能""倾向于"表述,并附推理依据。 4. 输出严格遵循用户指定的结构,不增加额外章节。 5. 不生成可直接用于攻击的完整载荷,只提供测试思路与观察点。 """然后构建:
ollama create sec-auditor -f ./sec-auditor.Modelfile ollama run sec-auditor "确认你已理解上述原则"这样做的好处很直接:调用方只需要传具体内容,角色和约束由模型自带,提示词模板可以大幅精简,也避免了不同脚本里提示词版本不一致的混乱。更关键的是,安全约束写死在模型层,任何上层脚本都无法绕过,这在多人协作时特别重要。
3.4 并发与环境变量调优
默认配置下 Ollama 一次只处理一个请求,队列会堆积。抓包分析场景往往是十几个请求同时涌进来,必须调整并发参数。通过环境变量控制:
# 同时加载的模型数量(显存够的话可以 >1) export OLLAMA_MAX_LOADED_MODELS=1 # 单模型并行处理的请求数 export OLLAMA_NUM_PARALLEL=4 # 模型空闲多久后卸载(默认 5 分钟,短任务可调小省显存) export OLLAMA_KEEP_ALIVE=10m # 监听地址,只绑本地环回 export OLLAMA_HOST=127.0.0.1:11434OLLAMA_NUM_PARALLEL的调整要配合显存看。每增加一个并行槽位,KV Cache 就要多一份,显存不够会直接 OOM 或者静默降级到 CPU。我的经验值是:12 GB 显存跑 7B Q4,并行设 4 比较稳;跑 14B 就老实设 1 到 2。调高之后一定要观察实际吞吐,如果响应时间反而变长,说明已经在换页了,赶紧调回来。
还有一个实用技巧:批处理时把相似请求排在相邻位置。模型的 KV Cache 对相同前缀有复用效果,如果一批请求的系统提示词完全一致(用 Modelfile 固化就能保证这点),连续处理会比随机顺序快不少。
4. BurpGPT 配置:把模型接进抓包工作流
Burp 生态里的 AI 插件这两年冒出来不少,BurpGPT 这类插件的核心逻辑都差不多:拦截或读取经过代理的请求与响应,按配置的提示词组装成模型调用,把返回结果标注在界面上并写入扫描报告。理解了这个逻辑,配置起来就不会迷路。
4.1 插件的工作模式与请求放大效应
必须先在脑子里建立这个认知:AI 插件是请求放大器。原理上,一个页面的 50 个请求,如果插件对每个都做一次主动分析,那就是 50 次模型调用;如果它还做多轮(先解析再研判),就是 100 次以上。本地模型每小时能处理的量是有限的,配置不当的后果就是任务卡死、界面假死、甚至把目标服务器拖垮。
所以插件一般提供几种工作模式,选型逻辑很清楚:
| 模式 | 行为 | 适用场景 | 风险 |
|---|---|---|---|
| 被动分析 | 只分析已经产生的流量,不发新请求 | 日常浏览时顺手看 | 低,但覆盖面受限于你访问了什么 |
| 主动探测 | 对识别出的输入点自动发起测试请求 | 拿到授权后做系统排查 | 高,可能触发告警或造成数据变更 |
| 手动触发 | 你在 Repeater 里选中某条请求,点一下分析 | 重点接口精查 | 最低,完全可控 |
我个人的用法是默认被动 + 手动触发为主,主动模式基本不开。原因很简单:主动模式发出的请求模式非常规,很容易被目标侧的防护设备识别,而且如果目标有写操作接口,插件很可能在你不注意的时候发出带副作用的请求。这个风险不值得冒。
注意:任何情况下都不要在未授权的目标上开启主动探测模式。这不是技术问题,是性质问题。
4.2 接入本地模型的配置要点
在 Burp 的扩展商店里搜索安装后,找到配置面板,通常需要填这几项:
API 地址:填http://127.0.0.1:11434/v1/chat/completions。如果是 OpenAI 兼容模式,有些插件只要求填 base URL(http://127.0.0.1:11434/v1),插件自己拼路径。两种都试一下,看哪个能通。
API Key:填任意非空字符串,比如ollama。本地端点不做校验,但字段不能空。
模型名称:填ollama list里显示的完整名称,注意要带标签部分(冒号后面的),写错一个字符就会 404。
提示词:直接粘贴前面第二类模板的简化版,或者如果做了 Modelfile,只填任务描述部分。
最大并发 / 请求间隔:这是最关键的两个参数。并发建议从 1 开始,间隔设 500 到 1000 毫秒,观察稳定后再逐步往上加。宁可慢,不可崩。
超时时间:本地模型首次加载需要时间(把权重读进显存),第一次请求可能要等十几秒。超时设 60 秒以上,不然会莫名其妙地报连接失败。
参与分析的字段范围:如果插件支持过滤,务必配置。把静态资源(图片、字体、CSS)排除掉,把健康检查、心跳接口排除掉。这一项能砍掉一半以上的无效调用。
配好之后先用最简单的请求验证:访问靶场首页,看插件有没有正常返回分析结果。如果报错,按这个顺序排查:地址格式 → 模型名拼写 → 服务是否在跑 → 显存是否够。90% 的问题出在前两项。
4.3 结果判读:如何对付高误报
接上之后你会发现一个新问题:插件报的东西太多了,多到没法看。这不是插件的问题,是模型的通病——它倾向于把"可能性"说成"风险"。
我的处理办法是建一个三级筛选漏斗。
第一级,看证据强度。要求提示词强制输出"依据"。没有引用具体响应片段、只说"可能存在风险"的,直接跳过。凡是能明确指认"响应体第 X 行返回了数据库错误信息"的,才进入下一级。
第二级,看可验证性。模型给出的判断,能不能用一条简单的请求证伪?能,就值得花两分钟验一下;不能(比如"可能存在业务逻辑缺陷"这种没法验证的),先记下来放一边。
第三级,看影响面。前两级都过了,才评估影响。这时候基本已经是人工主导了,模型只提供参考。
按这个漏斗走下来,十条模型提示里大概能留下一条值得深挖的。听起来效率不高,但对比纯手工翻包,仍然是数量级的提升——尤其是在你已经疲劳、容易漏看细节的时候,模型的"不知疲倦"是真优势。
4.4 别把插件当成扫描器
最后提醒一句认知层面的问题。很多人把 AI 插件当成新一代漏扫,指望它自动出报告。实际上它的定位更接近"副驾驶":它帮你看、帮你提示、帮你整理,但方向盘在你手里。真正的漏洞确认、影响评估、修复建议,还是得靠人。
我见过有人直接把插件输出整理成报告发给对方,结果里面一半是误报,另一半描述模糊到无法复现。这种交付不但没有价值,还会消耗信任。
5. Docker 靶场搭建:隔离、限流与快速重置
靶场这块看似简单,但要搭得"能长期用"而不是"能跑起来",差别挺大。核心诉求有三个:断网隔离(靶场里的东西绝对不能碰到外部)、资源限制(防止某个容器吃满内存拖垮宿主机)、秒级重置(测崩了能立刻恢复干净状态)。
5.1 为什么用容器而不是直接装
直接在本机装一套带漏洞的应用,最大的问题是污染不可逆。测试过程中会产生大量垃圾数据、修改配置、留下后门文件,测几次之后环境就面目全非,你自己都说不清当前状态。容器的价值在于状态是可丢弃的:down -v一执行,卷清空,下次起来又是全新的。
另一个好处是网络隔离可以做得很干净。Docker 的自定义网络可以把靶场关在一个内部网段里,宿主机只暴露必要的端口,且只绑127.0.0.1。这样即使靶场里有反连类的测试场景,也出不去。
5.2 编排文件的关键写法
下面是一份我常用的骨架,重点是网络和资源限制这两块:
services: target: image: <你本地的靶场镜像> container_name: lab-target ports: - "127.0.0.1:8088:80" networks: - labnet mem_limit: 512m cpus: "0.50" pids_limit: 128 restart: "no" environment: - TZ=Asia/Shanghai db: image: <数据库镜像> container_name: lab-db networks: - labnet mem_limit: 512m environment: - MYSQL_ROOT_PASSWORD=lab_only_password volumes: - dbdata:/var/lib/mysql restart: "no" networks: labnet: driver: bridge internal: true volumes: dbdata:几个关键点解释一下。
127.0.0.1:8088:80这种写法把端口只绑在环回地址上,局域网里的其他机器访问不到。很多人图方便写8088:80,等于把靶场暴露在局域网里,一旦有人扫到,性质就变了。
internal: true让这个网络完全没有对外出口。靶场容器之间能互访,但出不去公网,也访问不到宿主机上的其他服务。这个设置能挡掉很多意外。
mem_limit和cpus是我吃过亏之后必加的。有一次跑一个需要大量计算的测试,容器把宿主机内存吃满,整台机器卡死,只能硬重启。加了限制之后最坏情况就是这个容器被 OOM 杀掉,宿主机安然无恙。
restart: "no"是刻意的。测崩了就该停下来,让它自动重启反而会掩盖问题。
5.3 起停与重置的标准动作
# 启动(后台) docker compose up -d # 看状态,确认都是 running 而不是 restarting docker compose ps # 看日志排错 docker compose logs -f target # 停止并清空数据(回到初始状态) docker compose down -v # 彻底清理:包括悬空镜像层 docker system prune -f日常节奏是这样的:开始一轮测试前down -v重置一次,保证干净;测试过程中如果需要恢复,同样down -v再up -d,整个流程三十秒内完成。这个速度是容器方案最大的价值——敢于破坏,因为恢复成本极低。
5.4 靶场里怎么用 AI
靶场上跑 AI 分析,目的不是"找到漏洞"(靶场的漏洞是已知的),而是校准你的工具链。具体做法:
先手工确认一遍靶场里某个漏洞的存在与否、位置、表现,把这个作为标准答案。然后用工具链跑一遍,对比结果。模型有没有指出来?指出来了,描述准不准?没指出来,是提示词的问题还是模型能力的问题?描述里有没有编造不存在的东西?
这个对比过程重复十几个样本,你对这套工具的脾性就有数了。知道它在什么场景下可靠、什么场景下容易翻车,比单纯堆参数有用得多。
6. 合规规范:整套流程里最不能省的一环
技术讲完了,说点更重要的事。这类工具链的威力在于"能自动发现问题",风险也在于此——它同样能自动制造麻烦。合规这块我列几条硬要求,都是实践中总结出来的。
6.1 授权边界必须先落到纸面
任何对非自有系统的测试,前提都是书面授权。口头同意不算,聊天记录里说"你可以试试"也不算。授权文件需要明确:测试目标的域名和 IP 范围、测试时间段、允许的测试类型、禁止的操作(比如拒绝服务类、数据删除类)、应急联系人。
为什么强调范围?因为 AI 工具的行为不完全可控。你配了一个提示词,模型可能生成你没预料到的测试方向,插件可能把它发出去了。如果这个请求落在了授权范围之外的系统上,责任在你,不在工具。
实操建议:在代理工具里配置严格的作用域(Scope),只允许目标域名通过,其他一律拦截。这一条能挡掉 90% 的意外。同时把靶场和真实目标分在不同项目里,避免混淆。
6.2 数据不出环境
这条前面提过,这里展开。本地部署的最大价值就是数据不出机器,但很多人配着配着就破了功——比如为了"效果更好",在某个环节偷偷调了云端接口;或者把抓到的流量贴到公开的在线工具里做格式转换。
具体要求:模型推理全部本地;流量样本存储在本机加密卷里;如果要把样本发给同事,先做脱敏(把 Cookie、Token、手机号、身份证号之类的字段替换成占位符)。脱敏这一步建议写成脚本自动做,靠手工改容易漏。
6.3 全程留痕
测试过程的记录,既是交付依据,也是自我保护。需要留的东西包括:授权文件、测试时间线、每个发现对应的原始请求响应、验证步骤。这些如果靠手工整理,工作量很大,所以应该在一开始就设计好——代理工具的日志功能打开,项目文件定期归档,模型输出的结论和人工验证的结论分开存放。
有个细节:AI 生成的原始输出也要留档。万一后续对某个结论有争议,你能拿出"模型提示了什么、我验证了什么、最终结论是什么"这条完整链路,而不是只剩一个孤零零的结论。
6.4 报告里不要出现模型痕迹
最终交付的报告,读起来应该是一份正常的安全评估报告,而不是"AI 分析结果汇总"。这意味着:所有结论都经过验证、所有描述都有人工把关、不出现"模型认为""AI 判断"之类的表述。工具是你的工具,责任是你的责任,没必要也不应该在报告里做区分。
7. 常见问题与排查速查
把这段时间遇到的问题整理成表,方便对照。
7.1 模型侧问题
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 首次调用卡住十几秒 | 模型正在加载进显存 | 正常现象,把客户端超时调到 60 秒以上 |
| 响应速度突然变得极慢 | 显存不足,回落到 CPU 推理 | 减小模型规模或降低 num_ctx,用nvidia-smi看占用 |
| 输出中途截断 | 达到最大输出长度限制 | 调高 num_predict,或让提示词要求更简洁 |
| 中文输出夹杂英文术语 | 基础模型的语料倾向 | 在系统提示词中明确要求"全部使用中文" |
| 同一个输入两次结论不同 | temperature 过高 | 压到 0.1~0.2,并固定随机种子(如果支持) |
| 服务启动报端口占用 | 已有实例在跑 | 查进程杀掉,或改OLLAMA_HOST换端口 |
7.2 插件侧问题
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 提示 401/403 | API Key 为空 | 随便填一个非空字符串 |
| 提示 404 | URL 路径或模型名写错 | base URL 结尾不要带多余斜杠,模型名严格对照ollama list |
| 界面卡死无响应 | 并发过高,请求排队 | 并发降到 1,加请求间隔 |
| 大量重复分析同一请求 | 未配置去重或过滤 | 开过滤,排除静态资源和重复 URL |
| 分析结果全是套话 | 提示词过于宽泛 | 换成结构化的分类模板,强制要求引用证据 |
7.3 靶场侧问题
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 容器起来又立刻退出 | 依赖服务未就绪 | 看日志,加健康检查或依赖顺序 |
| 页面能开但功能报错 | 数据库未初始化完成 | 等几十秒再访问,或检查初始化脚本 |
| 宿主机变卡 | 容器未限制资源 | 补mem_limit和cpus |
| 端口冲突 | 本机已有服务占用 | 换宿主侧端口,或先停掉冲突服务 |
| 数据残留导致结果异常 | 卷未清空 | down -v彻底重置 |
7.4 几条不太容易想到的避坑经验
第一条,别在靶场和真实目标之间共用同一个插件配置。意思是你为靶场调的提示词可能过于宽松(因为靶场里什么都是漏洞),拿到真实目标上会疯狂误报。建议维护两套配置,靠代理工具的"项目"功能隔离。
第二条,模型升级要谨慎。新版本不一定更好。我遇到过升级之后模型对某些错误信息的敏感度下降的情况,表面上输出更"通顺"了,但关键细节被平滑掉了。升级前一定跑一遍回归集。
第三条,别指望模型理解你的业务。它不知道这个接口是给谁用的、什么数据算敏感、什么操作有副作用。凡是涉及业务语义的判断,必须人工介入。我吃过一次亏:模型把一个正常的批量查询接口标成"可能存在越权",理由是"参数是用户 ID"。这个判断在技术上没错,但那个接口本来就只能查自己的数据,模型看不到这层约束。
第四条,记录每次配置变更。模型、量化、num_ctx、温度、提示词版本、插件并发,这些参数任何一个变了都可能影响结果。用一个简单的表格记录变更时间和内容,出问题时能快速定位是哪次改动引起的。
第五条,给工具链设一个"停机条件"。比如连续 10 条结果都是误报,就停下来检查提示词,而不是继续硬跑。机器不会累,人会,让机器带着错误的配置跑一整夜,第二天面对几百条垃圾结果,那种挫败感很消耗人。
7.5 一个简化的工作流清单
最后把整套流程串一下,方便照着走:
- 启动靶场,
down -v重置到干净状态 - 确认模型服务在跑,用一条简单请求验证 OpenAI 兼容端点
- 打开代理工具,配置作用域只允许靶场域名
- 手动浏览靶场,产生基础流量
- 用第一类提示词批量做语义解析,筛出可疑输入点
- 对可疑点用第二类提示词深度研判,拿到验证思路
- 手工验证,记录原始请求响应
- 用第四类提示词整理成文,人工复核
- 归档项目文件,记录本次配置参数
down -v清理环境
这套流程跑顺了,单个中等复杂度目标的初筛时间能从大半天压缩到两三个小时,而且因为每一轮都有记录,回溯起来也方便。我个人在实际操作中的体会是,AI 在这个环节最大的价值不是"更聪明",而是"更稳定"——它不会因为连续看了三百个请求就开始走神,也不会因为前面几个都是误报就降低后面的敏感度。人做不到这点,所以把重复劳动交出去,把判断留给自己,这个分工是成立的。