dilates/beaconwatch
GitHub: dilates/beaconwatch
beaconwatch 通过对 Linux 出站连接的统计时间分析,被动检测恶意软件与 C2 服务器之间的规律性信标通信。
Stars: 0 | Forks: 0
# beaconwatch
Linux 的被动式 C2 beaconing 检测器。按进程监控出站网络连接,并使用统计分析来检测命令与控制 (command-and-control) 的 beaconing 模式 —— 即以可疑的规律性间隔连接到同一目标地址的进程。
**作者:** https://github.com/dilates
## 工作原理
真实的 C2 恶意软件会定期与其命令服务器“签到” —— 每 60 秒、每 5 分钟或每小时 —— 有时还会加入微小的抖动以避开简单的检测。这种规律性是一种统计指纹,与正常的应用程序流量(通常具有突发性、由用户驱动且无规律)截然不同。
beaconwatch:
1. **被动观察** 来自内核 conntrack 子系统的出站连接事件(无数据包检查,除了元数据外不进行流量拦截)
2. **按 `(进程, 目标)` 将连接分组** 为流量 (flow)
3. **对每个流量的连接间隔时间分布应用统计测试**:
- **变异系数 (CV)** = 标准差 / 平均值 —— 主要信号;C2 beacon 的 CV 通常小于 0.15(即使存在抖动),而人类/应用程序流量的 CV 通常大于 0.5
- **滞后 1–5 的自相关性 (Autocorrelation)** —— 即使在嘈杂的信号中也能检测周期性
- **基于 FFT 的周期估计** —— 适用于运行时间较长且有足够样本的流量
- **绝对中位差 (MAD)** —— 对笔记本电脑休眠等一次性异常情况具有鲁棒性
4. **为每个流量评分** 0–100,将其分类为 `benign / suspicious / likely_beacon / high_confidence_beacon`
5. 当流量风险升级时,通过桌面通知或 webhook **发出警报**
该工具**不会**解密或检查数据包内容 —— 它仅使用连接元数据(时间戳、源进程、目标 IP:port、协议、来自 conntrack 的字节数)。这使得它:
- 轻量级(不使用 BPF/eBPF,除了 conntrack 外不使用原始 socket)
- 在任何地方运行都是合法的(无拦截)
- **即使针对完全加密的 C2 也很有效** —— 加密隐藏了 payload,但无法隐藏时间规律
## 环境要求
- Linux(支持 conntrack netlink)
- Python 3.11+
- Root 权限或 `CAP_NET_ADMIN`(用于接收 conntrack 事件)
- 以下两者之一:
- `pyroute2`(首选,直接使用 netlink) —— `pip install pyroute2`
- `conntrack-tools`(备选子进程方式) —— `apt install conntrack-tools`
### 安装
```
pip install beaconwatch
# 或从源码:
git clone https://github.com/dilates/beaconwatch
cd beaconwatch
pip install -e .
```
## 快速开始
```
# 启动 daemon(需要 root)
sudo beaconwatch daemon --foreground
# 在另一个终端:打开 TUI
beaconwatch tui
# 或者仅列出可疑流
beaconwatch list
# 显示特定流的详细信息
beaconwatch show
# 检查总体状态
beaconwatch status
```
## 作为 systemd 服务运行
将单元文件从 `install/beaconwatch.service` 复制到 `/etc/systemd/system/`:
```
sudo cp install/beaconwatch.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now beaconwatch
sudo journalctl -u beaconwatch -f
```
使用 `CAP_NET_ADMIN` 以非 root 用户身份运行:
```
sudo useradd -r -s /bin/false beaconwatch
sudo mkdir -p /var/lib/beaconwatch
sudo chown beaconwatch: /var/lib/beaconwatch
sudo setcap cap_net_admin+ep $(which beaconwatch)
# 编辑 /etc/systemd/system/beaconwatch.service:设置 User=beaconwatch,AmbientCapabilities=CAP_NET_ADMIN
```
## CLI 参考
```
beaconwatch [OPTIONS] COMMAND
Commands:
daemon [--foreground] Run the capture daemon
tui Launch interactive TUI
list [--min-classification LEVEL] [--limit N]
show FLOW_ID Detailed flow view with interval histogram
allowlist list / add / remove / suggest
alerts [--unacknowledged]
ack ALERT_ID
status
--version
```
### 允许列表管理
常见的误报(NTP、包管理器、浏览器遥测)可以加入允许列表。使用 `suggest` 来寻找候选项:
```
beaconwatch allowlist suggest
beaconwatch allowlist add --process /usr/lib/systemd/systemd-timesyncd --dst-port 123 --reason "NTP time sync"
beaconwatch allowlist list
beaconwatch allowlist remove
```
## TUI
TUI 每隔 3 秒读取一次 SQLite 数据库(daemon 以 WAL 模式写入 —— 并发访问是安全的):
```
┌─ beaconwatch ─────────────────────────────────────────────────────────┐
│ ● running Flows: 47 Connections (24h): 12,403 │
├───────────────────────────────────────────────────────────────────────┤
│ Score Classification Process Destination Interval │
│ ─────────────────────────────────────────────────────────────────── │
│ 87 HIGH CONFIDENCE agent.sh 203.0.113.42:443 60.0s±0s│
│ 52 LIKELY BEACON suspicious.bin 198.51.100.7:8080 300s±8s │
│ 18 SUSPICIOUS curl 142.250.x.x:443 irregular│
│ 5 benign systemd-timesync pool.ntp.org:123 3600s │
├───────────────────────────────────────────────────────────────────────┤
│ [Enter] details [A]llowlist [R]efresh [Q]uit │
└───────────────────────────────────────────────────────────────────────┘
```
快捷键:`Enter` = 详情弹窗,`A` = 快速加入允许列表,`R` = 刷新,`Q` = 退出。
## 架构
```
Kernel conntrack → ConntrackMonitor → BeaconwatchDaemon → FlowTracker
→ IntervalStats (CV, autocorr, FFT)
→ score_flow (0–100)
→ SQLite (WAL)
→ Alerts (desktop / webhook)
TUI / CLI ──────────────────────────────────────────→ SQLite (read-only)
```
daemon 和 TUI 完全通过 SQLite 数据库文件进行通信。WAL (Write-Ahead Logging) 模式允许 daemon 在 TUI 并发读取的同时进行写入 —— 无需 IPC、无需 socket、无需共享内存。
**Conntrack 后端**(自动选择):
1. **pyroute2/netlink**(首选):直接的内核 netlink socket,延迟最低
2. **conntrack 子进程**(备选):启动 `conntrack -E`,解析文本输出
## 评分算法
| 因素 | 分数 | 条件 |
|--------|--------|-----------|
| CV < 0.05 | +50 | 接近完美的周期性 |
| CV < 0.15 | +35 | 高度规律(带抖动) |
| CV < 0.30 | +15 | 中等规律 |
| Autocorrelation > 0.7 | +15 | 强烈的周期性信号 |
| 间隔 30s–1h | +10 | 经典的 C2 睡眠区间 |
| 间隔 < 5s | +10 | 激进的 keepalive/beacon |
| 常见 C2 端口 (443/80/8080) | +5 | 混入正常流量中 |
| 异常端口 | +10 | 公网 IP 上的非标准端口 |
| 可疑路径 (/tmp, /dev/shm, dotfiles) | +20 | 恶意软件经常从此处运行 |
| 未知进程 | +10 | 无法识别该可执行文件 |
| 在允许列表中 | -30 | 用户批准的已知良性进程 |
| 样本数 < 5 | ×0.3 | 数据不足 |
| 样本数 5–15 | ×0.7 | 中等置信度 |
| 样本数 ≥ 16 | ×1.0 | 完全置信度 |
**分类:**
- `benign` (< 20):正常流量
- `suspicious` (20–44):值得关注
- `likely_beacon` (45–69):极有可能是 C2 beaconing
- `high_confidence_beacon` (≥ 70):存在 C2 的有力统计证据
## 误报
常见会定期发送 beacon 的良性进程:
| 进程 | 行为 | 为何属于良性 |
|---------|----------|-----------------|
| `systemd-timesyncd`, `chronyd` | 每 ~1024 秒同步一次 NTP | 时间同步 |
| `packagekitd`, `snapd`, `flatpak` | 定期检查更新 | 包管理 |
| `NetworkManager` | 连接检查 | 网络探测 |
| 浏览器同步 | 后台遥测 | 厂商遥测 |
| VPN 客户端 | keepalive 数据包 | 维持连接 |
使用 `beaconwatch allowlist suggest` 在您的环境中发现这些进程,并将它们添加到允许列表中。
## 局限性
- **无法查看数据包内容**:该工具仅使用时间元数据。它无法检查 payload。
- **可通过随机化规避**:使用完全随机(高 CV)睡眠间隔的恶意软件可以避开基于时间的检测 —— 但这也会降低恶意软件对攻击者的可靠性(随机化会破坏命令送达的保证)。在实践中,大多数 C2 框架为了保证可靠性,会使用有界限的抖动(±10–20%),这能被 beaconwatch 检测到。
- **依赖 conntrack**:该工具依赖内核的连接跟踪。如果 conntrack 被禁用或目标使用原始 socket,可能会漏掉事件。
- **进程解析是尽力而为的**:用于 PID→进程映射的 `/proc` 遍历本质上存在竞态(进程可能会在连接事件和解析之间退出)。解析失败的项仍会被记录在 "unknown" 下。
- **IPv6**:通过 /proc/net/tcp6 和 /proc/net/udp6 支持。
- **UDP**:会被跟踪,但 conntrack 的 UDP 跟踪是无状态的 —— “关闭”事件可能不会被触发。连接计数仍会累积。
## 开发
```
pip install -e ".[dev]"
pytest tests/ -v
```
测试涵盖:完美的 beacon、带抖动的 beacon、泊松(随机)流量、边缘情况(0/1/2 个样本、异常值)、评分阈值,以及针对 `tests/fixtures/sample_connections.json` 的完整 pipeline 测试。
标签:IP 地址批量处理, 网络流量分析, 逆向工具