copyleftdev/floq

GitHub: copyleftdev/floq

一款基于量子混沌谱统计理论的轻量级 C2 beacon 检测器,通过能级间距比率等指标从嘈杂网络流量中精准识别周期性命令控制通信。

Stars: 0 | Forks: 0

# floq 一个 C2 beacon 检测器,借鉴了量子混沌物理学家用来区分结构化信号与噪声的谱统计学方法,并将其应用于网络流时序。 **276KB 静态二进制文件。读取 pcap、实时捕获或 OpenTelemetry JSONL。在混沌中寻找线索。** ## 为什么会有这个项目 大多数 beacon 检测工具只使用一种信号:连接间隔的标准差和变异系数。RITA、Flare、BeaconHunter —— 它们都在计算 `stddev / mean` 并据此设定阈值。这对于具有低抖动的教科书式 beacon 有效,但真实的 C2 流量是突发、抖动且深埋在噪声中的。在繁忙的网络中,带有 15% 抖动的 Cobalt Strike beacon 对于仅依赖 CV 的检测器来说看起来很像普通流量,而且长间隔漂移即使在干净的 beacon 中也会降低 CV 的准确性。 `floq` 起步时提出的问题是:还有谁需要将微弱的周期性信号从嘈杂的背景中分离出来?物理学家 —— 特别是量子混沌中的随机矩阵理论诊断方法,它们仅根据能级间距的统计特性将一系列能级分类为*随机*或*结构化*。事实证明,**能级间距比率**(Level Spacing Ratio)对于网络时序来说是一个行为良好、尺度不变且抗漂移的规律性度量指标,它承担了这里的大部分工作。`floq` 将其与变异系数项和经过零假设校准的周期性检查相结合,最后将这三者合并。 ## 名称由来 **Floquet**(flo-KAY)—— Gaston Floquet 提出的周期驱动系统框架,在这种系统中,即使是在复杂、嘈杂的动力学中,隐藏的基本周期依然存在。它是周期性检测组件的灵感来源,也是 beacon 查找器的一个贴切名称。为了准确说明该工具实际计算的内容:`floq` *并不*构建 Floquet 算符,也不对准能谱进行对角化。它计算的是到达时间间隔上的经典谱统计和时间序列统计(参见[工作原理](#how-it-works)和[科学原理](#the-science))。物理学只是这些想法的来源,而不是在底层运行的字面意义上的模拟。 ## 工作原理 `floq` 对每个网络流的时序计算三种谱诊断指标: | 指标 | 来源 | 衡量内容 | |---|---|---| | **LSR**(能级间距比率) | 随机矩阵理论 | 连续到达时间间隔的局部规律性:Poisson 流量位于 r ≈ 0.386,干净的 beacon 接近 r = 1。尺度不变,且对缓慢的间隔漂移具有鲁棒性 | | **周期显著性** | 极值校准的自相关 | 间隔*序列*是否具有统计上真实的结构(重复模式、突发周期)—— ACF 峰值仅在超过其最大噪声基底时才会被计入,因此证据会随着样本量的增加而增强 | | **抖动**(变异系数) | 经典统计学 | 时序的规律性 —— 越低 = 越像 beacon。CV > 1(超 Poisson)会受到惩罚:突发和退避重试比随机情况*更*不规律,而没有任何周期性 beacon 会是这样 | 这三者被组合成一个综合评分(0-1): ``` score = 0.45 * LSR_norm + 0.25 * period_sig + 0.30 / (1 + CV) - 0.20 * overdispersion_penalty ``` LSR 和 CV 承担了大部分的区分能力 —— 一个具有独立单次休眠抖动的 beacon(Cobalt Strike 的工作方式)会产生独立同分布(i.i.d.)的间隔,因此其所有信号都存在于间隔分布中,而从数学上讲,原始的自相关峰值根本无法为其增加证据。显著性项适用于那些间隔序列具有*真实*结构的流(例如,Neris C2 的突发模式得分为 1.0),它针对 `sqrt(2 ln L / m)` 噪声基底进行了校准,因此绝不会奖励小样本。抖动项使用平滑的倒数衰减(`1/(1+CV)`),而过散惩罚则用于剔除那些仅靠规律性指标会被误判的洪泛/突发/退避流。 ## 验证 ### 真实恶意软件(CTU 数据集) | 数据集 | 恶意软件 | C2 类型 | 结果 | |---|---|---|---| | CTU-42 (Neris) | Neris 僵尸网络 | UDP beacon ~180秒 | **首选命中:评分 0.816,period_sig 1.00** — 在 t=0.6 时,主 C2 服务器是*唯一*被警告的流 | | CTU-46 (Virut) | Virut | IRC C2 + fast-flux,垃圾邮件 | **0 检测** — 正确,没有固定间隔的 beacon | | CTU-48 (Sogou) | Sogou | IRC + HTTP + DNS,垃圾邮件/点击欺诈 | **0 检测** — 正确,没有固定间隔的 beacon | ### 混沌寻针测试 超过 40,000 个数据包的合成混沌(Poisson 突发、TCP 洪泛、端口扫描、DNS 风暴、指数退避重试、漂移心跳、高频交互的微服务),其中隐藏了 5 个具有不同间隔和抖动级别的 beacon。 ``` Chaos Needle Test — 10 seeds, threshold=0.5 ══════════════════════════════════════════════ Needles found: 50/50 (100%) Score range: [0.562 - 0.718] Avg false positives per seed: 1.9 ALL SEEDS PASSED ══════════════════════════════════════════════ ``` 最难寻找的线索 —— 300 秒间隔、25% 抖动、在 2 小时的捕获中仅有 26 个数据包 —— 在每次运行中都被找到了。剩下的误报是合成的“漂移心跳”流(具有缓慢间隔漂移的监控代理),它们的评分刚好超过阈值,落在 0.50–0.52 之间 —— 这是与 beacon 非常接近的流量,但低于每一个真实的线索。在相同的阈值下,以前基于 ACF 的评分每个随机种子大约会产生 30 个误报;通过对周期性项进行零假设校准并惩罚过散现象,在保持 100% 召回率的同时,将误报率降低了一个数量级。 ## 安装 需要 [Zig](https://ziglang.org/download/) >= 0.14.0 和 libpcap-dev。 ``` sudo apt install libpcap-dev # Debian/Ubuntu git clone https://github.com/copyleftdev/floq.git cd floq zig build -Doptimize=ReleaseSafe # 位于 zig-out/bin/floq 的二进制文件(约 276KB) ``` ### 验证 ``` zig build test # 混沌针测试(需要 Python 3 + scapy) pip install scapy cd test-data && python3 run_chaos_test.py --seeds 5 ``` ## 使用方法 ``` # 实时捕获 sudo floq -i eth0 -f "tcp" -t 0.5 # 读取 pcap 文件 floq -r capture.pcap --json # 从 tcpdump 管道输入 sudo tcpdump -i eth0 -w - | floq -r - -t 0.5 # 从 stdin 输入 OpenTelemetry JSONL cat flows.jsonl | floq --stdin --json # 使用自定义 allowlist floq -r capture.pcap --allowlist internal-services.txt ``` ### 输出 ``` [FLOQ] score=0.816 95.211.58.97 -> 147.32.84.165:1293/udp interval=199.6s jitter=0.450 lsr=0.876 period_sig=1.000 n=84 ``` 提供 JSON (`--json`) 和 CSV (`--csv`) 输出模式。退出时,统计信息会打印到 stderr: ``` --- floq stats --- duration: 1s packets: 322248 processed, 906 skipped flows: 9004 active alerts: 2 ``` ### 选项 ``` INPUT MODES: -i Live capture on interface (requires root) -r Read from pcap file --stdin Read JSONL connection events from stdin OPTIONS: -f BPF filter expression (e.g. "tcp") -w Sliding window duration (default: 300) -t <0.0-1.0> Beacon score threshold (default: 0.6) -n Minimum samples per flow (default: 10) -a Analysis interval (default: 30) --max-flows Maximum tracked flows (default: 100000) --json JSON output (one object per line) --csv CSV output --allowlist Load additional allowlist entries from file --no-allowlist Disable built-in allowlist (NTP, SNMP, etc.) -v, --verbose Periodic stats to stderr -V, --version Show version and exit ``` ### JSONL 格式 (--stdin) ``` {"ts":1234567890.5,"src":"10.0.0.1","dst":"203.0.113.50","port":443,"proto":"tcp"} ``` 支持的 OpenTelemetry 语义约定: ``` {"startTimeUnixNano":"1234567890000000000","client.address":"10.0.0.1","server.address":"203.0.113.50","server.port":443} ``` IPv6 在 pcap 和 JSONL 模式下均可工作: ``` {"ts":1234.5,"src":"2001:db8::1","dst":"::ffff:5.6.7.8","port":80,"proto":"tcp"} ``` ### 白名单文件格式 ``` # 已知周期性服务(每行一个) 123/udp # NTP 161/udp # SNMP 10.1.1.1:53/udp # Internal DNS resolver ``` ## 架构 ``` floq (~276KB) ├── main.zig Event loop, CLI, signal handling, stats ├── capture.zig libpcap: Ethernet/VLAN/IPv4/IPv6 parsing ├── ingest.zig JSONL stdin reader with OTel support ├── detector.zig Per-flow state, sliding window, LRU eviction ├── spectral.zig Level spacing ratio, jitter, periodicity significance, composite score ├── allowlist.zig Built-in + file-based allowlists ├── output.zig Human/JSON/CSV formatters, exit stats └── types.zig FlowKey ([16]u8 addrs), Config ``` ### 生产级特性 - **IPv4 + IPv6**,采用统一的 `[16]u8` 地址表示 - **802.1Q + QinQ VLAN 标签剥离** - **Linux SLL**(cooked capture)链路类型支持 - **流数量上限**(默认 100K),带有 LRU 驱逐机制 - **SIGINT/SIGTERM** 优雅关闭,并进行最终分析 - **128 字节 snaplen** — 仅捕获 L4 头部 ## 科学原理 能级间距比率源于随机矩阵理论,在那里它通过连续间距的统计特性对谱进行分类。这里有两个重要的基准点: - **Poisson**(r = 2ln2−1 ≈ 0.386):间距是不相关的指数分布 —— 真正的随机到达 - **尖桩栅栏**(r → 1):间距完全相等 —— 周期性驱动 来自随机用户活动的网络连接时间戳遵循 Poisson 统计,并位于 0.386 基准点。周期性的 C2 beacon 位于尖桩栅栏极限附近,而抖动会将其拉回 Poisson 方向:一个 15% 抖动的 beacon 测得 r ≈ 0.91,一个 50% 抖动的 beacon 测得 r ≈ 0.73。`floq` 会对偏离 Poisson 零假设、向尖桩栅栏极限靠近的距离进行评分。(量子混沌中著名的 GOE 值 0.5307 位于这两个基准点之间,但 beacon 属于尖桩栅栏类,而不是 GOE —— 周期性时序是规律性的,不存在能级互斥。) r 统计量的两个特性使其非常适合 C2 检测。它对间隔的绝对尺度具有不变性 —— 一个 10 秒间隔的 beacon 和一个 300 秒间隔的 beacon,在相同的抖动特征下会产生相同的 r。而且它是纯局部的(*连续*间隔的比率),因此一个间隔在数小时内发生漂移的 beacon 依然会保持较高的 r 值,尽管其全局 CV 已经劣化。 周期显著性组件是带有极值校准的经典时间序列分析。一个微妙的要点推动了该设计:具有独立单次休眠抖动的 beacon 会产生独立同分布(i.i.d.)的间隔,其在所有滞后处的自相关都为零 —— *事件*的周期性在*间隔*的 ACF 中不会留下任何痕迹。因此,原始的 ACF 峰值仅仅是许多噪声估计的最大值(它集中在 `sqrt(2 ln L / m)` 处,并且会随着数据的增加而*缩小*)。`floq` 减去了该噪声基底,仅对统计上显著的超出部分予以认可 —— 即间隔序列中真实的重复结构,比如 Neris C2 协议的突发周期。 ### 参考文献 1. Oganesyan, V. & Huse, D. (2007). *Localization of interacting fermions at high temperature*. Phys. Rev. B — 引入了能级间距比率诊断方法。 2. Atas, Y.Y. et al. (2013). *Distribution of the ratio of consecutive level spacings in random matrix ensembles*. Phys. Rev. Lett. — 用作零假设基准点的 Poisson 值 2ln2−1。 ## 测试 ``` # 单元测试 zig build test # 混沌针测试 — 4 万个噪声包,包含 5 个隐藏 beacon cd test-data && python3 run_chaos_test.py --seeds 10 # 针对真实恶意软件进行测试(下载 CTU 数据集) wget https://mcfp.felk.cvut.cz/publicDatasets/CTU-Malware-Capture-Botnet-42/botnet-capture-20110810-neris.pcap -P test-data/ floq -r test-data/botnet-capture-20110810-neris.pcap -t 0.6 -n 10 -w 25000 -a 9999 --json ``` ## License MIT
标签:C2检测, IP 地址批量处理, Zig, 信标检测, 用户代理, 目录遍历, 网络安全, 网络流量分析, 隐私保护