thunderstornX/meshtastic-security-audit
GitHub: thunderstornX/meshtastic-security-audit
针对 Meshtastic 数据包抓取的被动式安全审计工具包,通过解析 PCAP 文件检测默认信道密钥、节点枚举、未加密流量和 GPS 位置泄露等安全问题。
Stars: 0 | Forks: 0
```
┌──────────────────────────────────────────────────────────────┐
│ m e s h t a s t i c - s e c u r i t y - a u d i t │
│ │
│ passive PCAP audit · 4 detectors · HTML + JSON reports │
└──────────────────────────────────────────────────────────────┘
```
[](https://github.com/thunderstornX/meshtastic-security-audit/actions/workflows/tests.yml)
[](results/security_scan.md)
[](results/security_scan.md)
[](results/security_scan.md)
[](results/eval_summary.json)
[](https://doi.org/10.5281/zenodo.20480462)
[](LICENSE)
对 Meshtastic 数据包抓取的被动分析。该工具包读取
PCAP,解析 LoRa 链路层上的 Meshtastic 帧结构,
并报告四类发现:
- **默认 channel** — channel hash 匹配默认单字节 PSK index 下的七种官方记录的 Meshtastic modem preset 的帧。
- **Node 枚举** — 在抓包中观察到的不同源 node id 和目标 node id,以清单形式呈现并包含每个源的帧计数。
- **未加密流量** — encrypted-bit 未置位的帧,或其 payload 字节解码为纯文本 Meshtastic `Data`
protobuf 的帧。
- **GPS 泄漏** — 未加密 position payload 中可恢复的纬度/经度对。
报告以内联样式的 HTML 或标准 JSON 格式输出。
## 架构
```
┌─ pcap_parser.py ─┐
capture.pcap │ Scapy + custom │ list[MeshFrame]
────────────►│ header decode ├──────┐
└──────────────────┘ │
▼
┌───────────────────────────┐
│ detectors/ │
│ default_key.py │
│ node_enum.py │ list[Finding]
│ unencrypted.py ├──────┐
│ gps_leak.py │ │
└───────────────────────────┘ │
▼
┌────────────────────────┐
│ reporter.py │
│ to_html / to_json │
└─────────┬──────────────┘
│
▼
report.html / report.json
```
## 快速开始
```
git clone https://github.com/thunderstornX/meshtastic-security-audit.git
cd meshtastic-security-audit
python -m venv .venv
.venv/bin/pip install -r requirements.txt
# 针对 bundled synthetic capture 运行审计
.venv/bin/python cli.py \
--pcap samples/sample.pcap \
--output report.html
# 或者 emit JSON alongside HTML
.venv/bin/python cli.py \
--pcap samples/sample.pcap \
--output report \
--format both
```
CLI 接受以下参数:
| 标志 | 效果 |
|---|---|
| `--pcap PATH` | 输入的抓包文件(必填)。 |
| `--output PATH` | 报告写入位置。除非指定 `--format`,否则扩展名决定格式。 |
| `--format html\|json\|both` | 覆盖默认输出格式。 |
| `--detector NAME` | 限制为单个 detector。可重复使用。 |
| `--severity-threshold S` | 抑制严重程度低于 `S` 的发现 (info → critical)。 |
| `--print-summary` | 向 stderr 输出一行摘要(默认开启)。 |
## Detectors
### `default_key` — 严重程度 `high`
计算官方记录的所有 Meshtastic preset 名称(`LongFast`, `LongSlow`, `VeryLongSlow`,
`MediumSlow`, `MediumFast`, `ShortSlow`, `ShortFast`)在默认 1 字节 PSK index 为
`0x01` 时产生的 channel hash,并标记任何 channel 字节匹配的帧。
任何开箱即用且运行相同 preset 的 Meshtastic node 都可以解码带有这些 hash 的流量。
### `node_enum` — 严重程度 `info` + `medium`
统计不同的源 id(每个帧都会暴露一个)和单播目的地。
这两个摘要发现回答了“从这个观测点可以看到多少个 node”以及“它们之中有多少在直接互相通信”。
### `unencrypted` — 严重程度 `high` + `critical`
两个互补的信号:flags 字节中未置位的 encrypted bit (0x10)(high),以及 payload 前几个字节被解析为带有 field-1 标签和可打印内部字节的纯文本 `Data` protobuf(critical)。
第二个信号基于内容,即使在流量错误地设置了 encrypted flag 的情况下也能复现。
### `gps_leak` — 严重程度 `critical`
解码 port 3 (`POSITION_APP`) 上的任何 `Data` 封包,并提取
`latitude_i` 和 `longitude_i`(按 1e7 缩放的 int32)。
每个恢复的纬度/经度对都足以在地图上定位广播 node。
该 detector 不会尝试解密;加密的 position 帧不会产生发现。
## 评估
该工具包附带了位于 `tests/fixtures/test_packets.py` 中的合成、字节级标注语料库(5 个帧,涵盖所有四种 detector 信号)。
`eval/run_eval.py` 中的测试框架从 `eval/labelled_corpus.json` 读取真实标签并生成:
| Detector | TP | FP | FN | P | R | F₁ |
|----------------|---:|---:|---:|------:|------:|------:|
| `default_key` | 1 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| `node_enum` | 5 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| `unencrypted` | 2 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| `gps_leak` | 1 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| **汇总** | 9 | 0 | 0 | 1.000 | 1.000 | 1.000 |
使用 `.venv/bin/python eval/run_eval.py` 重新生成 — 会写入
`results/eval_summary.json` 和 `results/eval_raw.csv`。
之所以存在这个合成语料库,是因为目前没有同等规模的公开 Meshtastic
PCAP 数据集;其标签与 `tests/fixtures/test_packets.py` 中的帧构造器绑定。
对于真实的 mesh 网络审计,请自行抓取流量并对其运行相同的 CLI。
## 测试
```
.venv/bin/pytest -q
```
| 模块 | 测试数 |
|----------------------|------:|
| `test_pcap_parser.py` | 7 |
| `test_detectors.py` | 9 |
| `test_reporter.py` | 3 |
| `test_cli.py` | 4 |
| **总计** | **23** |
## 安全检查关卡
| 关卡 | 发现 |
|---|---|
| Bandit (medium+) | 0 |
| pip-audit | 0 |
| Semgrep (p/python, p/security-audit) | exit 0 |
运行输出位于 [`results/security_scan.md`](results/security_scan.md)。
## 抓取真实 Meshtastic 流量
该工具包可处理你的抓包流水线放入 PCAP 中的任何数据。
目前常用的两种途径:
- **SDR + LoRa 解码器。** 将 RTL-SDR 或 HackRF 调谐至区域 ISM 频段(433 / 868 / 915 MHz),并输入给 `gr-lora_sdr` 或
`LoRaWatcher`,将解码后的帧按每个数据包的原始字节进行序列化。
- **固件调试串行嗅探器。** `meshtastic` Python 客户端
通过 USB 串行接口暴露了帧级别的调试流;该流
可手动序列化为 PCAP 记录。
该工具包特意将抓包步骤留给操作员自行处理;
RF 抓包本身具有因司法管辖区而异的法律监管影响。
## 仓库布局
```
meshtastic-security-audit/
├── audit/
│ ├── pcap_parser.py # Scapy-backed frame parser
│ ├── reporter.py # HTML + JSON output
│ └── detectors/
│ ├── default_key.py
│ ├── node_enum.py
│ ├── unencrypted.py
│ └── gps_leak.py
├── cli.py # Click CLI
├── config.py # Preset constants + hash function
├── eval/
│ ├── labelled_corpus.json
│ └── run_eval.py
├── tests/
│ ├── test_pcap_parser.py
│ ├── test_detectors.py
│ ├── test_reporter.py
│ ├── test_cli.py
│ └── fixtures/test_packets.py
├── samples/
│ ├── README.md
│ └── sample.pcap # 5 synthetic frames
├── paper/ # 3-page IEEE writeup
├── results/ # eval + security scan outputs
└── ETHICAL_USE.md
```
## 许可证
MIT。请参阅 [LICENSE](LICENSE)。该工具包依赖于
[Meshtastic 项目](https://meshtastic.org) 提供协议定义,并依赖
[Scapy](https://scapy.net) 进行数据包操作;两者
均有其各自的许可证。
标签:LoRa, PCAP, Python, Scapy, 安全规则引擎, 无后门, 逆向工具, 防御绕过