Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
vulns-2026-fatfs-chance — FatFs嵌入式文件系统库中已记录的安全漏洞,包含CVE详情、模糊测试工具、漏洞利用磁盘镜像生成器,以及跨数十个下游固件项目的供应链影响分析。 | Kitploit
工具/GitHubGitHub/runzeroinc/vulns-2026-fatfs-chance
嵌入式系统安全物联网安全漏洞分析漏洞利用模糊测试硬件安全二进制分析供应链安全论文与研究学习与教育固件分析
GitHub
419411个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
runzeroinc/vulns-2026-fatfs-chance

vulns-2026-fatfs-chance

FatFs嵌入式文件系统库中已记录的安全漏洞,包含CVE详情、模糊测试工具、漏洞利用磁盘镜像生成器,以及跨数十个下游固件项目的供应链影响分析。

查看仓库

ELM FatFs 漏洞研究

本仓库记录了 FatFs 中六个经确认的安全漏洞,以及一个测试工具套件、模糊测试器和独立的漏洞利用磁盘镜像生成器。

原始 FatFs 源代码可在 FatFs-R0.16 目录中找到。

该项目是对 2017 年一次安全评估的回顾,当时通过手动审计和多日模糊测试在 FatFs 驱动中发现了一些基础但无趣的漏洞。九年后,即 2026 年 3 月,我们使用 Visual Studio Code、GitHub Copilot(自动模式)和一些基本提示重新审视了该项目,没有使用任何特定的循环、工具或技能。结果令人惊讶——在手动审计中忽略的漏洞变得易如反掌,因为 LLM 自动构建了一个带有新颖输入的模糊测试器。这项工作不仅发现了有趣的漏洞,还自动化了针对不同嵌入式开发场景的可利用性验证过程。

请参阅以下文件以获取详细说明:

  • 00_INITIAL.md:初步调查与发现
  • 01_PROJECTS.md:项目枚举与 FatFs 版本调查
  • 02_CRITICAL.md:高影响项目分析

什么是 FatFs?

FatFs 是由 ChaN(elm-chan.org)用 C 语言编写的一个可移植、免版税的 FAT/exFAT 文件系统库。它专为资源受限的嵌入式系统设计,不依赖操作系统,通常直接编译进固件。它支持 FAT12、FAT16、FAT32 和 exFAT,以及可选的 LFN(长文件名)和 GPT 分区支持。

由于 FatFs 体积小、自包含且许可宽松,它已成为微控制器固件中 FAT 实现的事实标准。该库直接以原始形式被嵌入官方 SDK、RTOS、引导加载程序和应用程序框架中——这意味着单个上游漏洞会传播到每一个复制了 ff.c 的下游项目。

主要项目

以下项目已被确认捆绑了存在漏洞的 FatFs 版本。完整的分析、每个项目的传播路径以及安全联系信息请参阅 02_CRITICAL.md。

CVE 摘要

攻击者价值

FatFs 没有 CVE 历史、没有安全邮件列表、也没有补丁通知机制。每个将 ff.c 嵌入的下游项目必须独立发现、分类并修补这些漏洞,通常甚至不知道自身受到影响。这意味着从公开披露到广泛修复的时间窗口将以年计,而非以天计。因此,实际攻击面并非单个软件应用程序或服务,而是跨越数十个独立代码库的数千万台设备,其中许多设备永远不会收到补丁。

典型的攻击场景是恶意 SD 卡:攻击者只需几秒钟的物理接触,便可更换设备(从消费级相机到无人机,从 3D 打印机到成千上万的其他产品系列)中的存储介质。该漏洞集中的每一个漏洞都可以通过挂载精心构造的 FAT 镜像来触发,而这一过程在插入时几乎总是自动发生,无需用户交互。尽管如此,物理接触并非唯一途径。

那些从网络源摄入 FAT 格式更新包的设备(如 OTA 更新框架和拖放式引导加载程序更新)容易受到任何能够向更新管道投递恶意镜像的攻击者攻击。供应链攻击、在明文 HTTP 更新流上的中间人注入,或在爱好者固件分发门户上发布的恶意镜像,都是可能的攻击方式。在任何缺乏端到端认证完整性验证(在调用 FatFs 挂载更新容器之前)的设备上,OTA 路径完全远程可达。

按 CVE 划分的攻击者价值

