uleroboticsgroup/ciberlab-report-generator
GitHub: uleroboticsgroup/ciberlab-report-generator
一款用于自动化处理恶意软件动态分析输出并生成可读PDF报告的Python库。
Stars: 0 | Forks: 0
# Ciberlab-report-generator
[][cc-by-nc-sa]
## 描述
`ciberlab-report-generator` 是一个由 **Grupo de Robótica** 开发的 Python 库,用于自动化分析恶意软件样本(动态分析)并生成可供人类阅读的 PDF 格式报告。
它包含数据处理、页面生成、LLMs 集成(在需要时)以及使用 Sphinx 生成文档的支持。
## 主要特性
- 动态恶意软件分析输出处理(切片、规范化)。
- 自动生成 PDF 报告。
- 封装包结构,便于在其他项目中复用。
- 最佳实践:使用 Poetry 打包,使用 pytest 测试,Ruff + Black linter/formatter。
- 使用 Sphinx 生成的文档。
## 前置条件
- [Python](https://www.python.org/) >= 3.12
- [Poetry](https://python-poetry.org/) >= 2.0.0,用于管理环境和依赖。
## 配置(YAML + ENV)
该项目目前采用混合配置模型:
- YAML 文件用于非敏感配置(路径、模式、模型、限制)。
- 环境变量用于机密信息(`OPENAI_API_KEY`、`VT_API_KEY_X`)和运行时覆盖。
基础和配置文件:
- `config/base.yaml`
- `config/profiles/local.yaml`
- `config/profiles/cape.yaml`
- `config/profiles/batch_uploader.yaml`
标准环境变量模板:
```
cp config/.env.example .env
```
加载的环境文件优先级:
1. 如果设置了 `CIBERLABREPORT_ENV_FILE`,则加载该文件。
2. 否则,加载从当前工作目录找到的最近的 `.env` 文件。
3. 现有的 Shell 环境变量始终优先于文件中的值(`override=False`)。
最终配置优先级:
1. 基础 YAML(`CIBERLABREPORT_CONF_FILE`,默认为 `config/base.yaml`)
2. 配置 Profile YAML(`CIBERLABREPORT_PROFILE`,默认为 `local`)
3. 环境变量(来自 Shell 和/或加载的 env 文件)
加载器使用的环境变量:
| 必填 | 描述 |
| -------- | --------------------------------------- |
| 🟢 | 必填 |
| ⚪ | 可选 |
| 🔴 | 关键 |
| 变量 | 必填 | 默认值 | 描述 |
|--------------------------|-----------|---------------------|--------------|
| `OPENAI_API_KEY` | 🔴 | — | OpenAI API key(密钥)。 |
| `VT_API_KEY_1` | 🟢 | — | 第一个 VirusTotal API key(密钥)。 |
| `VT_API_KEY_X` | ⚪ | — | 额外的 VT keys(`VT_API_KEY_2`、`VT_API_KEY_3` 等)。 |
| `CIBERLABREPORT_CONF_FILE` | 🟢 | `config/base.yaml` | 基础 YAML 配置文件路径。 |
| `CIBERLABREPORT_PROFILE` | 🟢 | `local` | `config/profiles/` 下的配置 Profile 名称。 |
| `CIBERLABREPORT_ENV_FILE`| ⚪ | — | 在解析配置之前加载的可选环境文件。 |
| `MAX_VT_KEYS` | ⚪ | YAML `runtime.max_keys_list` | 顺序读取 `VT_API_KEY_X` 的最大数量。 |
| `INPUT_PATH_DEFAULT` | ⚪ | 从 YAML 获取 | 输入路径的运行时覆盖。 |
| `OUTPUT_PATH_DEFAULT` | ⚪ | 从 YAML 获取 | 输出路径的运行时覆盖。 |
| `CONFIG_PATH` | ⚪ | 从 YAML 获取 | 配置路径的运行时覆盖。 |
| `PROMPTS_PATH` | ⚪ | 从 YAML 获取 | Prompts 路径的运行时覆盖。 |
| `SCHEMAS_PATH` | ⚪ | 从 YAML 获取 | Schemas 路径的运行时覆盖。 |
| `TMP_PATH` | ⚪ | 从 YAML 获取 | 临时路径的运行时覆盖。 |
| `AI_MODEL` | ⚪ | 从 YAML 获取 | LLM 模型的运行时覆盖。 |
| `MODE` | ⚪ | 从 YAML 获取 | 执行模式(`PRO`、`DEV`)的运行时覆盖。 |
| `IMG_THRESHOLD` | ⚪ | 从 YAML 获取 | 图像阈值的运行时覆盖。 |
| `FAMILIES_SOURCE` | ⚪ | 从 YAML `families.source` 获取 | 恶意软件家族来源的覆盖(`json` 或 `db`)。 |
| `LOG_LEVEL` | ⚪ | `INFO` | 脚本使用的日志级别。 |
## 安装
```
git clone https://github.com/uleroboticsgroup/ciberlab-report-generator.git
cd ciberlab-report-generator
poetry install
```
## 使用方法
推荐的使用方法是先解析配置,然后构建 `ReportGenerator`:
```
from ciberlabreport.core import ReportGenerator
from ciberlabreport.settings import load_settings
s = load_settings()
rg = ReportGenerator(
openai_api_key=s.openai_api_key,
vt_api_keys=s.vt_api_keys,
max_files=s.max_files,
max_completion_tokens=s.max_completion_tokens,
input_path_default=s.input_path_default,
output_path_default=s.output_path_default,
config_path=s.config_path,
prompts_path=s.prompts_path,
schemas_path=s.schemas_path,
tmp_path=s.tmp_path,
ai_model=s.ai_model,
mode=s.mode,
img_threshold=s.img_threshold,
families_list=s.families_list,
)
rg.generate("input.json")
```
### `ReportGenerator` 参数
| 参数 | 类型 | 默认值 | 描述 |
|------------------|--------------------------------|--------------------|-------------|
| `openai_api_key` | `str` | *必填* | OpenAI API key。 |
| `vt_api_keys` | `list \| None` | `None` | VirusTotal API key 列表(例如 `["key1", "key2"]`)。 |
| `max_files` | `int` | `3` | 当 `input_data` 为目录时,要处理的最大输入 JSON 文件数量。如果设置为 `-1`,则处理目录中的所有文件(无限制)。 |
| `preprocess_limits` | `PreprocessLimits \| None` | `PreprocessLimits()` | CAPE 预处理的自定义限制(例如,在缩减报告中保留的最大签名、进程、行为数量)。如果为 `None`,则创建一个默认的 `PreprocessLimits()` 实例。 |
| `max_completion_tokens` | `int` | `25000` | 限制 LLM 在输出中生成或多或少的 token。仅在执行因 `finish_reason=length` 失败时使用。 |
| `input_path_default` | `str \| Path \| None` | `None` | 基础输入路径。如果省略,则使用当前工作目录。 |
| `output_path_default` | `str \| Path \| None` | `None` | 基础输出路径。如果省略,则使用当前工作目录。 |
| `config_path` | `str \| Path \| None` | `None` | 基础配置路径(JSON 配置)。如果省略,则使用当前工作目录。 |
| `prompts_path` | `str \| Path \| None` | `None` | Prompt 模板目录。默认为 `config_path/prompts`。 |
| `schemas_path` | `str \| Path \| None` | `None` | JSON schema 目录。默认为 `config_path/schemas`。 |
| `tmp_path` | `str \| Path \| None` | `None` | 临时文件目录。如果省略,则使用当前工作目录。 |
| `ai_model` | `str` | `gpt-5` | LLM 调用中使用的 AI 模型。 |
| `mode` | `str` | `PRO` | 执行模式(`PRO`、`DEV`)。 |
| `img_threshold` | `int` | `9` | 触发图像处理流程的最小图像数量。 |
| `families_list` | `list \| None` | `None` | 允许的恶意软件家族。如果设置,后处理阶段会将未知值强制设为 `Desconocida`。 |
### 按 Profile 划分的恶意软件家族
- `local` 和 `batch_uploader`:使用 `config/families.json`(通过 `families.source: json`)。
- `cape`:使用数据库 `SELECT DISTINCT`(通过 `families.source: db`)。
基础 YAML 支持这两种模式:
```
families:
source: json
json_file: families.json
db:
host_env: DB_HOST
port_env: DB_PORT
user_env: MARIADB_ROOT_USER
password_env: MARIADB_ROOT_PASSWORD
database_env: DATABASE
table: samples
column: family
where: "family IS NOT NULL AND family <> ''"
```
### `ReportGenerator.generate()` 参数
| 参数 | 类型 | 默认值 | 描述 |
|-------------|---------|---------|-------------|
| `input_data` | `str` | *必填* | 指向单个 JSON 文件或包含 JSON 文件的目录的路径。如果是目录,将收集所有 `*.json` 文件,并可选择性通过 `max_files` 进行数量限制。如果是文件的相对路径且不存在,生成器将尝试在 `INPUT_PATH_DEFAULT` 下解析它。 |
| `output_data` | `str \| None` | `None` | 输出路径。它可以是:(1) 绝对 `*.pdf` 路径,(2) 相对 `*.pdf` 文件名(保存在 `OUTPUT_PATH_DEFAULT` 下),(3) 目录(每个输入生成一个 PDF),或 `None`,在这种情况下,输出文件将按照 `-report.pdf` 的模式创建在 `OUTPUT_PATH_DEFAULT` 下。 |
您可以在 [main.py](/main.py) 中查看简单的用法。
有关更多代码详情,请查看[此处](/docs/README.md)。
## 开发和测试
要在本地运行 Linter、Formatter、测试并生成 Sphinx 文档,您必须使用 [ci-local.sh](/scripts/ci-local.sh):
```
chmod +x scripts/ci-local.sh
./scripts/ci-local.sh
```
### 后处理指南
创建此模块的目的是为了将 LLM 调用之后和传输给 `PDFGenerator` 之前的所有必要转换集中放在这里。
其功能依赖于配置项。这些条目存储在 [regex_config.json](/config/regex_config.json) 中。每个条目具有以下结构:
```
{
"description": "Description of the changes to apply",
"pattern": "Regex to complile and apply. Be careful to escape the necessary characters.",
"replace": "Regex or str to replace if the pattern matches"
},
```
## 结果
`ReportGenerator.generate` 方法现在将报告作为 `dict` 对象返回。此报告包含:
```
{
"input_files":
- ,
"output_files":
- ,
"time_spent":
-
}
```
| 字段 | 类型 | 描述 |
|---------------|------------------|--------------------------------------------------------------|
| `input_files` | `List[str]` | 输入文件的名称或路径列表。 |
| `output_files`| `List[str]` | 生成的输出文件的名称或路径列表。 |
| `time_spent` | `float` | 执行操作所花费的时间(以分钟为单位)。 |
| `money_spent` | `float` 或 `str` | 执行操作所花费的金钱(以美元 $ 计)。如果无法计算,则为字符串形式的解释说明。 |
| `out_files_data` | ``List[dict]` | 包含每个已处理输入的重要值的字典列表。 |
### `out_files_data` 的内容
```
[
{
"input":
- ,
"family":
标签:Ask搜索, Black, CAPE沙箱, DAST, LLM集成, OpenAI, PDF报告, Petitpotam, Poetry, Pytest, Ruff, Sphinx文档, VirusTotal, YAML配置, 代码示例, 内存规避, 威胁情报, 安全规则引擎, 开发者工具, 恶意软件分析, 恶意软件样本, 数据分析, 沙箱分析, 网络安全, 网络调试, 自动化, 自动化报告生成, 逆向工具, 隐私保护