RenatoMignone/Linux-eBPF-Verifier-Bypass-Research

GitHub: RenatoMignone/Linux-eBPF-Verifier-Bypass-Research

针对 Linux LTS 6.8 内核 eBPF 验证器的安全研究项目,将理论漏洞评估转化为可实际提权的 PoC 漏洞利用代码。

Stars: 0 | Forks: 0

# Linux eBPF 验证器漏洞实战利用 (LTS 6.8) ![Polito Logo](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/18a4033e73183211.jpg) ## 摘要 本项目探讨了 **eBPF (extended Berkeley Packet Filter)** 的安全边界,这是一项革命性的技术,允许用户定义的程序在 Linux 内核中安全运行。虽然 eBPF 的验证器旨在保证内存安全并防止恶意代码执行,但某些逻辑错误可能绕过这些保护。 ## 📚 README 层次结构与导航 本项目的文档分布在多个按层次组织的 README 文件中。请从此处开始,沿着导航路径深入探索: ``` ├── README.md (you are here) │ ├─ Explains: eBPF fundamentals, verifier concepts, threat model, inherited work │ ├─ Audience: Readers unfamiliar with eBPF or the project context │ └─ Next: See "My Objective: Practical Exploitation" section below, then proceed to src/README.md │ ├── src/README.md │ ├─ Explains: Exploitation workflow, VM setup, compilation pipeline, overall methodology │ ├─ Audience: Readers ready to understand the practical approach and environment │ └─ Next: Proceed to src/exploits/README.md for detailed vulnerability analysis │ ├── src/exploits/README.md │ ├─ Explains: Multi-stage analysis methodology (bytecode → verifier → xlated → runtime) │ ├─ Explains: 5 vulnerabilities with evidence chains and classification │ ├─ Audience: Readers interested in the analysis approach and vulnerability summaries │ └─ Next: Drill into individual vulnerabilities (5_06a, 5_06b, 5_06d, 5_39, 5_46b) │ └── src/exploits/{vulnerability}/README.md (one per vulnerability) ├─ Explains: Deep technical analysis, bytecode dumps, verifier logs, exploitation mechanics ├─ Explains: Complete evidence chain from source code to runtime traces ├─ Audience: Readers performing detailed technical analysis or reproducing exploits └─ Files: Specific PoC scripts, patch files, analysis logs ``` **快速导航:** - **只想看概述?** → 阅读本文件(根目录 README.md) - **想运行漏洞利用程序?** → 跳转到 [src/README.md](src/README.md) - **想了解方法论和分析?** → 查看 [src/exploits/README.md](src/exploits/README.md) - **正在分析特定漏洞?** → 查看 [src/exploits/{vulnerability}/README.md](src/exploits/) 文件夹 1. [什么是 eBPF?](#what-is-ebpf) - [起源与演变](#origins-and-evolution) - [架构概述](#architecture-overview) - [eBPF 验证器](#the-ebpf-verifier) - [程序类型与使用场景](#program-types-and-use-cases) - [安全隐患](#security-implications) 2. [威胁模型](#threat-model) 3. [为何选择 LTS 6.8?](#why-target-lts-68) 4. [eBPF 漏洞利用原语](#ebpf-exploitation-primitives) 5. [继承的工作:前一个团队做了什么](#inherited-work-what-the-previous-team-did) - [ISO-IEC TS 17961-2013 标准](#the-iso-iec-ts-17961-2013-standard) - [什么是 XDP SynProxy?](#what-is-xdp-synproxy) - [理论与实战:差距何在](#theoretical-vs-practical-the-gap) 6. [我的目标:实战利用](#my-objective) 7. [仓库结构](#repository-structure) 8. [快速开始](#quick-start-using-inherited-infrastructure) 9. [进度追踪](#progress-tracking) 10. [参考资料](#references) ## 什么是 eBPF?
### 起源与演变 **eBPF (extended Berkeley Packet Filter)** 是一项革命性的技术,起源于 1992 年创建的经典 BPF (Berkeley Packet Filter),最初用于网络数据包过滤。虽然经典 BPF 仅限于简单的数据包检查(被 `tcpdump` 等工具使用),但 eBPF 已演变成一个通用的**内核内虚拟机**,能够在 Linux 内核中运行沙盒程序。

**时间线:** * **1992**:BPF 创建(仅限数据包过滤)。 * **2014**:eBPF 在 Linux 3.18 中引入(扩展指令集、Maps、Helpers)。 * **2016**:添加了 XDP (eXpress Data Path),用于在驱动级别进行可编程网络处理。 * **2020+**:eBPF 在可观测性、安全和网络领域变得无处不在。 ### 架构概述 eBPF 程序使用受限的 C 方言编写,编译为 eBPF 字节码,由内核验证,并 JIT 编译为本地机器代码以供执行。

**关键组件:** | 组件 | 描述 | |-----------|-------------| | **eBPF 字节码** | 平台无关的指令集(11 个寄存器,64 位) | | **验证器** | 静态分析器,在执行前确保程序安全 | | **JIT 编译器** | 将字节码转换为本地 CPU 指令 | | **Maps** | 键值存储,用于在 eBPF 程序和用户空间之间共享数据 | | **Helpers** | 可从 eBPF 调用的内核函数(例如 `bpf_map_lookup_elem`) | | **Hooks** | 内核中的附加点(kprobes、tracepoints、XDP、TC、LSM) | ### eBPF 验证器 验证器是 eBPF 的**安全基石**。它在允许每个程序在内核中运行之前对其进行静态分析。其目标是保证:

1. **内存安全** — 无越界读/写 2. **终止性** — 程序将始终完成(无无限循环) 3. **有效操作** — 仅允许的 helpers 和操作 4. **类型安全** — 正确使用指针和数据类型 **验证器分析阶段:** 1. **CFG 构建**:构建控制流图并识别执行路径。 2. **指令遍历**:模拟每条指令并跟踪寄存器状态。 3. **边界检查**:验证内存访问并跟踪指针运算。 4. **循环检测**:确保有界的迭代。 5. **Helper 验证**:检查参数类型。 **验证器局限性(攻击面):** 验证器非常复杂(`kernel/bpf/verifier.c` 中约有 20,000 行代码),必须在安全性、可用性和性能之间取得平衡。这种复杂性为**逻辑错误**创造了潜力,其中: - 验证器对程序行为的模型与实际执行不同。 - 类型跟踪中的边缘情况允许无效操作。 - 指针运算混淆了验证器的边界跟踪。 **这些验证器错误是本项目的重点。** ### 验证器如何跟踪状态(逻辑) 为了在不执行代码的情况下确保安全,验证器模拟每条指令并为 11 个寄存器(`R0`-`R10`)中的每一个维护一个**状态**。当此内部状态与实际运行时机器状态不同步时,就会发生漏洞。 **验证器对每个寄存器的跟踪内容:** 1. **类型**:它是 **SCALAR**(数字)还是 **POINTER**(指向内存/map)? * *利用路径:* 如果我们能诱骗验证器认为 **SCALAR** 是 **POINTER**,我们就可以读取任意内核内存。 2. **范围 (`tnum`)**:此寄存器保存的最小/最大值是多少? * *利用路径:* 如果验证器认为值为 `0-100`,但在运行时为 `1000`,则边界检查将被绕过(OOB R/W)。 3. **偏移量**:此指针相对于基础对象指向何处? ### 程序类型与使用场景 eBPF 支持多种程序类型,每种类型附加到不同的内核 Hook: | 程序类型 | Hook 点 | 使用场景 | |--------------|------------|----------| | `BPF_PROG_TYPE_XDP` | 网络驱动(协议栈前) | DDoS 缓解、负载均衡 | | `BPF_PROG_TYPE_SCHED_CLS` | 流量控制 (TC) | 数据包过滤、NAT | | `BPF_PROG_TYPE_KPROBE` | 内核函数 | 跟踪、调试 | | `BPF_PROG_TYPE_TRACEPOINT` | 静态内核事件 | 性能监控 | | `BPF_PROG_TYPE_LSM` | Linux 安全模块 | 安全策略 | | `BPF_PROG_TYPE_SOCKET_FILTER` | 套接字层 | 数据包检查 | **XDP (eXpress Data Path)** 对于安全研究特别有趣,因为它在网络协议栈的**最早点**运行,具有**直接内存访问**能力,并且是**性能关键**的。 ### 安全隐患 eBPF 在内核空间运行自定义代码的能力使其成为攻击者的**高价值目标**。

* **预期边界**:无法访问任意内存,无法调用任意函数。 * **如果验证器被绕过**:任意内核读取(信息泄露)、任意内核写入(权限提升)。 **历史上的 eBPF 漏洞:** | CVE | 年份 | 描述 | |-----|------|-------------| | CVE-2020-8835 | 2020 | 验证器边界跟踪错误,任意 R/W | | CVE-2021-3490 | 2021 | ALU32 边界跟踪,权限提升 | | CVE-2021-31440 | 2021 | 边界传播错误 | | CVE-2022-23222 | 2022 | 指针运算混淆 | | CVE-2023-2163 | 2023 | 验证器日志缓冲区溢出 | 本项目侧重于识别和利用 LTS 6.8 中类似的**验证器逻辑错误**。 ## 威胁模型 在深入利用之前,必须定义威胁模型——攻击者是谁,他们拥有什么能力,以及他们试图实现什么? ### 攻击者概况 | 属性 | 描述 | |-----------|-------------| | **访问级别** | 对 Linux 系统 (LTS 6.8) 的非特权用户访问 | | **能力** | 可以加载 eBPF 程序(需要 `CAP_BPF` 或 root,具体取决于内核配置) | | **局限性** | 无法直接修改内核代码、模块或绕过安全启动 | ### 攻击目标 | 目标 | 影响 | 严重性 | |------|--------|----------| | **任意内核读取** | 泄露内核地址(绕过 KASLR)、凭据、加密密钥 | 高 | | **任意内核写入** | 修改 `cred` 结构 → 权限提升至 root | 严重 | | **代码执行** | 覆盖函数指针 → 执行任意内核代码 | 严重 | ### 攻击面 攻击面具体是 **eBPF 验证器的静态分析逻辑**: - 验证器模型与实际运行时行为之间的差异 - 类型跟踪中的边缘情况(SCALAR 与 POINTER 混淆) - 算术运算中的边界跟踪错误 - 错误假设路径等价的剪枝逻辑 ### 不在范围内 - 不涉及 eBPF 的内核漏洞(use-after-free、竞态条件) - 硬件漏洞(Spectre、Meltdown) - 社会工程或物理访问攻击 - 拒绝服务(我们专注于权限提升) ## 为何选择 LTS 6.8? 选择 **Linux Kernel LTS 6.8** 作为目标是经过深思熟虑的: | 原因 | 解释 | |--------|-------------| | **长期支持** | LTS 内核在生产环境中部署 2-6 年,这意味着漏洞具有持久的影响 | | **广泛部署** | 用于企业服务器、云基础设施(AWS、GCP、Azure)和嵌入式系统 | | **安全研究价值** | 这里发现的漏洞具有现实世界的影响 | | **验证器成熟度** | 包含最新的验证器改进——如果我们能绕过它,旧内核也可能存在漏洞 | | **可复现性** | 稳定、有文档记录的版本确保一致的测试环境 | | **eBPF 功能集** | 支持所有现代 eBPF 功能(BTF、CO-RE、ringbuf),这可能会引入新的攻击向量 | ## eBPF 漏洞利用原语 一旦验证器被绕过,攻击者就会利用特定的**原语**来实现其目标。了解这些对于攻防双方都至关重要。 ### 1. 越界读取 (OOB-R) ``` ┌─────────────────────────────────────────────────────┐ │ Verifier believes: ptr can access [0, 100] │ │ Reality: ptr can access [0, 1000] │ │ │ │ Result: Read kernel memory beyond allowed bounds │ └─────────────────────────────────────────────────────┘ ``` **使用场景:** - **绕过 KASLR**:泄露内核基地址以计算 gadget 位置 - **凭据窃取**:读取 `task_struct->cred` 以提取 UID、capabilities - **密钥提取**:从内核内存泄露加密密钥 ### 2. 越界写入 (OOB-W) ``` ┌─────────────────────────────────────────────────────┐ │ Verifier believes: ptr can write [0, 64] │ │ Reality: ptr can write [0, 512] │ │ │ │ Result: Overwrite adjacent kernel structures │ └─────────────────────────────────────────────────────┘ ``` **使用场景:** - **权限提升**:将 `cred->uid` 和 `cred->gid` 覆盖为 0 → 立即获得 root - **安全绕过**:修改 `cred->cap_effective` 以授予所有 capabilities - **代码执行**:覆盖内核结构中的函数指针 ### 3. 类型混淆 ``` ┌─────────────────────────────────────────────────────┐ │ Verifier believes: R1 = SCALAR (safe number) │ │ Reality: R1 = POINTER (kernel address) │ │ │ │ Result: Arithmetic on "numbers" actually moves │ │ pointers to arbitrary kernel locations │ └─────────────────────────────────────────────────────┘ ``` **使用场景:** - 将受控整数转换为任意内核指针 - 绕过指针运算限制 - 访问验证器认为不可达的内存区域 ### 常见漏洞利用流程