CVE-2026-6682 - 整数溢出导致攻击者控制的读取长度

通过构造一个特定字段设置为溢出值的 FAT32 卷,攻击者可以导致受害设备将一个攻击者选择的字节数(来自攻击者选择的源)读入固定缓冲区——这是代码执行的直接路径。在裸金属嵌入式目标上,该利用是确定性的,无需堆喷射、暴力破解或信息泄露作为前提条件。

攻击者需要控制目标将要挂载的 FAT 卷。对于大多数设备,这意味着物理接触以更换 SD 卡。接受网络固件更新,或仅在 FatFs 解析后才信任更新包完整性的设备,可远程利用。

CVE-2026-6683 - exFAT 同步中的除零错误

能够向运行 R0.16 之前版本 FatFs 的设备投递精心构造的 exFAT 卷的攻击者可以保证在后续任何写入时触发崩溃。FatFs R0.16 添加了一个部分挂载时防护,可能在写入发生前拒绝构造的卷,但底层的算术缺陷并未完全修复。对于通过写入 FAT 格式介质应用 OTA 固件更新的设备,成功触发成为一次性远程变砖:更新过程在写入中途崩溃,设备可能无法恢复,除非物理接触硬件调试器。

攻击者需要目标挂载其控制的 exFAT 卷,然后执行任何写入或同步操作。恶意 SD 卡场景覆盖了大多数嵌入式设备;对于远程利用,目标的 OTA 管道必须接受并挂载攻击者提供的镜像,而不首先验证其完整性。

CVE-2026-6684 - GPT 分区扫描中的无限循环

提供一个单个字段设置为最大值的 GPT 磁盘镜像会导致目标循环读取磁盘扇区,直到电源被断开。对于没有看门狗的引导加载程序和裸金属固件,这是一个永久性变砖:设备永远无法完成启动。该漏洞已在 FatFs R0.16 中修复,因此仅影响使用旧版本发布版的设备。

攻击者需要目标挂载其控制的 GPT 格式化磁盘,并且目标必须运行支持 64 位 LBA 的 R0.16 之前版本的 FatFs 构建。请注意,引导加载程序在此处是最具吸引力的目标,恰恰因为它们通常没有看门狗,也没有恢复路径。

CVE-2026-6686 - 在 Seek 超过文件末尾后可读的陈旧簇数据

当通过 Seek 超过文件末尾来扩展文件时,FatFs 不会将新分配的存储清零。先前写入这些扇区的任何数据(来自已删除的文件)都可以被打开该扩展文件的下一个进程读取。在通过 OTA 暂存区循环固件镜像的设备,或在引导加载程序和应用程序之间共享 SD 卡的设备上,这可能将先前的固件二进制文件、密钥或其他敏感内容暴露给低权限的读取者。

攻击者需要能够读取目标 FAT 卷上通过 Seek 操作扩展的文件。这主要是本地或物理接触场景。

CVE-2026-6687 - 通过 exFAT 卷标溢出导致的栈缓冲区溢出

提供一个带有超长卷标的 exFAT 卷会导致 FatFs 在应用程序调用 f_getlabel() 时溢出调用者的标签缓冲区。ST 的 STM32CubeMX 代码生成器在其生成的每个启用 FatFs 的项目中都使用了易受攻击的缓冲区大小,这意味着该漏洞存在于大量且大部分未编目的商业 STM32 固件中。在没有栈保护或 ASLR 的裸金属 Cortex-M 设备上(常见情况),这是一个一次性代码执行原语。

攻击者需要目标挂载其控制的 exFAT 卷,然后调用 f_getlabel()。FatFs 库不会内部调用此函数——应用程序必须显式调用。大多数项目在自身的挂载时初始化中会这样做,在实践中对于这些项目无需攻击者进一步交互。

CVE-2026-6688 - 通过目录列表中的长 LFN 文件名导致的缓冲区溢出

通过在 FAT 目录中放置一个长文件名文件,攻击者可以在调用应用程序遍历目录时溢出用于存储该名称的缓冲区。溢出量与文件名长度成正比,最多可达 255 字节。该漏洞存在于调用代码中,而非 FatFs 自身,因此影响因目标而异——但任何遍历目录并将文件名复制到固定大小缓冲区且不检查长度的应用程序都会受到影响。

