news 2026/4/16 12:18:20

AI 辅助开发实战:基于大模型的 Web 漏洞扫描系统毕设架构与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI 辅助开发实战:基于大模型的 Web 漏洞扫描系统毕设架构与实现


背景痛点:毕设场景下的“祖传”扫描器为何难用

做毕设选 Web 漏洞扫描器,听起来高大上,真动手才发现传统开源工具(w3af、OpenVAS、Nikto 等)在本科阶段几乎跑不通:

  1. 规则库动辄上万条,Git LFS 拉取就掉线,笔记本硬盘直接告急。
  2. 误报高到怀疑人生:一个「X-Powered-By」头没擦,直接报 20 条「信息泄露」;答辩时老师一句「你确定这是漏洞?」就卡壳。
  3. 插件语言百花齐放(C++、Lua、Python2.7),毕设周期只有 3 个月,光配环境就过去一半时间。
  4. 最致命:规则=硬编码,一旦目标站把登录口从/login.php改成/sign/in,扫描器直接失明,而本科毕设不可能让你写几千条正则去“兜底”。

于是把希望寄托在「AI 辅助」——让大模型做苦力,我负责架构与验证,这才有了下面的实战记录。

技术选型对比:规则引擎 vs. LLM 辅助决策

维度传统规则引擎LLM 辅助决策
维护成本新增漏洞需人工写正则、插件,周期长改 prompt 即可,分钟级迭代
误报率高,依赖白名单过滤中等,可要求模型“给出理由+置信度”
漏报率高,规则未覆盖就跳过低,模型可泛化到未见过的模式
执行性能毫秒级秒级(GPU 预热甚至 10s+)
离线场景完全可离线7B 模型可 CPU 跑,但需 6G+ 内存
可解释性正则即证据,老师看得懂自然语言推理,需额外落库留痕

结论:毕设不是商业项目,「能跑+能改+能讲清楚」优于「极致性能」。因此采用「混合架构」:

  • 用规则做「高频低危」快速过滤(如 robots.txt 泄露)
  • 用 LLM 做「低频高危」研判(如存储型 XSS、SQL 注入的语义确认)

核心实现:Python + Playwright 动态爬虫 × 开源 LLM

系统架构图

1. 动态爬虫模块(crawler.py)

职责:渲染 SPA、自动填表、维护 Cookie 池,输出「请求-响应」对给下游。

关键实现点:

  • 每个页面最大深度 3,防止无限递归
  • 相同 URL 仅爬一次,幂等靠page.url + postData 的哈希
  • 全局请求拦截器统一打时间戳,方便后续限速
import asyncio, hashlib, json from playwright.async_api import async_playwright class DeepCrawler: def __init__(self, max_depth=3, max_pages=200): self.visited = set() self.max_depth = max_depth self.max_pages = max_pages async def crawl(self, entry: str): async with async_playwright() as p: browser = await p.chromium.launch(headless=True) page = await browser.new_page() await self._dfs(page, entry, depth=0) await browser.close() async def _dfs(self, page, url, depth): if depth > self.max_depth or len(self.visited) >= self.max_pages: return key = self._url_key(url, await page.content()) if key in self.visited: return self.visited.add(key) # 真正发出请求 await page.goto(url, wait_until='networkidle') # 收集表单 forms = await page.locator('form').element_handles() for form in forms: await self._handle_form(page, form, depth) def _url_key(self, url, body): return hashlib.sha256(f"{url}{body[:500]}".encode()).hexdigest()

幂等性说明:_url_key把 URL 与响应前 500 字节一起做摘要,确保重复跳转不会二次入库。

2. LLM 客户端(llm_gate.py)

采用 Llama.cpp 7B-chat 量化版,本地 CPU 可跑,延迟 2~3 秒。

职责:

  • payload 生成(给定参数名、类型,让模型「脑补」攻击向量)
  • 响应研判(把响应体切片喂给模型,要求输出「是否漏洞+理由+置信度 0-1」)
