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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2025-38352-PoC — PoC 和 GDB 脚本协助触发 CVE-2025-38352 | Kitploit
工具/GitHubGitHub/longwasu/cve-2025-38352-poc
内存取证漏洞分析漏洞利用逆向工程调试器论文与研究学习与教育二进制利用
GitHublongwasu/cve-2025-38352-poc

CVE-2025-38352-PoC

PoC 和 GDB 脚本协助触发 CVE-2025-38352

查看仓库
7小时7分前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2025-38352:Linux 内核 POSIX CPU 定时器 TOCTOU 竞态条件与 UAF

针对 CVE-2025-38352 的可复现概念验证(PoC)及自动化 GDB 编排脚本。该漏洞是 Linux 内核 POSIX CPU 定时器子系统(kernel/time/posix-cpu-timers.c)中的检查时间与使用时间(TOCTOU)竞态条件,可导致释放后使用(UAF)。

免责声明: 本项目仅用于教育、防御及安全研究目的。所有测试与复现均在隔离的 ARM64 QEMU 虚拟机中进行。


🧠 漏洞原理

  1. 进程 A 创建子进程 B。

  2. 进程 B 创建一个 CPU 定时器并开始退出,进入僵尸状态。就在 B 退出时,其 CPU 核心上收到一个定时器中断。内核进入中断上下文处理该定时器,但为避免死锁而临时释放其锁(unlock_task_sighand)。

  3. 与此同时,在另一个核心上,进程 A 回收正在退出的 B,清理其信号处理器(sighand = NULL)并取消其 PID 的哈希。

  4. B 中的另一个线程调用定时器删除(posix_cpu_timer_del)。它尝试通过 PID 查找该任务并检查其信号处理器,但发现它们已被清理 / 为 NULL。它误以为该任务已完全死亡且不可能有定时器触发,于是认为安全并将该定时器从内存中释放。

  5. 与此同时,第一个核心上的定时器中断处理器恢复执行,触发已过期的定时器。由于该定时器刚在第 4 步被释放,访问它会触发释放后使用(UAF)并使内核崩溃。


🔬 同步策略(poc_gdb_script.py)

由于 QEMU 的 GDB stub 不支持 set non-stop on(暂停一个 vCPU 会暂停所有 vCPU),因此无法通过普通断点实现标准的多线程同步。

本仓库通过内存指令修补解决该问题:

  1. 阶段 1(CPU 屏障):

    • 在 4 个关键内核函数处设置断点:
      • exit_notify(CPU 2)
      • kernel_wait4(CPU 0)
      • __arm64_sys_timer_delete(CPU 1)
      • handle_posix_cpu_timers(CPU 2)
    • 当每个 vCPU 到达其会合点时,GDB 用 ARM64 自跳转操作码 0x14000000(b . 无限循环)修补其 $pc 并恢复执行。
    • 当全部 4 个 vCPU 都被固定在其确切位置后,GDB 恢复原始指令并将执行交给阶段 2。
  2. 阶段 2(顺序编排):

    • GDB 锁定调度器(set scheduler-locking on)并按顺序单步推进每个 vCPU:
      • 步骤 1(CPU 2): 将 handle_posix_cpu_timers 推进越过 unlock_task_sighand()。
      • 步骤 2(CPU 0): 将 kernel_wait4 推进越过 tsk->sighand = NULL。

🚀 复现方法

1. 下载目标内核源码

在提交 1bf1aa362e6b9573a310fcd14f35bc875b42ba83 处下载或克隆 Android Common Kernel 源码树:

root@kitploit:~
# Option A: Download tarball directly
curl -LO https://android.googlesource.com/kernel/common/+archive/1bf1aa362e6b9573a310fcd14f35bc875b42ba83.tar.gz
mkdir -p kernel-cve && tar -xzf 1bf1aa362e6b9573a310fcd14f35bc875b42ba83.tar.gz -C kernel-cve
cd kernel-cve

# Option B: Clone repository
git clone https://android.googlesource.com/kernel/common
cd common
git checkout 1bf1aa362e6b9573a310fcd14f35bc875b42ba83

2. 还原 run_posix_cpu_timers() 中的补丁