攻击者需要目标遍历其控制的 FAT 卷上的目录。不需要 exFAT;此漏洞适用于 FAT12、FAT16 和 FAT32。必须在 FatFs 配置中启用长文件名支持,而这是每个主要发行版中的默认和推荐设置。

漏洞详情

在 FatFs R0.16 及更早版本中发现了六个不同的错误。

CVE-2026-6682 - FAT32 整数溢出在 mount_volume() 中 → 攻击者控制的 finfo.fsize

位置: ff.c mount_volume() - fasize *= fs->n_fats

当 BPB_FATSz32 被构造为产生一个较大值时,会发生 DWORD 乘法溢出。当 BPB_FATSz32 = 0x80000001 且 NumFATs = 2 时:```c fasize = 0x80000001; fasize *= 2; // DWORD overflow → 0x00000002

root@kitploit:~
截断的 `fasize` 导致 `fs->database`(数据区起始位置)落入 FAT 区域。控制磁盘镜像的攻击者可以在重叠扇区放置伪造的目录项,使 `f_stat()` 返回攻击者控制的 `finfo.fsize`。任何调用 `f_read(fp, buf, finfo.fsize, &br)` 但未对计数进行 `sizeof(buf)` 边界限制的应用程序,都会导致目标缓冲区被完全由攻击者控制的字节溢出——这是通向 RCE 的直接路径。

**最坏影响:** 在从 FatFs 读取文件大小并将其用作读取长度的任何嵌入式设备上,可实现远程代码执行(堆或栈溢出)。

---

### CVE-2026-6683 - `sync_fs()` 中的除零错误(exFAT)

**位置:** `ff.c` `sync_fs()` - `(n_fatent - 2 - free_clst) * 100 / (n_fatent - 2)`

当 `BPB_NumClusEx = 0` 时,`n_fatent = 2`,使得除数 `(n_fatent - 2) = 0`。在对精心构造的 exFAT 卷执行任何写入或同步操作时都会触发此问题,产生 SIGFPE / 硬件故障并导致目标崩溃。

FatFs R0.16 在挂载时部分地对此进行了防护(当 `NumClusEx = 0` 时,位图簇验证失败)。旧版本——R0.14b(ArduPilot、Mbed OS)、R0.15(RIOT OS、STM32)、R0.13c(MicroPython)——没有此类防护,会无条件崩溃。

**最坏影响:** 对精心构造的 exFAT 卷进行任何写入操作时,导致拒绝服务/系统崩溃。在 OTA 更新期间,这可能会使设备变砖。

---

### CVE-2026-6684 - `find_volume()` 中无限制的 GPT 分区扫描循环(R0.16 之前)

**位置:** `ff.c` `find_volume()` - `for (i = 0; i < n_ent; i++) disk_read()`

当 `FF_LBA64 = 1` 时,`find_volume()` 遍历每个 GPT 分区条目以搜索 FAT 分区。在 R0.16 之前的构建中,循环次数直接取自磁盘上的 `GPTH_PtNum` 字段(0–0xFFFFFFFF),没有上限。精心构造的 GPT 镜像将 `GPTH_PtNum = 0xFFFFFFFF` 会导致大约十亿次磁盘读取,然后函数返回“未找到”,使系统永久挂起。

R0.16 引入了 `test_gpt_header()`,它在进入循环前验证 CRC32 并强制 `PtNum ≤ 128`。

**最坏影响:** 永久性的挂载时拒绝服务。在没有看门狗的设备上(引导加载器、裸机 FPGA 引导 ROM),这会永久性地使系统变砖。

### CVE-2026-6686 - 通过 `f_lseek()` 超出 EOF 导致的未初始化簇数据

**位置:** `ff.c` `f_lseek()`:```c
if (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) {
    fp->obj.objsize = fp->fptr;   // extend, but never zero-fill
    fp->flag |= FA_MODIFIED;
}

请求超出文件末尾会调用 create_chain() 来分配新的簇,但从未对其扇区清零。随后对扩展区域的任何读取将返回原始的陈旧数据——即回收簇中残留的已删除文件内容。

**最坏情况影响:**已删除文件内容(旧固件映像、私钥、传感器数据)泄露给权限较低的读取者或通过连接接口泄露。


CVE-2026-6687 - 通过 exFAT XDIR_NumLabel 在 f_getlabel() 中的栈缓冲区溢出

