第三章:信息收集与资产盘点:AI系统资产识别
好,咱们进入实操环节的第一步。说实话,很多安全工程师做AI系统审计,上来就拿着扫描器乱扫一通,结果扫了半天连人家用的是什么框架都没搞清楚。我个人习惯是,先花30%的时间做信息收集和资产盘点,后面70%的工作才能有的放矢。
3.1 资产识别:你到底在保护什么?
AI系统的资产,跟传统Web系统不太一样。传统Web你关心的是服务器、数据库、中间件。AI系统呢?核心资产是这三样:模型文件、训练数据、API接口。
核心资产三件套
- 模型文件:.h5、.pt、.onnx、.pb 等格式,这是AI的大脑
- 训练数据:标注数据集、原始语料、特征工程后的CSV
- API接口:推理接口、训练接口、管理接口
我在项目中遇到过一家做图像识别的公司,他们把模型文件直接放在NFS共享目录里,权限是777。我问他们为什么这么做,回答是「方便团队协作」。嗯,方便是方便了,但任何能访问内网的人都能把模型拖走。你想想看,一个训练了半年的模型,被人一键拷贝,这损失怎么算?
3.2 模型文件识别:从文件名到元数据
怎么快速识别一个目录下有没有模型文件?我一般用这个命令扫一遍:
find /data -type f \( -name "*.h5" -o -name "*.pt" -o -name "*.pth" -o -name "*.onnx" -o -name "*.pb" -o -name "*.ckpt" \) 2>/dev/null
但这只是第一步。真正的重点是看元数据。比如ONNX模型,你可以用工具读取它的输入输出张量信息:
import onnx
model = onnx.load("model.onnx")
print(model.graph.input)
print(model.graph.output)
为什么要看这个?因为有些模型文件里会残留调试信息,比如训练时的数据路径、预处理参数,甚至硬编码的API密钥。我曾经在一个.pb文件里找到了一段Base64编码的数据库连接字符串——嗯,开发者把它当注释写在了模型元数据里。
小技巧:检查模型文件时,别忘了看它的修改时间和文件大小。一个突然变大的模型文件,可能被人植入了后门。一个修改时间异常的文件,可能被替换过。
3.3 训练数据资产盘点:敏感信息重灾区
训练数据这块,说实话是AI系统里最容易出问题的。为什么?因为数据太杂了。文本、图片、音频、表格,什么格式都有。而且很多团队对数据的管控远不如对代码的管控严格。
我建议你重点关注这几个地方:
- 标注文件:JSON、XML、CSV格式的标注数据,里面可能包含原始文本
- 预处理脚本:数据清洗、特征提取的代码,经常暴露数据源路径
- 数据快照:训练过程中保存的中间数据,可能包含未脱敏的原始信息
举个例子,我审计过一个NLP项目,他们的训练数据里直接包含了用户的聊天记录,而且没有做脱敏处理。标注文件里甚至能看到用户的手机号。为什么会这样?因为标注团队为了方便,直接从生产数据库导出了原始数据。
警告:训练数据中的个人信息、商业机密、内部文档,是审计的重中之重。一旦泄露,后果比模型被盗更严重。因为数据泄露涉及合规问题,GDPR、个保法都在盯着你。
3.4 API接口探测:不止是RESTful
AI系统的API接口,跟传统API有个很大的区别:它往往有多种协议。除了常见的RESTful API,还有gRPC、WebSocket,甚至直接暴露TensorFlow Serving的端口。
我一般会这样探测:
- 扫描开放端口:nmap扫一遍,重点关注8500-8600(TF Serving默认端口)、8000-8100(PyTorch Serve)、5000-5005(Flask常见端口)
- 识别API框架:看响应头里的Server字段,或者错误页面里的框架信息
- 测试接口权限:直接访问 /v1/models、/api/health、/docs 这些常见路径
# 快速探测TF Serving
curl -s http://target:8501/v1/models | python -m json.tool
# 检查是否有Swagger文档
curl -s http://target:5000/swagger.json
我记得有一次,我只是访问了 /v1/models/default 这个路径,就拿到了完整的模型名称和版本号。更夸张的是,这个接口连基本的认证都没有。你想想看,攻击者知道了模型名称,就可以针对性地构造对抗样本了。
3.5 网络拓扑探测:画一张攻防地图
资产盘点不只是找文件,还要搞清楚网络拓扑。AI系统的典型拓扑是这样的:
| 层级 | 组件 | 常见端口 |
|---|---|---|
| 接入层 | API网关、负载均衡 | 80, 443, 8080 |
| 推理层 | 模型服务容器 | 8500-8600, 5000-5100 |
| 训练层 | 训练集群、GPU节点 | 22, 8888, 6006 |
| 存储层 | 对象存储、数据库 | 27017, 3306, 6379 |
我建议你用 traceroute 和 nmap 配合,先画出大致的网络分段。重点关注:
- 推理服务是否直接暴露在公网?
- 训练节点是否能访问生产数据库?
- 模型存储和API服务之间是否有网络隔离?
实战经验:很多AI系统的网络拓扑是「扁平化」的。训练节点和推理节点在同一个网段,甚至能互相SSH。这意味着,攻破一个GPU节点,就能横向移动到推理服务,然后窃取模型。
3.6 技术栈指纹识别:知己知彼
最后一步,识别技术栈。这决定了你后续用什么工具、什么方法去测试。我一般会收集这些信息:
- 深度学习框架:TensorFlow、PyTorch、MXNet、PaddlePaddle
- 模型服务框架:TF Serving、TorchServe、ONNX Runtime、Triton
- 数据处理工具:Spark、Flink、Pandas、NumPy
- 基础设施:Kubernetes、Docker、NVIDIA GPU驱动版本
怎么识别?看错误页面、看HTTP响应头、看API返回的元数据。比如TF Serving的响应里会有 tensorflow-serving 的标识。PyTorch Serve的默认错误页面会显示版本号。
# 识别TF Serving版本
curl -I http://target:8501/v1/models/default
# 响应示例
# HTTP/1.1 200 OK
# Content-Type: application/json
# Server: TensorFlow Serving
嗯,这里要注意。有些团队会修改默认的响应头来隐藏技术栈。但别担心,你还可以通过响应时间、错误信息格式、API路径命名风格来推断。比如gRPC接口的响应时间通常比RESTful短很多,这本身就是一个指纹。
避坑指南:我曾经遇到一个项目,对方把所有API都包装了一层,看起来像标准的RESTful接口。但我在测试时发现,传入非法的JSON格式数据,返回的错误信息里暴露了gRPC的内部错误码。嗯,这就暴露了底层用的是gRPC协议。
3.7 信息收集的产出物
做完以上工作,你应该能输出这样一份资产清单:
- 模型文件清单:路径、格式、大小、修改时间、元数据摘要
- 数据资产清单:数据源、存储位置、脱敏状态、访问权限
- API接口清单:端点、协议、认证方式、版本信息
- 网络拓扑图:分段、端口、服务依赖关系
- 技术栈清单:框架、版本、组件列表
这份清单,就是你后续渗透测试的「作战地图」。没有它,后面的所有工作都是盲人摸象。我个人习惯是把这些信息整理成一个Markdown文档,然后导入到Notion或者Confluence里,方便团队协作。
好了,信息收集和资产盘点就讲到这里。下一章咱们聊聊怎么对这些资产做具体的漏洞扫描和渗透测试。记住,信息收集做得越细,后面的工作就越轻松。别偷懒,这一步值得你花时间。