打开 kernel/time/posix-cpu-timers.c,定位函数 run_posix_cpu_timers()(约第 1435–1448 行),并注释掉补丁行:

root@kitploit:~
void run_posix_cpu_timers(void)
{
    struct task_struct *tsk = current;

    lockdep_assert_irqs_disabled();

    /*
     * Ensure that release_task(tsk) can't happen while
     * handle_posix_cpu_timers() is running. Otherwise, a concurrent
     * posix_cpu_timer_del() may fail to lock_task_sighand(tsk) and
     * miss timer->it.cpu.firing != 0.
     */
//  if (tsk->exit_state)
//      return;

3. 禁用 CONFIG_POSIX_CPU_TIMERS_TASK_WORK

注意: 当 CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y 时,CPU 定时器从 task_work 上下文而非定时器 IRQ 执行,从而绕过此竞态条件。因此,必须禁用它才能复现该漏洞。

由于 CONFIG_POSIX_CPU_TIMERS_TASK_WORK 在上游 Kconfig 中缺少提示字符串,它默认为 y 且无法在 menuconfig 中直接切换。你可以按如下方式将其暴露出来:

  1. 在 kernel/time/Kconfig(约第 56 行)中,添加提示字符串并更改默认值:
    root@kitploit:~
    config POSIX_CPU_TIMERS_TASK_WORK
        bool "POSIX CPU timers task work"
        default n
    
  2. 生成默认配置并禁用该选项:
    root@kitploit:~
    ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig
    scripts/config --disable POSIX_CPU_TIMERS_TASK_WORK
    ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make olddefconfig
    
  3. 验证其在 .config 中已被禁用:
    root@kitploit:~
    grep POSIX_CPU_TIMERS_TASK_WORK .config
    # Expected output: # CONFIG_POSIX_CPU_TIMERS_TASK_WORK is not set
    

4. 构建内核

编译 ARM64 内核镜像:

root@kitploit:~
time ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j$(nproc) Image

5. 编译用户态 PoC

交叉编译 poc.c:

root@kitploit:~
aarch64-linux-gnu-gcc -ggdb3 ./poc.c -o poc

6. 启动带 GDB Stub 的 QEMU

启动具有 4 个 vCPU(-smp 4)的 QEMU 虚拟机,并启用 GDB stub(-s 标志,端口 1234):

root@kitploit:~
qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a57 \
    -smp 4 \
    -m 2G \
    -kernel arch/arm64/boot/Image \
    -append "console=ttyAMA0 root=/dev/vda oops=panic panic_on_warn=1" \
    ... \
    -s

7. 附加 GDB 并运行脚本

在宿主机终端中,将 GDB 附加到 QEMU 并加载编排脚本:

root@kitploit:~
gdb-multiarch vmlinux
pwndbg> target remote :1234
pwndbg> source poc_gdb_script.py
pwndbg> continue

8. 触发漏洞

在 QEMU 客户机 shell 中,运行编译好的二进制文件:

root@kitploit:~
./poc

[!TIP] 时序与故障排除:
如果定时器在目标线程到达僵尸状态之前过早触发,GDB 将记录:

root@kitploit:~
[!] ERROR: handle_posix_cpu_timers fired before exit_state == EXIT_ZOMBIE
  • 选项 1: 只需重新运行 ./poc 并多次 source GDB 脚本。
  • 选项 2: 增大 poc.c 中的 TIMER_FIRE_MS(例如从 #define TIMER_FIRE_MS 10 改为 20),重新编译 poc.c 并再次运行。这为线程提供了额外时间,使其在定时器过期前到达 exit_notify() 并转换为 EXIT_ZOMBIE。

9. 演示

https://github.com/user-attachments/assets/11481b5c-25f8-46c3-be3a-7b79a06a4948


📚 参考资料

  • Race Against Time in the Kernel Clockwork 作者 StreyPaws
  • CVE-2025-38352 Root Cause Analysis 作者 Faith
下载工具
  • 步骤 3(CPU 1): 将 timer_delete 推进至调用 release_posix_timer()(释放 sigq)。
  • 步骤 4(CPU 2): 释放调度器锁定,允许 CPU 2 触发已释放的定时器 $\rightarrow$ 崩溃!