位置: ff.c f_getlabel():```c for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) { wc = ld_16(dj.dir + XDIR_Label + si * 2); nw = put_utf((DWORD)hs << 16 | wc, &label[di], 4); di += nw; }

root@kitploit:~
exFAT规范将`XDIR_NumLabel`限制为11个字符。FatFs将其作为原始`BYTE`(0–255)读取,不做任何验证。精心构造的卷中的`XDIR_NumLabel = 128`会导致`f_getlabel`向调用者的缓冲区写入128个字符——通常是STM32CubeMX生成的`char label[12]`或`char label[24]`——从而溢出堆栈多达244字节。

**最坏情况影响:** 在exFAT卷上,任何调用`f_getlabel()`的函数都存在堆栈缓冲区溢出。典型的漏洞模式(`char label[12]`)出现在STM32CubeMX、AN3224和UM1721生成的每个项目中。

---

### CVE-2026-6688 - 通过长LFN文件名导致调用者堆栈/堆溢出

**根本原因:** 当启用`FF_USE_LFN`时,`f_readdir()`会用完整的Long File Name填充`fno.fname`——最多`FF_LFN_BUF`(255)个字符。仅针对SFN操作编写的调用者使用固定大小的路径或名称缓冲区(例如`char path[16]`、`char name[14]`),并在没有边界检查的情况下复制`fno.fname`。

在多个项目中发现的常见漏洞模式:```c
strcpy(entry->name, fno.fname);          // Zephyr: entry->name[14]
sprintf(path, "0:/%s", fno.fname);       // NodeMCU, ChibiOS demo, StarryPilot
sprintf(&cur_path[n], "/%s", fn);        // Samsung TizenRT

最坏情况影响: 在精心构造的FAT卷上进行任意目录遍历时,栈或堆溢出与LFN长度成正比(最多255字节)。精心构造的SD卡使entry->name[14]溢出241字节,会可靠地破坏Zephyr调度器栈帧。


仓库布局```

├── harness/ Security test harness and exploit tools │ ├── Makefile Build system (see targets below) │ ├── test_ffconf.h FatFs config for the harness (LFN+exFAT+LBA64) │ ├── diskio_ramdisk.c/h In-memory block device (2 MiB RAM disk) │ ├── ffunicode_stub.c Minimal Unicode stub (CP437 pass-through) │ ├── test_harness.c Deterministic per-bug test suite (CVE-2026-6682 through CVE-2026-6688) │ ├── rce_demo.c Standalone CVE-2026-6682 RCE demo: OTA struct-pointer overwrite │ ├── libfuzzer_harness.c libFuzzer / AFL++ entry point │ ├── exploit_disks.c Standalone disk-image generator (see below) │ ├── build/ Compiled binaries │ └── img/ Generated exploit disk images (*.img) │ ├── fuzzer/ Go corpus generator and structural fuzzer │ ├── main.go Corpus builder + Go native fuzz targets │ ├── fat_image.go FAT12/16/32/exFAT/GPT image construction helpers │ └── corpus/ Seed corpus written by make corpus

root@kitploit:~
---

## Harness 构建目标

所有目标均从 `harness/` 目录运行。需要 `clang`(或设置 `CC=gcc`)。

要在 macOS 上构建 `afl` 目标,请使用 `brew install afl++`,然后运行 `sudo afl-system-config` 来准备系统。

| 目标 | 描述 |
|--------|-------------|
| `make` / `make test` | 构建并运行带 ASan + UBSan 的确定性测试套件 |
| `make rce_demo` | 构建并运行 CVE-2026-6682 RCE 演示(无 Sanitizers,无栈保护) |
| `make exploit_disks` | 构建并生成全部 14 个漏洞利用磁盘镜像到 `harness/img/` |
| `make fuzz_asan` | 构建 libFuzzer 二进制文件(`build/fuzz_fatfs`) |
| `make afl` | 构建 AFL++ 目标(需要 `afl-clang-fast` 在 `PATH` 中) |
| `make corpus` | 通过 Go 生成器生成种子语料库到 `harness/corpus/` |
| `make clean` | 移除 `build/` 和 `img/` |

### 快速开始```sh
# Run the full deterministic test suite
cd harness && make

# Run the CVE-2026-6682 RCE demo
make rce_demo

# Generate all exploit disk images
make exploit_disks

# Fuzz with libFuzzer (requires clang)
make fuzz_asan
build/fuzz_fatfs -max_len=2097152 corpus/