from llama_cpp import Llama class LlamaGate: def __init__(self, model_path: str, n_ctx=4096): self.llm = Llama(model_path=model_path, n_ctx=n_ctx, logits_all=False) def prompt_payload(self, param: str, context: str) -> list[str]: tpl = f"""Below is a web form parameter "{param}" in context: {context} List 5 classic payloads for testing XSS or SQLi. No explanation.""" output = self.llm(tpl, max_tokens=200, temperature=0.8) return [p for p in output['choices'][0]['text'].split('\n') if p] def judge(self, payload: str, response_snippet: str) -> tuple[bool, str, float]: tpl = f"""Payload: {payload} Response snippet: {response_snippet} Is the above response indicating a successful XSS or SQLi? Answer JSON only: {{"vuln": boolean, "reason": "...", "confidence": 0.0-1.0}}""" out = self.llm(tpl, max_tokens=120, temperature=0.1) try: obj = json.loads(out['choices'][0]['text']) return obj['vuln'], obj['reason'], obj['confidence'] except Exception as e: # 模型偶尔输出非 JSON,保守返回 return False, f"parse error: {e}", 0.0

错误处理:解析失败即视为无漏洞,宁可漏报也不误报,符合毕设「演示优先」原则。

3. 扫描调度器(scanner.py)

把上面两个模块串起来,并加入速率限制、敏感字段脱敏。

import asyncio, re, time from crawler import DeepCrawler from llm_gate import LlamaGate class AIDrivenScanner: def __init__(self, llm: LlamaGate, rps=5): self.llm = llm self.rps = rps self.last_req = 0 async def scan(self, target: str): crawler = DeepCrawler() await crawler.crawl(target) for req_resp in crawler.collected: await self._test_with_ai(req_resp) async def _test_with_ai(self, rr: dict): # 速率控制 gap = 1 / self.rps await asyncio.sleep(max(0, gap - (time.time() - self.last_req))) self.last_req = time.time() # 脱敏:把手机号、邮箱替换成占位符 body = self._desensitize(rr['response_body']) for param in rr['params']: payloads = self.llm.prompt_payload(param, rr['context']) for p in payloads: vuln, reason, conf = self.llm.judge(p, body[:1500]) if vuln and conf > 0.7: print(f"[VULN] param={param} payload={p} reason={reason}") def _desensitize(self, text: str) -> str: text = re.sub(r'\b1[3-9]\d{9}\b', '<PHONE>', text) text = re.sub(r'\b[\w.-]+@[\w.-]+\.\w+\b', '<EMAIL>', text) return text

Clean Code 要点:

  • 函数不超过 30 行,一眼看完
  • 幂等:多次调用_test_with_ai不会重复插入漏洞(去重 key 由 crawler 保证)
  • 错误隔离:LLM 抛异常只丢单条 payload,主流程继续

安全性与性能考量

  1. 请求频率:默认 RPS=5,可在路由器层再套令牌桶,防止把靶站打挂。
  2. 敏感信息脱敏:日志、prompt 里一旦出现身份证、手机号直接掩码,防止「扫描器本身成为泄露源」。
  3. 模型冷启动优化:Llama.cpp 支持mmap,首次加载 3.8 GB 模型需 8-10 秒;在毕设演示前先把进程常驻,用unix socket做守护,避免老师点按钮后空等。
  4. 内存控制:7B 模型在 0.5 量化后约 3.8 GB,再留 1 GB 给 Playwright,8 GB 笔记本刚好跑得动;若目标站过大,可关浏览器多进程--single-process省 30% 内存。
  5. 超时与重试:Playwright 默认 30 秒网络空闲,遇到大文件下载会卡;在page.gototimeout=10 000并捕获TimeoutError,重试一次即可。