## 继承的工作:前一个团队做了什么 仓库 `ebpf-exploitability-test/` 包含前一个团队(Francesco Rollo、Gianfranco Trad、Giorgio Fardo、Giovanni Nicosia)的工作,他们基于 **ISO-IEC TS 17961-2013**(C 安全编码标准)进行了**理论漏洞评估**。 ### ISO-IEC TS 17961-2013 标准 前一个团队基于 **ISO-IEC TS 17961-2013** 进行了漏洞评估,该标准标题为*"信息技术 — 编程语言、其环境和系统软件接口 — C 安全编码规则"*。 该技术规范定义了 **46 条规则**,用于识别 C 语言中导致未定义行为、安全漏洞或可靠性问题的常见编程模式。每条规则都有编号(5.1 至 5.46),并按漏洞类型分类: | 类别 | 规则示例 | 漏洞类型 | |----------|---------------|--------------------| | **内存安全** | 5.2, 5.20, 5.21, 5.35 | 冲区溢出、悬空指针、未初始化内存 | | **类型安全** | 5.1, 5.10, 5.16 | 指针转换、整数转换、别名违规 | | **控制流** | 5.4, 5.17 | switch 缺少默认情况、条件中的赋值 | | **数据处理** | 5.24, 5.40, 5.46 | 格式字符串、污点输入传播 | | **指针操作** | 5.22, 5.36 | 无效指针运算、指针比较 | #### 为何选择此标准? 团队将这 46 条规则系统地应用于 XDP SynProxy 代码,提出问题: 这种方法提供了**全面覆盖**——他们不是在寻找特定的错误,而是根据已知漏洞模式的标准目录测试验证器。 #### 不适用于 eBPF 的规则 在 46 条规则中,由于基本架构限制,有 **22 条不适用于** eBPF: | 约束 | 受影响规则 | 原因 | |------------|----------------|--------| | **无动态内存** | 5.2, 5.18, 5.21, 5.23, 5.34 | eBPF 中无 `malloc()` 或 `free()` | | **无信号处理** | 5.3, 5.5, 5.7 | 内核上下文中无信号处理程序 | | **无文件操作** | 5.12, 5.27, 5.41, 5.43 | 无 FILE 结构或 stdio | | **无标准库** | 5.8, 5.19, 5.29, 5.32, 5.37, 5.42 | 有限的 libc 访问 | | **与安全无关** | 5.25, 5.38, 5.44 | 因对利用无用而被舍弃 | **适用规则**:约 24 条规则可以在 eBPF 环境中测试。 **关键发现**:在这 24 条适用规则中,有 **21 条违规通过了验证器**——这是一个令人担忧的结果,促使了后续利用工作的开展。 ### 什么是 XDP SynProxy? 前一个团队**专门**专注于测试 XDP SynProxy 实现中的漏洞。要理解为什么这是一个重要目标,我们需要了解它解决的问题。 #### SYN Flood 攻击

**SYN flood** 是一种利用 TCP 三次握手的拒绝服务 攻击类型: **问题所在**:每个 SYN 数据包都会导致服务器分配一个**传输控制块 (TCB)** 并等待 ACK。攻击者发送数千个带有伪造源 IP 的 SYN 数据包,耗尽服务器的连接表,同时从不完成握手。 #### SYN Proxy 解决方案

**SYN Proxy** 充当中介,在将连接转发到真实服务器之前验证客户端: **SYN Cookies**:代理不再存储状态,而是将连接信息(源 IP、端口、时间戳)编码到 SYN-ACK 的**序列号**中。当客户端用 ACK 响应时,代理可以在没有存储任何状态的情况下通过数学方法验证 cookie。带有伪造 IP 的虚假客户端永远不会收到 SYN-ACK,因此无法完成握手。 #### 为何使用 XDP 进行 SYN Proxy?

