boredchilada/AL4-pdfstudio
GitHub: boredchilada/AL4-pdfstudio
Assemblyline v4 的 PDF 静态结构分析服务,封装 pdfstudio 解析器,通过启发式规则、Catalog 路径遍历和嵌入式 payload 提取对 PDF 样本进行自动化结构检测与评分。
Stars: 0 | Forks: 0
# Assemblyline 服务:PdfStudio
针对 Assemblyline v4 的 PDF 文件静态结构分析,封装了
[pdfstudio](https://github.com/boredchilada/pdfstudio) —— 一个只读且仅依赖标准库的
PDF 分析器(“PEstudio 风格”的结构浏览)。
## 功能说明
对于每个 `document/pdf` 提交,该服务会运行 `pdfstudio --json` 并将
报告转换为 Assemblyline 结果:
- **检测标志**(30 多条结构规则)按严重程度分组,并通过
启发式算法进行评分 —— 嵌入的可执行文件(`EMBEDDED_PE`/`ELF`/`ZIP`)、启动/命令
操作(`LAUNCH_CMD`)、自动执行的 JavaScript(`OPENACTION_JS`)、高熵
数据流、对象流/xref 异常、加密等。
- **Catalog 触发路径** —— catalog 图遍历的自动触发链
(例如 `/OpenAction` → 活动内容)。
- **逐版本武器化** —— 添加/重写对象的增量更新。
- **解析异常** —— 格式错误/规避性结构警告。
- **明文 IOC** —— 从原始字节中提取 URL/domain/IP 并打上标签
(`network.static.uri|domain|ip`),常见的 XMP/metadata 命名空间会被加入白名单。
- **嵌入式 payload 提取** —— 对解码后的对象流进行 PE/ELF/ZIP/RAR/7z/OLE/PDF 特征嗅探,并通过 `add_extracted()` 将其切分出来,以便
服务集群的其余部分对它们进行递归重新扫描(嵌入的 PDF 会重新进入
此服务,嵌入的 PE 会发送到您的 PE/AV 服务等)。通过
MD5 进行去重,并受 `max_extracted_payloads` 限制。
- 完整的 JSON 报告将作为补充文件附加。
## 机器可读输出 / ontology
此服务将发现结果导出为 **标签**(`network.static.*`)以及带有
`signature_score_map` + MITRE `attack_id` 的 **启发式规则** —— 这是
*静态* 分析器正确的机器可读层(这些结果将输入到 AL 的关联引擎和 SIEM 导出中)。它故意
**不输出 Result Ontology** 部分:AL ontology 模型描述的是动态/观察到的
行为(`NetworkConnection`、`Sandbox`、`Process`、`Antivirus`)或签名引擎
命中(`Signature.type` 仅限于
`SURICATA|SIGMA|YARA|CUCKOO`),这些都不适合
pdfstudio 的结构启发式规则。最接近的 CCCS PDF 服务(`pdfid`、`peepdf`)
出于同样的原因省略了 ontology。只有在将 YARA 扫描(`pdfstudio --yara`)接入 AL 的签名更新程序时,`Signature` ontology 部分才会变得
适用。
## 网络策略
该服务被**设计为离线模式**:`allow_internet_access: false` 且永远不会调用 pdfstudio 的
网络丰富化模式(`--hunt`、`--hunt-vt`、`--hunt-mb`)。IOC
提取仅限于文件中的明文;隐藏在压缩流中的
URI 无法被恢复。
## 启发式规则
| ID | 名称 | 分数 | 备注 |
|----|------|-------|-------|
| 1 | 高严重性 PDF 指标 | 1000 | 每个规则代码对应 `signature_score_map`;ATT&CK T1204 |
| 2 | 中等严重性 PDF 指标 | 500 | |
| 3 | 低严重性 PDF 指标 | 100 | |
| 4 | 信息性 PDF 观察 | 0 | |
| 5 | Catalog 触发路径 | 500 | ATT&CK T1204 |
| 6 | 多版本武器化 | 750 | ATT&CK T1027 |
| 7 | PDF 解析异常 | 100 | |
## 提交参数
- `show_object_table`(布尔值,默认为 `false`)—— 包含完整的 PDF 对象表。
在深度扫描提交时也会自动启用。
## 配置 (`self.config`)
- `internal_timeout`(默认为 `110`)—— 子进程超时时间;请保持在 `timeout` 以下。
- `max_iocs`(默认为 `200`)—— 每种类型最多标记的 IOC 数量。
- `max_extracted_payloads`(默认为 `30`)—— 每个文件最多切分的嵌入式 payload 数量。
## 版本控制
版本在 `service_manifest.yml` 中的两处被**硬编码**,这两处必须始终
保持一致:顶层的 `version:` 和 `docker_config.image:` 标签。发布时请同时
更新这两处。(这与上游 CCCS 的 `$SERVICE_TAG` 补丁方式不同,以适应
内部的 CI 和 AL 4.7 Rust `service_server`,后者还要求 `attack_id` 必须是
YAML 列表。)
## 构建与发布
推送到 `main` 分支会触发 `.github/workflows/docker-publish.yml`,该工作流会读取
清单中的 `version:`,并推送
`ghcr.io/boredchilada/al4-pdfstudio:` 以及
`:latest`。(GHCR 会将仓库名称转为小写,因此 `AL4-pdfstudio` → `al4-pdfstudio`。)
本地构建:
```
docker build -t ghcr.io/boredchilada/al4-pdfstudio:4.7.0.1 .
# 可选的 upstream tool 可复现 pin:
# docker build --build-arg PDFSTUDIO_REF= -t ghcr.io/boredchilada/al4-pdfstudio:4.7.0.1 .
```
然后在 Assemblyline 中注册该服务(UI → Administration → Services → Add,粘贴
清单),并指向推送的镜像标签。
## 测试
```
pip install -r tests/requirements.txt
# 单元测试(仅 helpers,不需要 samples):
pytest tests/test_pdfstudio_unit.py
# Sample 回归:将 PDF 添加到 tests/samples/,使用
# assemblyline-service-utilities TestHelper 生成 golden 结果,提交 tests/results/,然后:
pytest tests/test_pdfstudio_samples.py
```
## 目录结构
```
pdfstudio/
├── Dockerfile
├── service_manifest.yml
├── requirements.txt
├── pkglist.txt
├── pyproject.toml
├── README.md
├── LICENSE
├── pdfstudio_/
│ ├── __init__.py
│ └── pdfstudio_.py # class PdfStudio(ServiceBase)
└── tests/
├── __init__.py
├── requirements.txt
├── test_pdfstudio_unit.py
├── test_pdfstudio_samples.py
└── results/
```
标签:Assemblyline, DAST, DNS 反向解析, Go语言工具, PDF分析, 威胁情报, 安全, 开发者工具, 恶意软件分析, 搜索语句(dork), 文件分析, 请求拦截, 超时处理, 逆向工具