litemars/BeaconDetectionSystem
GitHub: litemars/BeaconDetectionSystem
基于 eBPF 的去中心化 C2 信标检测框架,通过统计分析连接时间间隔模式在网络边缘识别命令与控制流量。
Stars: 1 | Forks: 0
# eBPF Beacon 检测系统
一个网络信标检测器。数据平面使用 eBPF(入口使用 XDP,出口使用 TC clsact)以低开销捕获连接事件。控制平面在每个连接对的时间间隔上运行统计分析,并标记命令与控制 (C2) 流量。
大多数 C2 植入程序会定期与其控制端通信。攻击者会添加抖动、休眠周期和流量伪装,但如果仔细测量时间间隔,其潜在的规律性通常依然存在。这正是此工具所要测量的。
## 检测信号
每个连接对都会从四个信号中获得一个综合评分。权重配置在 `config.yaml` 中;默认值总和为 1.0。
- **变异系数 (35%)。** 间隔紧凑会产生较低的 CV。植入程序得分低,而突发性人类流量得分高。
- **FFT 周期性 (35%)。** 频域中的主峰是我们拥有的最强单一指标。
- **抖动 (15%)。** 相对中位数间隔的最大偏差。用于捕获仍然存在边界的随机化时间。
- **数据包大小 CV (15%)。** 植入程序倾向于发送几乎相同的 payload。浏览器则不会。
得分达到或超过 0.7 的连接对将生成警报。严重程度跟随分数:
| 得分 | 严重程度 | 通常代表的含义 |
|---------|-----------|---------------------------------------|
| ≥ 0.90 | CRITICAL | 高可信度信标,立即调查 |
| ≥ 0.80 | HIGH | 可能是信标 |
| ≥ 0.70 | MEDIUM | 可疑,值得关注 |
| < 0.70 | LOW | 可能是噪音 |
## 架构
```
┌─────────────────────────────────────────────────────────────────┐
│ Control Plane │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Storage │ │ Detector │ │ Analyzer │ │ Alert Manager │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │
│ │ │
│ HTTP API (:9090) │
└─────────────────────────────────────────────────────────────────┘
▲
│ Telemetry
┌─────────────────────────────────────────────────────────────────┐
│ Data Plane │
│ ┌──────────────┐ ┌──────────────┐ ┌─────────────────────────┐│
│ │ eBPF Program │──│ Collector │──│ Telemetry Exporter ││
│ └──────────────┘ └──────────────┘ └─────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
```
数据平面驻留在内核中并发出连接事件。控制平面是一个普通的 HTTP 服务,负责对它们进行评分并路由警报。它们通过 `/api/v1/telemetry` 进行通信,因此您可以将它们运行在一台主机上,也可以分别部署在两台主机上。
## 快速开始
```
pip install -r requirements.txt
```
运行控制平面(无需 root 权限):
```
python3 -m control_plane.server -c config/config.yaml
```
运行数据平面(eBPF 需要 root 权限):
```
sudo python3 -m data_plane.collector -c ./config/config.yaml
```
然后通过 CLI 驱动所有操作:
```
python3 -m control_plane.cli status # health, uptime, counters
python3 -m control_plane.cli beacons # what has been flagged
python3 -m control_plane.cli beacons --min-score 0.8
python3 -m control_plane.cli long-conns # connections older than 1h
python3 -m control_plane.cli watch # live view
python3 -m control_plane.cli beacons --csv > beacons.csv
```
## CLI 参考
### `status`
服务器健康状况、运行时间以及正在运行的事件计数器。
```
____ ____ __ __
/ __ )___ ____ __________ ____ / __ \___ / /____ _____/ /_
/ __ / _ \/ __ `/ ___/ __ \/ __ \ / / / / _ \/ __/ _ \/ ___/ __/
/ /_/ / __/ /_/ / /__/ /_/ / / / // /_/ / __/ /_/ __/ /__/ /_
/_____/\___/\__,_/\___/\____/_/ /_//_____/\___/\__/\___/\___/\__/
═══════════════════════════════════════════════════════════════════
SYSTEM STATUS
═══════════════════════════════════════════════════════════════════
✓ LIVE
Server: localhost:9090
Status: Running
Uptime: 2.5h
Events Received: 15,432
Connection Pairs: 234
Beacons Detected: 3
Alerts Generated: 5
```
### `beacons`
检测到的信标,按分数排序。
```
python3 -m control_plane.cli beacons [options]
```
选项:
- `--min-score FLOAT`:最低信标分数(0.0 到 1.0)
- `--limit INT`:限制结果数量
- `--csv, -o`:输出 CSV 而不是表格视图
示例输出:
```
SCORE SEVERITY SOURCE IP DEST IP PORT PROTO CONNS INTERVAL
----- -------- --------- ------- ---- ----- ----- --------
94.2% CRITICAL 10.0.0.100 203.0.113.50 443 TCP 156 60.0s
85.3% HIGH 10.0.0.101 198.51.100.25 8080 TCP 89 30.0s
72.1% MEDIUM 10.0.0.102 192.0.2.100 53 UDP 45 300.0s
```
### `long-conns`
可能表明存在持久性 C2 的长连接。
```
python3 -m control_plane.cli long-conns [options]
```
选项:
- `--min-duration INT`:最短持续时间(以秒为单位,默认为 3600)
- `--limit INT`:限制结果数量
- `--csv, -o`:输出 CSV
### `connections`
所有受跟踪的连接对。
```
python3 -m control_plane.cli connections [options]
```
选项:
- `--limit INT`:限制结果数量
- `--csv, -o`:输出 CSV
### `watch`
带自动刷新的实时监控。
```
python3 -m control_plane.cli watch [options]
```
选项:
- `--interval INT`:刷新间隔(以秒为单位,默认为 5)
`Ctrl+C` 退出。
## 与远程控制平面通信
```
python3 -m control_plane.cli --host 192.168.1.100 --port 9090 status
python3 -m control_plane.cli --host 192.168.1.100 beacons
python3 -m control_plane.cli --host 192.168.1.100 watch
```
## 配置
默认配置位于 `config/config.yaml`。主要调整项:
```
control_plane:
listen_address: "0.0.0.0"
listen_port: 9090
detection:
min_connections: 10 # events required before scoring kicks in
cv_threshold: 0.15 # tighter than this looks beacon-like
alert_threshold: 0.7 # combined score that fires alerts
jitter_threshold: 5.0 # seconds; max acceptable deviation from median
analysis_interval: 60 # how often we re-score, in seconds
alerting:
syslog_enabled: true
file_enabled: true
file_path: "/var/log/beacon-detect/alerts.json"
webhook_enabled: false
webhook_url: ""
whitelist:
source_ips: []
destination_ips: []
destination_ports: [53, 123] # DNS, NTP
```
YAML 文件本身包含更多选项,并有注释解释其利弊权衡。
## API 端点
| 端点 | 方法 | 描述 |
|----------|--------|-------------|
| `/api/v1/health` | GET | 健康检查,包括警报队列背压 |
| `/api/v1/status` | GET | 带有丢弃计数器的服务器状态 |
| `/api/v1/metrics` | GET | Prometheus 文本指标 (v0.0.4) |
| `/api/v1/beacons` | GET | 检测到的信标 |
| `/api/v1/alerts` | GET | 警报 |
| `/api/v1/connections` | GET | 连接对 |
| `/api/v1/config` | GET/POST | 读取或更新配置 |
| `/api/v1/telemetry` | POST | 接收来自数据平面的遥测数据 |
| `/api/v1/analyze` | POST | 强制运行一次分析 |
### Prometheus 指标
`GET /api/v1/metrics` 返回 Prometheus 文本展示格式(Content-Type: `text/plain; version=0.0.4`),包含以下计数器和仪表盘:
| 指标 | 类型 | 描述 |
|--------|------|-------------|
| `beacon_detector_events_total` | counter | 从所有数据平面节点接收到的连接事件 |
| `beacon_detector_pairs_active` | gauge | 当前存储中的连接对 |
| `beacon_detector_analysis_duration_seconds` | gauge | 上次分析运行的实际耗时 |
| `beacon_detector_alerts_total` | counter | 自启动以来生成的信标警报 |
| `beacon_detector_buffer_overflow_total` | counter | 被数据平面缓冲区丢弃的事件 |
| `beacon_detector_ebpf_drops_total` | counter | 被 eBPF 环形缓冲区丢弃的事件 |
```
curl http://localhost:9090/api/v1/metrics
# HELP beacon_detector_events_total 从所有 data plane 节点接收到的总连接事件。
# TYPE beacon_detector_events_total counter
beacon_detector_events_total 15432
...
```
### 警报队列背压
健康端点会报告队列饱和度,以便 sidecar 或编排器可以在事件被静默丢弃之前进行负载削减:
```
{
"status": "healthy",
"alert_queue_fill_percent": 43.0,
"alert_queue_backpressure": false,
"alert_queue_drops": 0
}
```
一旦队列通过 80% 的容量,`alert_queue_backpressure` 就会翻转为 `true`。来自警报队列和数据平面的丢弃计数器都会被镜像到 `/api/v1/status`。
## Docker
### 控制平面
控制平面是纯 Python 的,运行在普通容器中。
```
docker compose up control-plane
# 当此返回 200 时为健康:
curl http://localhost:9090/api/v1/health
```
`docker-compose.yml` 还定义了一个 `data-plane-sim` 服务,它会发送合成的 60 秒信标流量。这足以在没有 eBPF 或 root 权限的情况下端到端地测试整个 pipeline。在生产环境中请将其注释掉。
### 数据平面
真正的数据平面不会在普通容器内运行。eBPF 和 XDP 附加到内核网络接口上,这意味着:
| 需求 | 原因 |
|-------------|-----|
| `--network=host` | XDP 和 TC 钩子位于主机网络命名空间中 |
| `--privileged` | 加载 XDP/TC 程序需要 `CAP_BPF` 和 `CAP_NET_ADMIN` 权限 |
| Linux ≥ 5.8 | 用于 `BPF_RINGBUF` |
| Kernel headers | BCC 在加载时编译 C 程序 |
直接在主机上运行,或者使用特权容器:
```
sudo docker run --rm \
--privileged \
--network=host \
--pid=host \
-v /lib/modules:/lib/modules:ro \
-v /usr/src:/usr/src:ro \
-v /sys/kernel/debug:/sys/kernel/debug \
-v ./config:/app/config:ro \
beacon-detect-data-plane \
python3 -m data_plane.collector -c /app/config/config.yaml -i eth0
```
## eBPF 钩子附加
收集器按优先顺序尝试各种钩子,以便它能监控双向流量。
### 首选:XDP 入口 + TC 出口
```
NIC RX -> xdp_connection_tracker (direction = INGRESS = 0)
NIC TX -> tc_egress_tracker (direction = EGRESS = 1)
```
XDP 在内核网络栈之前运行,这为入口流量提供了尽可能低的延迟。出口流量则通过 TC clsact qdisc 处理。
### 备用:TC 入口 + TC 出口
如果 NIC 驱动程序不支持原生 XDP(常见于 `virtio`、`vmxnet3` 和其他虚拟 NIC),收集器将回退到两侧都使用 TC:
```
TC ingress -> tc_ingress_tracker (direction = INGRESS = 0)
TC egress -> tc_egress_tracker (direction = EGRESS = 1)
```
### 钩子摘要
| 钩子 | 方向 | BPF 函数 | 附加时机 |
|------|-----------|--------------|------------------|
| XDP (原生) | ingress | `xdp_connection_tracker` | 默认,当 NIC 具有 XDP 驱动程序时 |
| TC clsact egress | egress | `tc_egress_tracker` | 始终(与 XDP 或 TC 入口配对使用) |
| TC clsact ingress | ingress | `tc_ingress_tracker` | 在 XDP 不可用时的备用方案 |
活动模式会在启动时记录下来,因此您无需猜测:
```
INFO Attached XDP ingress hook on eth0
INFO Attached TC egress hook on eth0 (clsact)
INFO eBPF attachment mode: xdp+tc_egress
```
## 部署
### 所需包
Ubuntu/Debian:
```
sudo apt-get update
sudo apt-get install -y \
python3 \
python3-pip \
python3-venv \
bpfcc-tools \
linux-headers-$(uname -r) \
libbpf-dev
```
### 生产配置
将您的配置放在 `/etc/beacon-detect/config.yaml` 中:
```
data_plane:
interface: "eth0"
export_interval: 60
control_plane_host: "127.0.0.1"
control_plane_port: 9090
control_plane:
listen_address: "127.0.0.1"
listen_port: 9090
detection:
min_connections: 10
cv_threshold: 0.15
alert_threshold: 0.7
```
### 运行
终端 1,控制平面:
```
sudo ./venv/bin/python -m control_plane.server \
--config /etc/beacon-detect/config.yaml
```
终端 2,数据平面:
```
sudo ./venv/bin/python -m data_plane.collector \
--config /etc/beacon-detect/config.yaml
```
### 高流量调优
如果导出正在丢弃事件或内存不断攀升,值得调整的选项有:
```
data_plane:
export_interval: 120 # less chatter
max_buffer_size: 500000 # larger telemetry buffer
ring_buffer_pages: 128 # larger eBPF ring buffer
control_plane:
data_retention: 3600 # keep less history
cleanup_interval: 120 # cull more often
```
### 将周期性服务加入白名单
在真实网络中,误报的最大来源是合法的周期性流量。对您信任的流量进行抑制:
```
whitelist:
destination_ips:
- "8.8.8.8"
- "8.8.4.4"
- "1.1.1.1"
ports:
- 53
- 123
- 67
- 68
pairs:
- "10.0.0.5:169.254.169.254:80"
```
基于 UDP/53 的 DNS 有意不在默认设置中。它是一种常见的 C2 通道,因此只有在您有其他 DNS 可见性时才添加它。
## 测试
```
pytest tests/
```
## 许可证
MIT。
标签:0.7阈值, AMSI绕过, C2通信检测, Docker镜像, FFT, IP 地址批量处理, SIEM集成, TC clsact, XDP, 代理服务器, 信标检测, 变异系数, 告警系统, 周期性分析, 命令与控制, 威胁检测, 异常流量检测, 快速傅里叶变换, 恶意软件通信, 抖动分析, 控制平面, 数据平面, 网络安全, 网络安全监控, 网络流量分析, 自定义请求头, 请求拦截, 边缘路由器, 逆向工具, 隐私保护, 驱动开发