传统的 SYN 代理在用户空间或内核协议栈的较高层运行,这会引入延迟。**XDP (eXpress Data Path)** 通过在**尽可能早的点**——直接在网络驱动程序中——运行 SYN 代理逻辑来解决此问题: **XDP SynProxy 优势**: - **线路速率处理**:每秒可处理数百万个数据包 - **零拷贝**:直接在驱动程序中对数据包内存进行操作 - **早期丢弃**:恶意数据包永远不会进入内核协议栈 - **CPU 高效**:无上下文切换,开销极小 #### 目标:`xdp_synproxy_kern.c` 文件 `xdp_synproxy_kern.c` 是 SYN 代理的 eBPF/XDP 实现,取自 **Linux 内核自测**。它执行: 1. **数据包解析**:以太网 → IP → TCP 头部解剖 2. **SYN 检测**:识别传入的 TCP SYN 数据包 3. **Cookie 生成**:创建加密 SYN cookie 4. **SYN-ACK 制作**:构建带有嵌入 cookie 的响应数据包 5. **ACK 验证**:验证返回的 ACK 是否包含有效 cookie 6. **连接转发**:将经过验证的连接传递给内核 前一个团队选择此目标是因为: - 它是来自 Linux 内核自测的**真实生产代码** - 它涉及用于数据包解析的**复杂指针运算** - 它使用**多种 eBPF 功能**(maps、helpers、tail calls) - 它是**安全关键**的——这里的错误可能禁用 DDoS 保护或泄露信息 - 它是**性能关键**的——必须以线路速度处理数据包 #### 重要提示:XDP SynProxy 是用户代码,而非内核代码

一个需要理解的关键区别:`xdp_synproxy_kern.c` **不是** Linux 内核本身的一部分。它是一个 **eBPF 程序**——用户提供的代码,在运行时加载*到*内核中: 这就是 eBPF 的**力量与危险**所在:任何拥有适当权限的人都可以加载在内核中以完全内核权限运行的自定义代码。 #### 作为安全守门员的验证器

eBPF 验证器的存在 specifically 是为了防止恶意或有错误的用户代码危害内核。 #### 测试实际证明了什么 当我们通过补丁注入易受攻击的代码并针对验证器进行测试时:

#### “翻译鸿沟”:C 漏洞与字节码现实 本研究的一个关键见解是,**C 源代码中的漏洞并不保证内核中的漏洞利用**,即使验证器允许加载它。 存在这种差异是因为漏洞必须经过复杂的翻译链才能存活: 1. **C 源代码**:漏洞存在于此(例如,ISO-17961 违规)。 2. **LLVM 编译**:编译器将 C 翻译为 eBPF 字节码。 * *过滤效应:* 编译器可能会优化掉易受攻击的逻辑,对分支进行死代码消除,或者将复杂的内存违规转换为良性的寄存器操作。 3. **JIT 编译**:内核将字节码翻译为本地机器码 (x86/ARM)。

**为何“验证器通过” $\neq$ “漏洞利用”:** 漏洞要可被利用,必须在此翻译过程中被**保留**。许多“理论上的”C 错误会消失,因为 eBPF 的内存模型(512 字节栈,64 位寄存器)迫使编译器生成的代码在运行时由于巧合或约束是安全的。 **示例**:C 中的缓冲区溢出(`memcpy(dst, src, user_len)`)可能会编译为使用有界循环展开的 eBPF 指令,其中编译器静态地将拷贝限制为安全最大值,而不管 `user_len` 如何。 **结论**:我们不只是在利用 C 代码;我们在利用 C 代码产生的**字节码**。 **对本项目的影响**:在开发 PoC 时,仅检查 C 源代码是不够的。我必须通过使用 `llvm-objdump -d` 或 `bpftool prog dump xlated` 等工具分析 eBPF 字节码,来验证漏洞是否在编译后存活。 #### 这为何重要 前一个团队发现了约 **21 例**验证器**错误地接受**了易受攻击代码的情况: | 结果 | 数量 | 含义 | |---------|-------|---------| | 验证器阻止 | ~14 | 安全有效 ✓ | | 编译器阻止 | ~8 | 从未到达验证器 | | **验证器通过 + 可利用** | **~9** | **安全失效 — 主要目标** | | **验证器通过 + 有限** | **~12** | **不确定 — 次要目标** | | 验证器通过 + 安全 | ~17 | 逻辑错误但无安全影响 | **9 个“可利用”**和 **12 个“有限”**案例代表了以下情况: 1. 故意编写了易受攻击的代码 2. eBPF 验证器**未能检测到**该漏洞 3. 代码被**加载到内核中** 4. 该漏洞现在具有内核权限,**可能被利用** **我的任务**:通过构建有效的漏洞利用程序,证明这些理论上的漏洞实际上是危险的。 ### 理论与实战:差距何在 理解前一个团队的工作与我的工作之间的区别至关重要: | 方面 | 前一个团队(理论) | 我的工作(实战) | |--------|----------------------------|---------------------| | **核心问题** | “此代码是否通过验证器?” | “我真的能利用这个获得 root 吗?” | | **分析类型** | 源代码分析 | 字节码 + 运行时分析 | | **输出** | 分类 (YES/LIMITED/NO) | 有效的 PoC 漏洞利用 | | **验证** | 静态评估 | 动态利用 | | **结论** | “这可能很危险” | “这很危险,这是证据” | | **交付物** | 漏洞目录 | 功能性漏洞利用代码 | **差距**:知道漏洞*存在*不同于证明它*可被利用*。许多理论漏洞在实践中失败,归因于: - 编译器优化中和了错误 - 静态分析中不可见的额外运行时检查 - 内存布局约束阻止了有用的破坏 - 缺少链接到完整利用的原语 **我的贡献**:通过将理论发现转化为实际证明来弥合这一差距。 ### 他们的测试环境 前一个团队实现了一个**完整的客户端-服务器架构**,用于实际的 eBPF/XDP 漏洞测试。他们的设置允许你: - 在单独的主机(或主机和 VM)上运行 netcat 服务器和客户端,中间有 XDP SynProxy eBPF 程序作为代理。 - 使用 `start_session.sh` 脚本启动一个 tmux 会话,该会话设置: - XDP SynProxy 加载器(将 eBPF 程序附加到网络接口) - netcat 服务器(监听 TCP 连接) - 内核跟踪输出(用于调试和观察 eBPF 行为) - 模拟真实网络通信,XDP SynProxy 程序在客户端和服务器之间拦截和处理数据包。 此架构使你能够测试如何通过网络数据包利用 eBPF 程序中注入的漏洞,为安全研究提供真实且交互式的环境。 **实践中的工作原理:** - netcat 服务器始终在 VM 上运行,监听端口 80 上的传入 TCP 连接。 - XDP SynProxy eBPF 程序附加到 VM 的网络接口,并在所有传入数据包到达服务器之前拦截它们。 - 你使用 netcat 客户端(通常来自宿主机)连接到 VM 的 IP 和端口 80,发送精心构造的网络数据包。 - 此设置允许你观察 XDP 程序如何处理、阻止或可能被这些数据包利用。

