CyberKareem/kameTrace
GitHub: CyberKareem/kameTrace
一款 DFIR 取证工具,用于解析和重组 PowerShell 脚本块日志并提取统计特征向量,以支持脚本溯源与机器生成检测研究。
Stars: 0 | Forks: 0
# kameTrace
**一款用于 DFIR 研究的 PowerShell Script Block Logging 取证分析工具。**
kameTrace 读取 Windows **PowerShell Operational** 事件日志 (`.evtx`),
重新组装碎片化的 **Script Block Logging** 记录,并提取适用于统计分析的
单脚本特征向量 —— 例如,用于研究机器生成的 PowerShell 是否留下了可衡量的
风格计量或结构痕迹,从而将其与人类编写的脚本区分开来。
这是**防御性/取证研究工具**。它仅*读取和测量*已捕获的事件日志和脚本文件;
它既不生成也不执行 PowerShell。
## 为什么该设计将解析与分析分离
二进制 `.evtx` 解析(需要 `python-evtx` + `lxml`)被刻意隔离在
单个模块中。下游的所有操作都基于 **XML 字符串**和**脚本字符串**运行,
因此具有取证价值的逻辑 —— 记录解析、
多部分重组和特征提取 —— 完全可以在
合成的 XML fixtures 上进行单元测试,**无需二进制日志和主机数据**。
```
kametrace/
evtx_reader.py binary .evtx ingest -> event-record XML strings (python-evtx)
records.py XML string -> structured EventRecord (stdlib only)
reassembly.py 4104 fragments -> complete ReassembledScript (stdlib only)
features.py complete script -> flat feature vector (stdlib only)
matrix.py rows -> labelled CSV / JSON matrix (stdlib only)
cli.py argparse entry point (`kametrace parse` / `kametrace ingest`)
```
### 相关事件 ID
| Event ID | 日志来源 | 含义 | kameTrace 用途 |
|----------|---------------------------|-------------------------------------------|---------------|
| **4104** | PowerShell/Operational | Script Block Logging(脚本文本) | 重组并提取特征 |
| **4103** | PowerShell/Operational | 模块日志(命令/模块上下文) | 解析命令上下文 |
大型脚本块会被 PowerShell 拆分为多个 4104 事件,每个
事件都带有 `MessageNumber` 和 `MessageTotal`,并共享一个通用的 `ScriptBlockId`。
kameTrace 按 `ScriptBlockId` 分组,并按 `MessageNumber` 顺序拼接
`ScriptBlockText` 片段,容忍乱序到达并记录
任何丢失的片段。
## 安装说明
```
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # python-evtx, lxml (for .evtx ingest)
pip install -e . # installs the `kametrace` console script
```
分析阶段(`records`、`reassembly`、`features`、`matrix`)是纯
标准库 —— `python-evtx` / `lxml` 仅用于读取二进制 `.evtx`
文件。
要求 Python **3.9+**。
## 用法
### 1. 分析 PowerShell Operational `.evtx`
```
kametrace parse Microsoft-Windows-PowerShell%4Operational.evtx -o features.csv
kametrace parse powershell.evtx -o features.csv --json features.json
kametrace parse powershell.evtx --label suspected-tooling -o features.csv
```
流程:读取 `.evtx` → 过滤 4104/4103 → 重组脚本块 →
提取特征 → 写入带标签的特征矩阵(CSV 和/或 JSON)。默认情况下会跳过
不完整(片段缺失)的脚本块;传递
`--include-incomplete` 参数无论如何都会对其进行特征提取(该行会记录
`is_complete` 和 `missing_parts`)。
### 2. 从包含 `.ps1` 脚本的目录构建带标签的数据集
```
kametrace ingest ./corpus/human --label human -o human.csv
kametrace ingest ./corpus/llm --label llm-generated -o llm.csv --json llm.json
```
该目录下(递归查找;使用 `--pattern` 覆盖)的每个 `.ps1` 文件都会
成为带有 `--label` 来源标记的一行 —— 这是用于组装学位论文带标签语料库的
确切工作流(例如 `human` 与 `llm-generated`)。
如果未指定 `-o` 或 `--json`,CSV 将被写入 stdout。
### 编程式使用
```
from kametrace.records import parse_record
from kametrace.reassembly import reassemble
from kametrace.features import extract_features
records = [parse_record(xml) for xml in event_xml_strings]
for script in reassemble(records):
if script.is_complete:
features = extract_features(script.text)
print(script.script_block_id, features["obfuscation_score"])
```
## 特征目录
`kametrace.features.extract_features(script)` 返回一个**扁平的**
`{feature_name: value}` 字典。每个矩阵行都是此向量加上一个
`source_id`(`ScriptBlockId` 或文件名)和一个可选的 `origin_label`。
### 词法特征
| Feature | Type | Description |
|---|---|---|
| `line_count` | int | 重组脚本中的行数。 |
| `char_count` | int | 总字符数。 |
| `comment_density` | float | (`#` 行注释 + `<# #>` 块)每行出现的频率。 |
| `comment_style_line` | 0/1 | 使用 `#` 单行注释。 |
| `comment_style_block` | 0/1 | 使用 `<# ... #>` 块注释。 |
| `comment_style_help_block` | 0/1 | 包含基于注释的帮助(`.SYNOPSIS`、`.DESCRIPTION` 等)。 |
| `variable_naming_convention` | str | 主流命名规范:`PascalCase` / `camelCase` / `snake_case` / `lowercase` / `UPPERCASE` / `mixed` / `none`。 |
| `variable_count` | int | 不同的用户变量引用(排除自动变量)。 |
| `variable_name_entropy` | float | 所有变量名字符的香农熵。 |
| `alias_count` | int | 检测到的 cmdlet 别名(`gci`、`ls`、`iex`、`%`、`?` 等)。 |
| `full_cmdlet_count` | int | 完整的 `Verb-Noun` cmdlet 调用。 |
| `alias_to_full_cmdlet_ratio` | float | `alias / (alias + full)` —— 0 = 全部为完整 cmdlet,~1 = 大量使用别名。 |
| `single_quote_count` / `double_quote_count` | int | 单引号/双引号字符串字面量。 |
| `quote_style_single_ratio` | float | 单引号字符串字面量的比例。 |
| `avg_indent_width` | float | 缩进行的平均前导空白宽度。 |
| `indent_uses_tabs` / `indent_uses_spaces` | 0/1 | 正在使用的缩进字符类别。 |
| `tab_indent_ratio` | float | 使用制表符缩进行的比例。 |
| `line_continuation_count` | int | 以反引号行延续符结尾的行。 |
### 结构特征
| Feature | Type | Description |
|---|---|---|
| `has_function_block` | 0/1 | 声明了 `function`。 |
| `has_param_block` | 0/1 | 声明了 `param( ... )` 块。 |
| `try_catch_count` | int | `try { ... }` 块的数量。 |
| `pipeline_max_depth` | int | 单个语句中 `|` 操作符的最大数量(启发式)。 |
| `here_string_count` | int | Here-strings(`@" ... "@` / `@' ... '@`)。 |
### 混淆指标
| Feature | Type | Description |
|---|---|---|
| `shannon_entropy` | float | 整个脚本在字符级别的香农熵。 |
| `has_encodedcommand` | 0/1 | `-EncodedCommand` / `-enc` / `FromBase64String` 标记。 |
| `base64_blob_count` | int | 看起来像 base64 的长数据块。 |
| `string_concat_density` | float | 每行 `+` 字符串构建操作符的数量。 |
| `format_operator_density` | float | 每行使用 `-f` 格式化操作符的次数。 |
| `char_code_density` | float | 每行通过 `[char]NN` / `[convert]` / 基于编码构建字符的次数。 |
| `obfuscation_score` | float | 上述指标的加权汇总(值越高 = 混淆越严重)。 |
## 测试
测试套件完全在**合成的** 4104/4103 事件 XML(Python
字符串构建器加上 `tests/fixtures/` 下的小型 fixtures)上运行。不需要
真实主机数据,也不需要二进制 `.evtx`。
```
pip install pytest
pytest
```
覆盖范围包括:记录字段提取和命名空间容忍度;
三部分重组(按顺序、乱序以及缺失片段的情况);以及
特征提取关键字的稳定性,还有核心研究信号 —— 一个大量使用别名 / base64 / 字符代码的脚本,在混淆
指标上的得分明显高于一个干净、带注释且具有函数结构的脚本。
## 取证与道德范围
kameTrace 适用于**授权的事件响应、数字取证和**
对您被允许分析的日志进行的学术研究**。事件日志通常
包含敏感的主机和用户数据 —— 请谨慎处理提取的矩阵,
并且不要提交真实的日志(参见 `.gitignore`)。
## 作者
**Abdullah Kareem** (CyberKareem) — [github.com/CyberKareem](https://github.com/CyberKareem)
## 许可证
MIT —— 参见 [LICENSE](LICENSE)。版权所有 (c) 2026 Abdullah Kareem (CyberKareem)。
标签:OpenCanary, Python, Windows PowerShell, 安全规则引擎, 数字取证, 无后门, 特征工程, 自动化脚本, 逆向工具