# Fuzz with AFL++
make corpus afl
afl-fuzz -i corpus/ -o findings/ -- build/afl_fatfs @@

漏洞利用磁盘镜像

make exploit_disks 在 harness/img/ 下生成14个原始磁盘镜像,每个对应一个项目/漏洞组合。每个镜像在生成时都会通过挂载附带的FatFs进行自测试。这些镜像可以写入物理SD卡:```sh dd if=harness/img/exploit_bug1_espidf.img of=/dev/sdX bs=512

root@kitploit:~
| Image | Bug | 目标项目 | 效果 |
|-------|-----|----------|--------|
| `exploit_bug1_fat32.img` | CVE-2026-6682 | 通用 | 通过 `f_read` 传递指针大小的有效载荷 |
| `exploit_bug1_espidf.img` | CVE-2026-6682 | espressif/esp-idf | `finfo.fsize=16 MB` → `malloc`/`fread` 堆溢出 |
| `exploit_bug1_stm32.img` | CVE-2026-6682 | STMicro stm32-mw-fatfs | `finfo.fsize=1 MB` → 1 KB 固件缓冲区溢出 |
| `exploit_bug1_keystone3.img` | CVE-2026-6682 | KeystoneHQ wallet | `finfo.fsize=512 KB` → OTA 缓冲区溢出 |
| `exploit_bug1_ardupilot.img` | CVE-2026-6682 | ArduPilot / Mbed OS / RIOT / MicroPython | `finfo.fsize=2 MB` → 日志读取缓冲区溢出 |
| `exploit_bug2_exfat.img` | CVE-2026-6683 | ArduPilot / Mbed OS / MicroPython / RIOT | `BPB_NumClusEx=0` → `sync_fs` 除零错误(在 pre-R0.16 上为 SIGFPE) |
| `exploit_bug3_gpt.img` | CVE-2026-6684 | vivado-risc-v / tinyuf2 / circle | `GPTH_PtNum=0xFFFFFFFF` → 启动时无限循环(pre-R0.16) |
| `exploit_bug5_stale.img` | CVE-2026-6686 | RT-Thread / tinyuf2 / ArduPilot / RIOT | `f_lseek` 扩展暴露了以 `0xAA` 填充的已删除簇数据 |
| `exploit_bug6_stm32.img` | CVE-2026-6687 | STMicro stm32-mw-fatfs | `XDIR_NumLabel=128` → CubeMX `label[12]` 的 117 字节溢出 |
| `exploit_bug6_zephyr.img` | CVE-2026-6687 | Zephyr / ArduPilot / RIOT / MicroPython | `XDIR_NumLabel=255` → `label[24]` 的 216 字节溢出 |
| `exploit_bug7_max255.img` | CVE-2026-6688 | NodeMCU / ChibiOS / StarryPilot / TizenRT | 255 字符的 LFN 溢出任何小于 255 字节的固定缓冲区 |
| `exploit_bug7_zephyr.img` | CVE-2026-6688 | Zephyr | 14 字符的 LFN → `entry->name[14]` 的 1 字节 NUL 溢出 |
| `exploit_bug7_grblhal.img` | CVE-2026-6688 | grblHAL | 差一错误:保护检查上一个条目;11 字符的 LFN 以 1 个 NUL 字节溢出 `dirent.name[12]` |

---

## 确定性测试套件(`test_harness.c`)

测试工具通过内存中构建的手工磁盘镜像测试六个漏洞,然后确认已到达易受攻击的代码路径:

- **CVE-2026-6682** - 构建一个 `BPB_FATSz32=0x80000001` 的 FAT32 镜像,挂载它,并确认 `fs.database` 落在 FAT 区域内;然后执行完整的 RCE 链(伪造目录项 → `f_read` 读取植入的函数指针 → 调用 `rce_proof_of_execution()`)。
- **CVE-2026-6683** - 记录 `(n_fatent-2)` 除数并确认运算路径;检查 R0.16 在挂载时拒绝该镜像。
- **CVE-2026-6684** - 构建一个 `GPTH_PtNum=0xFFFFFFFF` 的 GPT 镜像,并确认 R0.16 通过 `test_gpt_header()` 在 ≤ 3 次磁盘读取内拒绝它。
- **CVE-2026-6686** - 用 `0xAA` 预填充所有数据簇,写入一个短文件,通过 `f_lseek` 扩展它,并回读以确认可见的陈旧字节。
- **CVE-2026-6687** - 构建一个带有 `XDIR_NumLabel=128` 的 exFAT 镜像,调用 `f_getlabel` 到探测缓冲区,并统计超过第 24 字节的溢出。
- **CVE-2026-6688** - 构建一个包含 50 字符 LFN 的 FAT16 目录,通过 `f_readdir` 读取它,并确认 `fno.fname` 长度超过典型调用者的缓冲区。

## CVE-2026-6682 RCE 演示(`rce_demo.c`)

一个自包含、真实的 CVE-2026-6682 利用链演示,模拟嵌入式 OTA 固件更新代码。 声明了一个结构体,其中包含一个固定大小的头部缓冲区,后面紧跟着一个函数指针回调:```c
typedef struct {
    uint8_t  fw_header[128];   // buffer the developer reads into
    uint32_t crc32;
    uint32_t version;
    void   (*on_apply)(void);  // callback - attacker target
} ota_ctx_t;