#### VM 基础设施 (`virt/`) `vmctl.sh` 脚本提供完整的 VM 生命周期管理: ``` # VM 管理命令 ./vmctl.sh create ~/.ssh/id_rsa.pub # Create and provision new VM ./vmctl.sh connect # Connect to VM console ./vmctl.sh destroy # Tear down VM ``` **VM 规格:** | 参数 | 值 | |-----------|-------| | 基础镜像 | Ubuntu 24.04 (Noble) Cloud Image | | 内存 | 4096 MB | | vCPUs | 2 | | 磁盘 | 20 GB | | Hypervisor | KVM/QEMU via libvirt | **Cloud-Init 配置**:VM 在首次启动时使用 `cloud-init` 自动配置: - 预装开发工具(`clang`、`llvm`、`bpftool`、`make`) - SSH 密钥注入以实现无密码访问 - 用于 XDP 测试的网络配置 - 所有必需的 eBPF 开发依赖项 #### 关键设计决策 - **单 VM 拓扑**:团队最初尝试了 3-veth(虚拟以太网)拓扑来模拟客户端/代理/服务器分离。然而,虚拟接口导致了 SYN cookie 的**校验和卸载问题**——内核的校验和计算与硬件预期不同。他们简化为单个真实接口,其中 XDP 程序、服务器和客户端都在同一 VM 内运行或连接到同一 VM。 - **tmux 测试会话**:`start_session.sh` 脚本创建了一个多窗格 tmux 会话,包含: - 窗格 1:XDP SynProxy 程序输出 - 窗格 2:监听连接的 Netcat 服务器 - 窗格 3:数据包监控 / 测试命令 ### 了解补丁和 `git apply` **补丁**(或 diff)是一个描述文件两个版本之间差异的文本文件。虽然补丁传统上用于分发错误修复,但在此研究背景下,它们充当**漏洞注入载体**——每个补丁将干净、安全的 `xdp_synproxy_kern.c` 转换为包含特定 ISO-17961 漏洞的版本。 #### 为何使用补丁进行漏洞注入? | 好处 | 描述 | ---------|-------------| | **隔离** | 每个漏洞存在于自己的补丁中——无交叉污染 | | **可复现性** | 任何人都可以重新创建确切的易受攻击状态 | | **可逆性** | 易于应用和还原(`git apply -R`) | | **文档记录** | 补丁元数据包含漏洞描述 | | **自动化** | xvtlas 可以以编程方式遍历补丁 | #### 补丁文件剖析 ``` From b5856aa7d76351adf1a201097c3a950c9e94502d Mon Sep 17 00:00:00 2001 From: author Date: Wed, 27 Aug 2025 13:10:03 +0200 Subject: [PATCH] feat(5.10a_exploit): intptrconv --- XDPs/xdp_synproxy/xdp_synproxy_kern.c | 251 ++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) diff --git a/XDPs/xdp_synproxy/xdp_synproxy_kern.c b/XDPs/xdp_synproxy/xdp_synproxy_kern.c index 0d0d990..34a1474 100644 --- a/XDPs/xdp_synproxy/xdp_synproxy_kern.c ← Original file +++ b/XDPs/xdp_synproxy/xdp_synproxy_kern.c ← Modified file @@ -373,6 +431,9 @@ struct header_pointers { ← Location marker static __always_inline int tcp_dissect(void *data, void *data_end, struct header_pointers *hdr) { + __u32 data_base_truncated; ← Lines starting with + are ADDED + void *calculated_ptr; + hdr->eth = data; - old_line_here ← Lines starting with - are REMOVED if (hdr->eth + 1 > data_end) ``` **关键要素:** - **头部**:提交元数据(作者、日期、消息) - **文件路径**:修改了哪些文件 - **块**(`@@`):显示行号的位置标记 - **`+` 行**:正在添加的代码 - **`-` 行**:正在删除的代码 - **上下文行**:未更改的定位行 #### Git Apply 命令 Git 提供了 `git apply` 命令将补丁应用到工作目录: ``` # 应用补丁 (修改文件但不创建 commit) git apply patches/5_10a_exploit_intptrconv/0001-feat-5_10a_exploit.patch # 检查补丁是否可以干净地应用 (dry-run) git apply --check patches/5_10a_exploit_intptrconv/0001-feat-5_10a_exploit.patch # 反向应用 (移除补丁更改) git apply -R patches/5_10a_exploit_intptrconv/0001-feat-5_10a_exploit.patch # 替代方案: git am 从补丁创建 commit git am patches/5_10a_exploit_intptrconv/0001-feat-5_10a_exploit.patch ``` #### 本项目中的工作流程

这种方法允许: - **清晰分离**:每个漏洞隔离在自己的补丁中 - **易于测试**:应用一个补丁,测试,还原,应用下一个 - **版本控制**:补丁可跟踪和审查 - **可复现性**:任何人都可以重新创建确切的易受攻击状态 ### xvtlas 自动化工具 **xvtlas** (XDP Verifier Testing Launch Automation Suite) 是团队创建的自定义 Go 工具,用于自动化测试漏洞补丁的重复性工作流程。 #### 他们构建它的原因 手动测试 60 多个漏洞补丁需要: 1. 将补丁应用到基础文件 2. 使用 clang/LLVM 编译 3. 使用 bpftool 加载程序 4. 捕获验证器输出 5. 记录结果 6. 还原补丁 7. 重复... xvtlas 自动化这整个管道:

#### 使用模式 **1. 批量测试(所有补丁)** ``` ./xvtlas --export "./output/" \ --kernel "6.8" \ --patch-path ./patches/ \ --base-file ./xdp_synproxy_kern.c \ --save-logs --verbose ``` 处理所有补丁并生成综合 CSV 报告。 **2. 单补丁交互模式** ``` ./xvtlas --run-single "./patches/5_10a_exploit/*.patch" \ --base-file "./xdp_synproxy_kern.c" ``` 应用一个补丁,编译,并打开 tmux 会话进行手动测试。 **3. 清理** ``` ./xvtlas --destroy ``` 还原 git 状态并清理先前会话的临时文件。 #### 输出结构 ``` xvtlas_output/ ├── report.csv # Summary: patch, compiled?, verified?, loaded? ├── 5_06a_argcomp/ │ ├── make.log # Compiler output and warnings │ └── verifier.log # eBPF verifier output ├── 5_10a_exploit_intptrconv/ │ ├── make.log │ └── verifier.log └── ... ``` ### 他们的方法论

他们将 46 条 C 漏洞规则应用于目标代码,以测试验证器的响应。 ### 他们生产的内容 | 产出物 | 描述 | |----------|-------------| | **60+ 漏洞补丁** | 每个都实现了特定的 ISO-IEC TS 17961-2013 规则违规 | | **基础目标:`xdp_synproxy_kern.c`** | 来自 Linux 内核自测的真实 XDP SYN 代理 | | **xvtlas 工具** | 用于补丁/编译/验证工作流程的 Go 自动化套件 | | **patches.csv** | 带有可利用性分类的汇总表 | | **详细文档** | 解释每个漏洞的 1500+ 行 | ### 他们的结果摘要 * **总共 60 个补丁** * 8 个编译失败(在验证器之前被拒绝)。 * 14 个被 eBPF 验证器阻止 ✓(安全有效)。 * 19 个通过验证器但“不可利用”(内存边界仍被强制执行)。 * **9 个通过验证器且标记为“可利用”**(这些是我的主要目标)。 * **12 个通过验证器且具有“有限”可利用性**(次要目标)。 ### 标记为“可利用”的漏洞 | 补丁 | ISO 规则 | 漏洞类型 | 他们的评估 | |-------|----------|-------------------|------------------| | `5_06a_argcomp` | 5.6 | 函数指针不匹配 | 寄存器/栈破坏 | | `5_06b_argcomp` | 5.6 | 参数数量错误 | 栈内存覆盖 | | `5_10a_exploit_intptrconv` | 5.10 | 指针截断绕过 | **信息泄露** | | `5_14_nullref` | 5.14 | 空指针解引用 | 无效内存访问 | | `5_17_swtchdflt` | 5.17 | switch 缺少默认情况 | 未定义的防火墙行为 | | `5_20a_libptr` | 5.20 | 缓冲区溢出(8 字节) | 相邻栈破坏 | | `5_20c_libptr` | 5.20 | 类型混淆溢出 | 12 字节缓冲区溢出 | | `5_35_uninit_mem` | 5.35 | 未初始化内存读取 | 内核栈数据泄露 | | `5_35a_unint_mem` | 5.35 | 未初始化内存读取 | 内核栈数据泄露 | ### 标记为“有限”可利用性的漏洞 这些漏洞通过了验证器,但具有不确定或受限的利用潜力: | 补丁 | ISO 规则 | 漏洞类型 | 他们的评估 | |-------|----------|-------------------|------------------| | `5_06d_argcomp` | 5.6 | 参数类型错误 | 值截断(局部影响) | | `5_14a_nullref` | 5.14 | 空指针解引用 | 无效访问,无逃逸路径 | | `5_16b_signconv` | 5.16 | 有符号转换 | 仅逻辑错误 | | `5_33a_restrict` | 5.33 | restrict 指针违规 | 栈中的逻辑/数据破坏 | | `5_33b_restrict` | 5.33 | restrict 指针违规 | 局部栈数据破坏 | | `5_36a_ptrobj` | 5.36 | 指针比较 UB | 内存布局信息泄露 | | `5_36b_ptrobj` | 5.36 | 上下文指针比较 | 内核布局信息泄露 | | `5_36c_ptrobj` | 5.36 | Map 指针比较 | 堆组织泄露 | | `5_39_taintnoproto` | 5.39 | 污点函数指针 | 不可预测的逻辑行为 | | `5_45_invfmtstr` | 5.45 | 无效格式字符串 | 通过日志泄露地址 | | `5_46b_taintsink` | 5.46 | 污点内存拷贝 | 攻击者控制的数据包篡改 | ### 标记为“不可利用”的漏洞 这些漏洞要么被编译器阻止,要么被验证器阻止,要么通过但没有安全影响: **因编译错误被阻止(8 个补丁):** | 补丁 | 原因 | |-------|--------| | `5_06c_argcomp` | 函数类型冲突 | | `5_13_objdec` | 变量类型冲突 | | `5_13b_objdec` | 变量类型冲突 | | `5_22d_invptr` | 数组下标越界 | | `5_24a_usrfmt` | 不兼容的指针类型 | **被 eBPF 验证器阻止(12 个补丁):** | 补丁 | 验证器错误 | |-------|----------------| | `5_4a_boolasgn` | 检测到无限循环 | | `5_4b_boolasgn` | 检测到无限循环 | | `5_06e_argcomp` | R1 type=scalar expected=map_ptr | | `5_10a_intptrconv` | Pointer arithmetic with <<= prohibited | | `5_10b_intptrconv` | R1 invalid mem access 'scalar' | | `5_14b_nullref` | R7 invalid mem access 'map_value_or_null' | | `5_16a_signconv` | R8 offset outside packet | | `5_20b_libptr` | Invalid indirect access to stack | | `5_22c_invptr` | Invalid access to context parameter | | `5_24b_usrfmt` | Invalid access to context parameter | | `5_35b_unint_mem` | R1 invalid mem access 'scalar' | | `5_40_taintformatio` | Invalid indirect access to stack | | `5_46a_taintsink` | Unbounded min value not allowed | | `5_46c_taintsink` | Address R11 invalid (VLA attempt) | **通过验证器但不可利用(19 个补丁):** | 补丁 | 原因 | |-------|--------| | `5_01a/b/c_ptrcomp` | 内存边界仍由验证器强制执行 | | `5_9_padcomp` | 仅逻辑不确定性,无内存暴露 | | `5_11_alignconv` | 逻辑误解,不可利用内存 | | `5_11a/c_alignconv` | 逻辑误解,不可利用内存 | | `5_15_addrescape` | 悬空指针但栈按数据包管理 | | `5_15a/b_addrescape` | 悬空指针但栈按数据包管理 | | `5_22_invptr` | 验证器强制执行的内存边界 | | `5_22b/e/f_invptr` | 仅逻辑误解 | | `5_26a-e_diverr` | 除以零结果为 0,无崩溃 | | `5_28_strmod` | 只读内存,程序终止 | | `5_30_intoflow` | 二进制补码运算,无内存违规 | | `5_31a/b_nonnullcs` | 需要受控内存布局 | ### 完整漏洞摘要 ``` Total: 60 patches tested │ ├─── YES (Exploitable): 9 patches ────────────► PRIMARY TARGETS │ └── Verifier bypassed, real security impact possible │ ├─── LIMITED (Uncertain): 12 patches ─────────► SECONDARY TARGETS │ └── Passed verifier, constrained exploitation potential │ └─── NO (Not Exploitable): 39 patches ├── 8 blocked by compiler ├── 14 blocked by verifier ✓ (security works) └── 17 passed but no security impact ```