生产环境避坑指南(别问为什么强调,踩过)

  • 过度依赖 AI 导致漏报:LLM 对「时间盲注」这类延迟响应无感,务必保留传统sleep()检测链。
  • 输出不可控:模型可能返回「我认为这是漏洞」但置信度 0.51,答辩时被老师追问「依据呢?」——务必把reason落库,并展示原始响应片段,人工复核。
  • 法律红线:扫描公网需授权,毕设靶场建议用 Vulhub 或自建 Docker 镜像;日志里若记录真实学生手机号,属于「个人信息处理」,需做匿名化。
  • GPU 云主机费用:AutoDL 按量 1.4 元/小时,演示 10 分钟花 2 元,可接受;但切记关机,否则通宵跑 30 块就没了。

可改进方向 & 留给读者的思考题

  1. payload 生成策略目前靠「无脑枚举」,能否让 LLM 先读 OpenAPI 文档,再针对性生成符合字段语义的攻击向量?
  2. 如何把「自动化」与「人工验证」量化平衡?例如设定业务阈值:置信度>0.9 自动报 bug,0.7-0.9 发企业微信待人工点确认,<0.7 直接丢弃。
  3. 响应体过大时,先让模型读摘要(html2text 后 2 000 字符),再逐步放大窗口,能否在保持精度的同时降低延迟?

动手改一改,你会发现毕设不止「能跑」,还能「讲出故事」。祝你答辩顺利,也欢迎把改进后的 prompt 和代码回馈到社区,一起把 AI 辅助安全做得更靠谱。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 20:11:32

Qwen-Image-2512 GPU算力优化实测:CPU卸载策略让显存占用趋近于零

Qwen-Image-2512 GPU算力优化实测&#xff1a;CPU卸载策略让显存占用趋近于零 1. 为什么“显存几乎为零”这件事值得专门写一篇实测&#xff1f; 你有没有遇到过这样的情况&#xff1a;刚部署好一个文生图模型&#xff0c;兴奋地打开WebUI&#xff0c;输入提示词点下生成——…

作者头像 李华
网站建设 2026/4/16 9:03:16

MedGemma-X效果实测:在LUNA16数据集上F1-score达0.891

MedGemma-X效果实测&#xff1a;在LUNA16数据集上F1-score达0.891 1. 这不是又一个CAD工具&#xff0c;而是一次影像阅片方式的重构 你有没有试过把一张胸部X光片上传给AI&#xff0c;然后直接问它&#xff1a;“左肺下叶这个结节边界是否清晰&#xff1f;周围有无毛刺征&…

作者头像 李华
网站建设 2026/4/16 9:01:27

显存不足怎么办?GLM-TTS优化技巧大公开

显存不足怎么办&#xff1f;GLM-TTS优化技巧大公开 显存告急、合成卡顿、OOM报错——当你满怀期待点下「 开始合成」&#xff0c;屏幕却突然弹出 CUDA out of memory&#xff0c;那种挫败感&#xff0c;用过GLM-TTS的朋友一定不陌生。这不是模型不行&#xff0c;而是它太“认真…

作者头像 李华
网站建设 2026/4/16 9:07:37

零基础掌握screen命令在远程调试中的用法

以下是对您提供的博文《零基础掌握 screen 命令在远程调试中的用法:终端会话持久化核心技术解析》的 深度润色与重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位资深运维老手在技术分享会上娓娓道来; ✅ 打破模板…

作者头像 李华
网站建设 2026/4/16 9:06:42

Ubuntu20.04下Gazebo源码编译与ROS1集成实战指南

1. 环境准备与依赖管理 在Ubuntu 20.04上通过源码编译Gazebo前&#xff0c;需要彻底清理系统残留的二进制文件。我遇到过不少开发者因为旧版本冲突导致编译失败的情况&#xff0c;建议先执行以下命令彻底清除&#xff1a; sudo apt-get purge .*gazebo.* .*sdformat.* .*igni…

作者头像 李华