该演示构建了一个精心构造的磁盘镜像,其中 DIR_FileSize = sizeof(ota_ctx_t), 将 rce_win() 的地址放置在 payload 扇区的正确字节偏移处, 然后运行 OTA 检查器。f_read 从 fw_header 写入到 on_apply 的越界位置, 随后的 ctx.on_apply() 调用会触发 rce_win(), 并将 rce_canary 设置为 0xDEAD。

构建并运行:cd harness && make rce_demo


Fuzzer (fuzzer/)

Go 模糊测试器有两种模式:

  1. 语料库生成器(go run . -out ./corpus 或 make corpus):生成 18 个 结构化的种子镜像,覆盖六种漏洞类别、所有三种 FAT 变体、正常和畸形 GPT,以及对一个有效 FAT32 镜像的 50 个随机单字节突变。

  2. Go 原生模糊测试器(go test -fuzz=FuzzFAT32BPB):使用 Go 内置的模糊测试器对 BPB 字段值进行结构性模糊测试;验证字段之间的关系 而无需调用 C 代码。

种子语料库同时提供给 libFuzzer 二进制文件(build/fuzz_fatfs)和 AFL++ 目标(build/afl_fatfs)。

通过 QEMU 的 ESP-IDF

该仓库包含一个自包含的 Docker 测试用例,演示了 一个与 ESP32 相关的 CVE-2026-6688 调用者溢出模式,利用 FatFs 目录遍历 在 Espressif QEMU ESP32 模拟器中的 ESP-IDF 固件上执行。

当前的 PoC 镜像有意设计为混合模式:

  • 它保留了 CVE-2026-6682 风格的精心构造的 FAT32 几何结构,以便伪造的根 目录被可靠地控制。
  • 它嵌入了一个由 readdir() 返回的长 VFAT 文件名。
  • 然后应用程序镜像了公共 ESP32 代码模式(strcpy / strcat 路径组合),并将长文件名复制到一个固定的 32 字节缓冲区中。

这个最后的复制就是 CVE-2026-6688 风格的条件:由于对长文件名的无界使用而导致的 调用者侧溢出。``` cd esp32-qemu-test ./run.sh

root@kitploit:~
或者,另一种方式是:```
docker build -t fatfs-esp32-vuln-test esp32-qemu-test/
docker run --rm fatfs-esp32-vuln-test

为什么这映射到 CVE-2026-6688

f_readdir() 可以返回长达 255 个字符的长文件名(LFN)。许多实际的嵌入式调用者仍然将名称复制到较小的固定缓冲区中。公共的 ESP32 示例包括等同于以下模式的模式:``` strcpy(fn, entry->d_name); strcat(path, "/"); strcat(path, entry->d_name);

root@kitploit:~
使用包含长文件名的精心构造的FAT镜像,这些复制操作会溢出调用方缓冲区。

### 此仓库中的PoC链

| 步骤 | 描述 | 标记 |
|------|------|------|
| 1 | 精心构造的存储镜像挂载并返回攻击者控制的目录条目 | (挂载成功) |
| 2 | 长文件名通过公共模式的不安全复制路径被复制到`char name[32]`中 | `[VULN-BUG7-CONFIRMED]` |
| 3 | 记录到保护字段损坏,随后在QEMU中发生控制数据崩溃 | `guard=0x61616161`, `Guru Meditation Error` |

该PoC仍然保留了一个传统的CVE-2026-6682风格的OTA回调覆盖路径,用于上下文和标记输出(`PWNED-UART`),但此处针对该漏洞的具体证明是上述的长文件名调用方溢出标记。

代表性输出:```
I (...) fatfs_vuln: PoC: CVE-2026-6688 long-LFN caller overflow probe (ESP32 public-pattern copy path)
...
PWNED-UART
E (...) fatfs_vuln: [VULN-BUG7-CONFIRMED] guard corrupted after filename copy
E (...) fatfs_vuln: entry='esp32_lfn_trigger_aaaa...aaaa.bin' len=78 guard=0x61616161
Guru Meditation Error: Core  0 panic'ed (...)