**潜在调查范围:21 个补丁(9 个 YES + 12 个 LIMITED)** ### 他们没有做的事 - ❌ 创建实际有效的漏洞利用 - ❌ 实现任意内核读/写 - ❌ 演示权限提升 - ❌ 验证对真实内核版本的影响 他们证明了漏洞**可以绕过验证器**,但止步于理论分类。 ## 仓库结构 ``` Project_EBPF/ ├── README.md # This file ├── report/ # My exploitation reports (TODO) ├── src/ # My PoC code (TODO) │ └── ebpf-exploitability-test/ # INHERITED FROM PREVIOUS TEAM └── codebase/ ├── README.md # Their documentation ├── docs/ │ └── ISO-IEC-TS-17961-2013.pdf │ ├── virt/ # VM management │ ├── vmctl.sh # Create/destroy/connect to test VM │ └── meta-data.yaml │ ├── XDPs/ │ ├── xdp_synproxy/ # Main target │ │ ├── xdp_synproxy_kern.c # Base vulnerable program │ │ ├── Makefile │ │ ├── patches/ # 60+ vulnerability patches │ │ │ ├── 5_10a_exploit_intptrconv/ │ │ │ ├── 5_14_nullref/ │ │ │ ├── 5_20a_libptr/ │ │ │ └── ... │ │ ├── patches.csv # Summary of all patches │ │ ├── apply_rules.sh │ │ ├── start_session.sh │ │ └── kill_session.sh │ │ │ ├── minimal/ # Minimal exploit examples │ │ └── 5_10a_exploit.c │ │ │ └── tools/ # BPF headers │ ├── xvtlas/ # Automation tool (Go) │ ├── main.go │ ├── xvtlas # Pre-compiled binary │ └── README.md │ └── xvtlas_output/ # Previous test results ├── report.csv └── [per-patch logs]/ ``` ## 我的目标 我的工作**直接建立在现有的客户端-服务器/XDP SynProxy 架构之上**。由于 XDP 程序在网络接口运行,拥有两个主机(客户端和服务器)通过代理进行通信对于真实的利用至关重要。 **我的目标:** - 利用前一个团队的基础设施进行实战利用。 - 使用网络数据包作为攻击载体:从 netcat 客户端(在主机上)生成并发送它们到 netcat 服务器(在 VM 上),中间有 XDP SynProxy eBPF 程序。 - 通过精心构造特定的网络流量,触发并利用通过 eBPF 补丁注入 XDP 接口的漏洞。 - 用真实网络流量演示哪些漏洞在实践中是可利用的,并记录利用过程。 ### 目标 1. **深入分析**约 10 个“可利用”漏洞 2. **开发**展示真实内核影响的有效 PoC 3. **记录**利用技术和验证器绕过方法 4. **验证**在 LTS 6.8 内核上的严重性 ## 快速开始(使用继承的基础设施) ### 1. 设置测试 VM ``` cd ebpf-exploitability-test/codebase/virt/ ./vmctl.sh create ~/.ssh/id_rsa.pub ./vmctl.sh connect ``` ### 2. 测试漏洞补丁 ``` # VM 内部 cd ~/ebpf-tests/XDPs/xdp_synproxy/ # 应用补丁 git apply patches/5_10a_exploit_intptrconv/0001-feat-5_10a_exploit.patch # 编译 make # 测试 ./start_session.sh ``` ### 3. 使用 xvtlas 自动化 ``` cd xvtlas/ ./xvtlas --run-single "./patches/5_10a_exploit_intptrconv/*.patch" \ --base-file "./xdp_synproxy_kern.c" ``` ## 实战利用工作流程:分步 ### 前置条件:自动提取 vmlinux.h 以进行 eBPF 编译 在编译 XDP SynProxy eBPF 程序之前,`vmlinux.h` 头文件由会话脚本从您运行内核的 BTF 数据自动生成。此文件提供 CO-RE (Compile Once, Run Everywhere) eBPF 开发所需的所有内核类型定义。 **自动提取 vmlinux.h:** 以下命令由 `start_session.sh` 在编译前自动运行: ``` sudo bpftool btf dump file /sys/kernel/btf/vmlinux format c > /mnt/shared/XDPs/xdp_synproxy/vmlinux.h ``` 启动 VM 和会话脚本后,您只需在 `/mnt/shared/XDPs/xdp_synproxy` 中运行 `make`。如果您的共享文件夹路径不同,请相应调整输出路径。 **为何需要这样做?** - eBPF 内核程序使用 CO-RE 功能,需要准确的内核类型定义。 - 如果缺少 `vmlinux.h`,编译将失败并提示有关缺少文件的错误。 本节解释了使用继承的基础设施利用 eBPF 验证器漏洞的**完整过程**,包括 Makefile、脚本和 tmux 会话如何协同工作。它还阐明了前一个团队的理论工作与实战利用阶段之间的区别。 ### 1. 编译和加载:Makefile 的作用 `ebpf-exploitability-test/codebase/XDPs/xdp_synproxy/` 中的 Makefile 负责编译: - eBPF 内核程序(`xdp_synproxy_kern.c`)为字节码(`xdp_synproxy_kern.bpf.o`) - 用户空间加载器(`xdp_synproxy.c`)为可执行文件(`xdp_synproxy`) **工作流程:** 1.目标文件夹中运行 `make` 以构建这两个二进制文件。 2. 用户空间加载器使用 `sudo` 运行,以将 eBPF 程序加载到内核中。eBPF 验证器在加载时自动检查代码。 3. 如果代码通过,它将被加载并在内核中运行;否则,将被拒绝。 ### 2. 应用漏洞补丁 前一个团队提供了 60 多个补丁,每个补丁将特定漏洞(基于 ISO-IEC TS 17961-2013)注入基础代码。这些补丁使用 `git apply` 应用: ``` git apply patches//.patch make clean && make ``` 这允许您测试 eBPF 验证器是阻止还是接受易受攻击的代码。 ### 3. 设置测试环境:tmux 会话和脚本 同一文件夹中的 `start_session.sh` 脚本设置了一个用于交互式测试的多窗格 tmux 会话: - **窗格 1:** 运行 XDP SynProxy 加载器(`sudo ./xdp_synproxy ...`)以将 eBPF 程序附加到网络接口。 - **窗格 2:** 启动 netcat 服务器(`sudo nc -lvnp 80`)以监听 TCP 连接。 - **窗格 3:** 显示内核调试输出(`sudo cat /sys/kernel/debug/tracing/trace_pipe`)。 此环境允许您: - 观察 eBPF 程序如何处理数据包 - 查看注入漏洞的影响 - 通过从客户端发送精心构造的数据包(例如,使用主机的 netcat)测试利用 ### 4. 利用:客户端-服务器交互 tmux 会话运行后: - netcat 服务器监听传入的 TCP 连接。 - 客户端(您的宿主机或另一个 VM)使用 netcat 连接: nc 80 -v - 这模拟攻击者发送数据包以利用加载的 eBPF 程序。 - 内核跟踪和服务器输出帮助您观察漏洞是否可利用。 ### 5. 理论与实战:有何变化 **前一个团队(理论):** - 编目漏洞并测试 eBPF 验证器是否会阻止它们。 - 未尝试实际利用或权限提升。 **您的工作(实战):** - 应用补丁、编译并加载代码。 - 使用 tmux 会话模拟真实攻击并观察内核影响。 - 记录哪些漏洞在实践中真正可利用。 ### 6. 自动化工具 `xvtlas` 工具(基于 Go)可以自动化补丁应用、编译、加载和结果收集,用于批量测试。 ## 实战利用步骤摘要 1. 使用 `vmctl.sh` **启动 VM** 并连接。 2. 使用 `make` **编译基础代码或打过补丁的代码**。 3. 使用用户空间加载器**加载 eBPF 程序**(验证器自动检查)。 4. 使用 `start_session.sh` **启动 tmux 会话**。 5. 使用主机的 netcat **模拟客户端攻击**。 6. 在 tmux 窗格和内核跟踪中**观察结果**。 7. **记录发现**:验证器是否阻止了漏洞?是否可利用? 此工作流程弥合了理论漏洞评估与实战利用之间的差距,为 eBPF 安全研究提供了可复现、自动化的环境。 ## 进度追踪 - [ ] 环境搭建(VM、内核 6.8) - [ ] 研究继承的代码库 - [ ] 分析优先漏洞 - [ ] 开发 PoC #1:(待定) - [ ] 开发 PoC #2:(待定) - [ ] 编写利用报告 - [ ] 最终文档 ## 参考资料 - [ISO-IEC TS 17961-2013](https://www.iso.org/standard/61134.html) - C 安全编码标准 - [eBPF 文档](https://ebpf.io/) - [Linux 内核 BPF 验证器](https://www.kernel.org/doc/html/latest/bpf/verifier.html) - 前一个团队的详细文档:`ebpf-exploitability-test/codebase/XDPs/xdp_synproxy/README.md` ## 实战利用的优先漏洞 以下是本项目实战利用的主要焦点漏洞: - **5.6a argcomp** — 函数指针类型不兼容 - **5.6b argcomp** — 参数数量错误 - **5.6d argcomp** — 参数类型错误 - **5.39 taintnoproto** — 将污点值用作没有原型的函数指针 - **5.46b taintsink** — 具有污点长度的内存拷贝 ## 📖 后续步骤 既然您已经了解了背景和目标,请继续阅读实战利用文档: **→ [继续阅读 src/README.md](src/README.md)** 以了解利用工作流程、环境设置和整体方法论。
标签:eBPF安全, Go语言工具, ISO-IEC TS 17961, Linux内核漏洞, LTS 6.8, PoC, Web报告查看器, 云资产清单, 内存安全, 内核安全研究, 内核提权, 反取证, 子域名枚举, 安全测试, 安全评估, 底层安全, 技术白帽, 攻击性安全, 攻击技术, 日志审计, 暴力破解, 系统安全, 缓冲区溢出, 网络安全, 逆向工程, 逻辑漏洞, 隐私保护, 零日漏洞, 验证器绕过