purseclab/deepSURF

GitHub: purseclab/deepSURF

deepSURF 是一款结合静态分析与 LLM 自动生成 fuzz harness 的工具,专门用于检测 Rust 库中的内存安全漏洞。

Stars: 27 | Forks: 1

# deepSURF deepSURF 是一款结合了静态分析和 LLM 能力的工具,用于自动生成模糊测试工具(fuzzer)所需的 harness,以发现 Rust 库中的内存安全漏洞。 本仓库包含论文 _deepSURF: Detecting Memory Safety Vulnerabilities in Rust Through Fuzzing LLM-Augmented Harnesses_ 的相关材料,该论文已被 IEEE Symposium on Security and Privacy 2026 ([IEEE S&P '26](https://sp2026.ieee-security.org/)) 录用。 deepSURF 获得了所有三个 Artifact Evaluation 徽章(Available、Functional、Reproduced)。经过评估的工件已归档在 Zenodo 上:[AE 套件](https://zenodo.org/records/17115101)。 ### 如何引用 ``` @inproceedings{gandrout2026deepsurf, author = {Georgios C. Androutsopoulos and Antonio Bianchi}, title = {deepSURF: Detecting Memory Safety Vulnerabilities in Rust Through Fuzzing LLM-Augmented Harnesses}, booktitle = {In Proceedings of the IEEE Symposium on Security & Privacy (S&P)}, year = {2026}, note = {To appear} } ``` ## 仓库布局 - [`code/`](./code) — 核心源代码树。 - [`rust/`](./code/rust) — 用于静态分析的扩展版 **rustc 1.81.0-dev**;关键改动集中在: - [`rust/compiler/rustc_driver_impl/src/lib.rs`](./code/rust/compiler/rustc_driver_impl/src/lib.rs) - [`rust/compiler/rustc_surf/src/lib.rs`](./code/rust/compiler/rustc_surf/src/lib.rs) - [`harness_generator/`](./code/harness_generator) — Harness 生成组件。 - [`global_data/`](./code/global_data) — 用于从 fuzzer 数据创建全局 DATA 的库。 - [`fuzzer/`](./code/fuzzer) — 已配置的 **afl.rs** crate。 - [`dataset/`](./dataset) — 评估所用的数据集。 - [`rqs/`](./rqs) — 实验结果(研究问题)。 - [`rqs/rq1`](./rqs/rq1) — deepSURF 发现的漏洞的概念验证(PoC)案例。 - [`rqs/rq2`](./rqs/rq2) — deepSURF 和其他 Rust 模糊测试工具的 Fuzz harness 和 _URAPI Coverage_ 统计数据。 - [`rqs/rq3`](./rqs/rq3) — 消融实验工件。 ## 系统要求 - **平台:** deepSURF 已在 Linux (amd64) 上经过测试。建议在 Docker 容器内运行。 - **推荐主机资源:** - Harness 生成:≥ 10 CPU 核心,≥ 64 GB 内存,≥ 100 GB 可用磁盘空间。 - 模糊测试:取决于待测 harness 的数量和模糊测试配置。 - **LLM 访问:** 需提供您自己的 OpenRouter API 密钥以生成 fuzz harness。 ## 编译器基线 deepSURF 基于 commit 为 `a9c8887c7d548abc6c3e87f7d6fa02a0e95880bd` 的 **rustc 1.81.0-dev** 构建。 deepSURF 引入的所有编译器修改均包含在 [`compiler.diff`](./compiler.diff) 中。 ## 构建 要在 Docker 容器内安装 deepSURF,请在仓库根目录执行: ``` cd code # 一步设置(构建 + 任何初始准备) ./install.sh # — 或者手动操作 — ./build-docker.sh # builds the image (deepsurf:latest) ./run-docker.sh # starts the container # 对于可选的 AFL core-dumps,运行容器时可能需要额外权限(例如 `--privileged --ulimit core=-1`)。 ``` ## 运行 脚本 `generate_harnesses.sh` 包含了用于复现我们数据集 fuzz harness 的命令。在脚本开头,我们设置了一些工具参数。 变量 `OPENROUTER_API_KEY` 必须设置为您的个人 OpenRouter API 密钥。 ### 工具参数 Harness 生成可以通过以下关键参数进行配置: - `SURF_ENABLE_LLMS=1` — 启用基于 LLM 的增强组件。 - `SURF_SKIP_OPTION=""` — 选择跳过选项(默认:`condskip`)。 - `OPENROUTER_API_KEY=""` — 您的 OpenRouter API 密钥。 - `SURF_DISABLE_LLM_DOCUMENTATION=1` — 禁止在 prompt 中包含文档(当 LLM 上下文窗口受限时很有用)。 - `SURF_ENABLE_FEATURES` — 编译 fuzz harness 时要启用的 Cargo features(示例见 `generate_harnesses.sh`)。 - `SURF_EXTRA_DEPS` — 编译 fuzz harness 时要包含的额外 Cargo 依赖(示例见 `generate_harnesses.sh`)。 - `SURF_ENABLE_LINE_COVERAGE=1` — 在生成的 fuzz harness 中包含 `llvm-cov` 插桩。 - `LLM_BACKEND=""` — LLM 后端名称(根据 OpenRouter 的命名)(默认:`deepseek/deepseek-r1`)。 ### 示例 假设我们要为 crate **algorithmica-0.1.8** 生成 harness,其源代码位于 `$HOME/deepSURF/dataset/erasan_crates/algorithmica-0.1.8/`。 脚本 `generate_harnesses.sh` 已经包含了为 **algorithmica-0.1.8** 生成 fuzz harness 的命令,因此您可以直接运行它。 用于复现我们其余评估的所有命令已被注释掉。 下面,我们将逐步解释脚本中生成 harness 所执行的命令。 您可以按照相同的步骤为任何 Rust 库 crate 生成 harness。 首先,运行静态分析: ``` export SURF_HARNESS_GENERATOR_PATH=$HOME/deepSURF/code/harness_generator export GLOBAL_DATA_PATH=$HOME/deepSURF/code/global_data export SURF_ANALYZE_LIB=1 # Enable static analysis for a library crate export SURF_WORKING_PATH=$HOME/deepSURF/dataset/erasan_crates/algorithmica-0.1.8/ # Path to the target library cd "$SURF_WORKING_PATH" && cargo clean && RUSTFLAGS="-Zub-checks=no -Awarnings" cargo +rustc_surf build # Run static analysis unset SURF_ANALYZE_LIB ``` 静态分析的关键输出结果位于 `$HOME/deepSURF/dataset/erasan_crates/algorithmica-0.1.8/deepSURF/report`: - `algorithmica_.urapi.json` — 参数类型分析后检测到的库的 _URAPIs_。 - `algorithmica_.cmplx_tys.json` — 复杂类型与构造函数 API 之间的映射。 - `algorithmica_.stats.json` — 静态分析的汇总统计数据。 要根据静态分析输出结果生成 harness,请运行: ``` cd $SURF_HARNESS_GENERATOR_PATH && RUSTFLAGS="-Awarnings" cargo run --release "$(ls "$HOME/deepSURF/dataset/erasan_crates/algorithmica-0.1.8/deepSURF/report"/*.urapi.json | head -n1 | sed -E 's/\.urapi\.json$//')" # Run the harness generator using the static analysis output # 欲知更多详情,请参阅 `generate_harnesses.sh` 及其注释。 ``` harness 生成的主要输出结果位于 `$HOME/deepSURF/dataset/erasan_crates/algorithmica-0.1.8/deepSURF/`: - `fuzz/fuzzing_corpus/` — 模糊测试语料库。 - `deepsurf_stats.txt` — harness 生成的汇总统计数据。 fuzz harness 位于 `fuzz/fuzzing_corpus/` 中。如何对它们进行模糊测试取决于您的系统配置(例如,一次性全部运行或分批运行)。 我们提供了 `fuzz-algo.sh` 作为示例,用于并行模糊测试 `$HOME/deepSURF/dataset/erasan_crates/algorithmica-0.1.8/deepSURF/fuzz/fuzzing_corpus/` 下的所有 harness。 在该脚本中,每个 harness 使用两个并行的 AFL++ 线程在主从(master–slave)设置下进行模糊测试:一个启用 **ASan**,另一个启用 **CmpLog**。 ## deepSURF 发现的内存破坏漏洞 下表列出了 deepSURF 在我们的数据集上识别出的内存安全漏洞。 _列_:Dataset(数据集)、No(编号)、[RustSec ID](https://rustsec.org/)(如已分配)、Crate、Affected Function/Trait(受影响的函数/Trait)、Bug Type(漏洞类型)。 _漏洞类型代码_:DF = double free(双重释放),HBOF/SBOF = heap/stack buffer overflow(堆/栈缓冲区溢出),UAF = use after free(释放后使用),MEMCRP = 其他内存破坏违规,如任意内存访问和丢弃未初始化内存。由 deepSURF 新发现的漏洞以 `*` 标记。 | Dataset | No | RustSec ID | Crate | Affected Function/Trait | Bug Type | |:------:|:---|:-------------------|:-------------------|:-----------------------------------------|:-------:| | ERASan | 1 | RUSTSEC-2021-0053 | algorithmica | `merge_sort::merge` | DF | | ERASan | 2\* | RUSTSEC-2025-0062 | toodee | `TooDee::remove_col` | HBOF | | ERASan | 3 | RUSTSEC-2021-0028 | toodee | `TooDee::insert_row` | HBOF | | ERASan | 4 | RUSTSEC-2021-0028 | toodee | `TooDee::insert_row` | DF | | ERASan | 5 | — | toodee | `TooDee::insert_col` | HBOF | | ERASan | 6 | RUSTSEC-2021-0033 | stack_dst | `StackA::push_cloned` | DF | | ERASan | 7 | — | stack_dst | `StackA::push_stable` | DF | | ERASan | 8 | RUSTSEC-2021-0047 | slice-deque | `SliceDeque::drain_filter` | DF | | ERASan | 9\* | RUSTSEC-2025-0044 | slice-deque | `SliceRingBuffer::insert` | DF | | ERASan | 10\*| RUSTSEC-2025-0044 | slice-deque | `slice_ring_buffer::IntoIter::clone` | DF | | ERASan | 11\*| RUSTSEC-2025-0044 | slice-deque | `SliceRingBuffer::extend_from_slice` | DF | | ERASan | 12\*| RUSTSEC-2025-0044 | slice-deque | `SliceRingBuffer::shrink_to_fit` | DF | | ERASan | 13 | RUSTSEC-2021-0048 | stackvector | `StackVec::extend` | SBOF | | ERASan | 14 | RUSTSEC-2021-0042 | insert_many | `Insert_many::Vec::insert_many` | DF | | ERASan | 15 | RUSTSEC-2019-0009 | smallvec-0.6.6 | `SmallVec::grow` | DF | | ERASan | 16 | RUSTSEC-2021-0003 | smallvec-1.6.0 | `SmallVec::insert_many` | HBOF | | ERASan | 17 | RUSTSEC-2020-0039 | simple-slab | `Slab::index` | MEMCRP | | ERASan | 18 | RUSTSEC-2020-0039 | simple-slab | `Slab::remove` | HBOF | | ERASan | 19 | RUSTSEC-2020-0038 | ordnung | `CompactVec::remove` | DF | | ERASan | 20\*| — | ordnung | `CompactVec::remove` | UAF | | ERASan | 21 | RUSTSEC-2020-0005 | cbox | `CBox::::new` | MEMCRP | | ERASan | 22 | RUSTSEC-2021-0018 | qwutils | `VecExt::insert_slice_clone` | DF | | ERASan | 23 | RUSTSEC-2021-0039 | endian_trait | `slices::Endian::from_be` | DF | | ERASan | 24 | RUSTSEC-2020-0167 | pnet_packet | `MutablepV4Packet::set_payload` | HBOF | | ERASan | 25 | RUSTSEC-2021-0094 | rdiff | `BlockHashes::diff_and_update` | HBOF | | ERASan | 26 | RUSTSEC-2021-0049 | through | `through::through` | DF | | RustSan| 27 | RUSTSEC-2018-0003 | smallvec-0.6.1 | `SmallVec::insert_many` | DF | | RustSan| 28 | RUSTSEC-2018-0008 | slice-deque-0.1.15 | `SliceDeque::move_head_unchecked` | MEMCRP | | RustSan| 29 | RUSTSEC-2019-0012 | smallvec-0.6.3 | `SmallVec::grow` | MEMCRP | | RustSan| 30 | RUSTSEC-2020-0041 | sized-chunks | `Chunk::insert_from` | DF | | RustSan| 31 | RUSTSEC-2020-0041 | sized-chunks | `Chunk::insert_from` | SBOF | | RustSan| 32 | RUSTSEC-2020-0006 | bumpalo-3.2.0 | `bumpalo::realloc` | HBOF | RustSan| 33 | RUSTSEC-2020-0047 | array-queue | `array_queue::ArrayQueue::pop_back` | MEMCRP | | RustSan| 34\*| RUSTSEC-2025-0054 | array-queue | `array_queue::ArrayQueue::push_front` | MEMCRP | | RustSan| 35\*| RUSTSEC-2025-0049 | scratchpad | `scratchpad::Tracking` | HBOF | | RustSan| 36\*| RUSTSEC-2025-0053 | arenavec | `arenavec::common::SliceVec::split_off` | DF | | RustSan| 37\*| RUSTSEC-2025-0053 | arenavec | `arenavec::common::allocate_inner` | HBOF | | RustSan| 38\*| RUSTSEC-2025-0053 | arenavec | `arenavec::common::AllocHandle` | MEMCRP | | RustSan| 39 | RUSTSEC-2021-0052 | id-map | `IdMap::clone_from` | DF | | RustSan| 40 | RUSTSEC-2021-0052 | id-map | `IdMap::get_or_insert_with` | DF | | RustSan| 41\*| RUSTSEC-2025-0050 | id-map | `IdMap::from_iter` | MEMCRP | | CrabTree| 42 | — | leapfrog | `HashMap::insert` | MEMCRP | ## 备注 - 每个研究问题子目录都包含一个专门的 README 来解释其内容。
标签:AFL, AI安全, Chat Copilot, DLL 劫持, Fuzzing, Harness生成, IEEE S&P, Rust安全, Rust编程, TLS抓取, 云安全监控, 代码安全审计, 内存安全漏洞, 可视化界面, 可配置连接, 大语言模型, 测试用例生成, 程序分析, 编译器技术, 网络安全, 请求拦截, 软件安全, 隐私保护, 静态分析