关于 CVE 编号的说明

在此研究过程中,曾记录并报告过一项无符号减法行为,但后来该信息从 CVE 数据库中移除。因此,您会注意到编号上存在空缺,这是因为我们有意省略了该已被撤回的记录,未将其纳入本仓库的活跃 CVE 集合中。CVE 项目对于引用未发布的记录可能较为敏感,这样做既避免了交叉引用的麻烦,又保持了历史记录的准确性。对于非常好奇的读者,您可以通过查阅本仓库的 git 历史记录来了解该发现的详细信息。

感谢 David Brown 提醒我们注意这份有争议的报告。关于上游状态和补丁指南,请关注 ChaN 官方的 FatFs 补丁页面:https://elm-chan.org/fsw/ff/patches.html

下载工具
项目星标数FatFs 版本漏洞
espressif/esp-idf17,655R0.16CVE-2026-6682
STMicroelectronics/stm32-mw-fatfs所有 STM32CubeR0.15 w/p2CVE-2026-6682, CVE-2026-6683, CVE-2026-6686, CVE-2026-6687
zephyrproject-rtos/zephyr14,820R0.16CVE-2026-6683, CVE-2026-6687, CVE-2026-6688
micropython/micropython21,583R0.13c (2019)CVE-2026-6682, CVE-2026-6683, CVE-2026-6684, CVE-2026-6686, CVE-2026-6687
ArduPilot/ardupilot14,743R0.14bCVE-2026-6682, CVE-2026-6683, CVE-2026-6686, CVE-2026-6687
RT-Thread/rt-thread11,862R0.16CVE-2026-6683, CVE-2026-6686
nodemcu/nodemcu-firmware7,903不定CVE-2026-6688
RIOT-OS/RIOT5,701R0.15CVE-2026-6682, CVE-2026-6683, CVE-2026-6686, CVE-2026-6687
ARMmbed/mbed-os4,837R0.14bCVE-2026-6682, CVE-2026-6683, CVE-2026-6686
sbabic/swupdate1,780R0.16CVE-2026-6683
rsta2/circle2,222待定CVE-2026-6684
hugen79/NanoVNA-H695R0.15CVE-2026-6683
ChibiOS/ChibiOS833不定CVE-2026-6688
Samsung/TizenRT643R0.16CVE-2026-6683, CVE-2026-6688
adafruit/tinyuf2447待定CVE-2026-6684, CVE-2026-6686
grblHAL/Plugin_SD_card475R0.16CVE-2026-6688
JcZou/StarryPilot315R0.16CVE-2026-6688
KeystoneHQ/keystone3-firmware199R0.16CVE-2026-6682
flysight/flysight44不定CVE-2026-6682, CVE-2026-6688
eugene-tarassov/vivado-risc-v1,061待定CVE-2026-6684
CVE ID简短标题CWE
CVE-2026-6682FAT32 卷挂载中的整数溢出CWE-190: 整数溢出或回绕
CVE-2026-6683exFAT 同步中的除零错误CWE-369: 除零错误
CVE-2026-6684GPT 分区扫描中的无限循环CWE-835: 循环不可达退出条件
CVE-2026-6686在 Seek 超过文件末尾后使用未初始化的簇CWE-908: 使用未初始化的资源
CVE-2026-6687通过未限制的 exFAT 卷标长度导致的栈缓冲区溢出CWE-121: 基于栈的缓冲区溢出
CVE-2026-6688通过无界 LFN 文件名复制导致的缓冲区溢出CWE-120: 未检查输入大小的缓冲区复制