CVE-2026-43499 — vivo V2279A (PD2279J) 移植全记录
设备: vivo V2279A, MT6833 Dimensity, Android 12, Linux 5.10.149, user build
目标: 将 IonStack 全链漏洞(CVE-2026-43499)移植到此设备,获取 root
结果: 偏移量 31/31 全部确认,KASLR slide 精确测定,但 KernelSnitch mm_struct 泄露在 MediaTek 上不可行
请不要利用官方给出的内核源码来获取偏移量,除非你十分确定版本完全匹配!!!
2026-7-13更新: 出现了新的突破,之前均扫描了了错误的地址,目前已突破了KernelSnitch,但pwrite等不受支持
一、已完成的突破
1.1 偏移量提取(31/31 全部确认)
| 符号 | 值 | 方法 |
|---|---|---|
KIMAGE_TEXT_BASE | 0xffffffedb6680000 (运行时) | perf_event_open perf leak + ELF 符号匹配 |
PAGE_SHIFT | 12 (4KB) | /proc/config.gz |
VA_BITS | 48 (运行时) | KASLD 确认, /proc/config.gz 的 39 是误导 |
P0_PAGE_OFFSET | 0xffffff8000000000 | KASLD 运行时推断 |
INIT_TASK_OFF | 0x02abc140 | vmlinux-to-elf |
ASHMEM_FOPS_OFF | 0x2581e60 | IDA miscdevice 追踪 |
| 8 个 ashmem 函数 | BTI wrapper 地址 | fops struct 提取 |
CONFIGFS_READ/BIN_WRITE_ITER | 0x1a2baa8/0x1a2bad8 | configfs fops 追踪 |
COPY_SPLICE_READ_OFF | 0x1a27040 | 144 fops 共用频率分析 |
NOOP_LLSEEK_OFF | 0x1a39f10 | 59 fops 共用频率分析 |
ANON_PIPE_BUF_OPS_OFF | 0x0242f328 | vmlinux-to-elf |
KMALLOC_CACHES_OFF | 0x025c38e8 | vmlinux-to-elf |
SECURITY_HOOK_HEADS_OFF | 0x025c3db0 | vmlinux-to-elf |
EMPTY_ZERO_PAGE_OFF | 0x02cf4000 | vmlinux-to-elf |
ROOT_TASK_GROUP_OFF | 0x02cfa100 | vmlinux-to-elf |
INIT_UTS_NS_OFF | 0x02abbee8 | vmlinux-to-elf |
SELINUX_BLOB_SIZES_OFF | 0x025c4440 | vmlinux-to-elf |
SELINUX_STATE_OFF | 0x02e85bd0 | vmlinux-to-elf |
| 4 个 SLIDE 符号 | 见 target.h | vmlinux-to-elf |
1.2 运行时参数确认
MM_STRUCT_SZ = 960 (0x3C0) // /proc/slabinfo: "mm_struct 930 1054 960 34 8" MM_ORDER = 3 // 8 pages/slab KERNEL_PAGE_SIZE = 4096 // /proc/config.gz: CONFIG_ARM64_PAGE_SHIFT=12 perf_event_paranoid = -1 // 完全无限制!
1.3 KASLR Slide 精确测定
利用 perf_event_open + PERF_TYPE_HARDWARE + exclude_user=1,从 callchain 中泄露了内核地址。通过与 vmlinux-to-elf 生成的 ELF 符号表交叉对比:
0xFFFFFFEDB6738F5C→el0_svc_common(OFF=0xB8E88)0xFFFFFFEDB7E78DB4→el0_svc(OFF=0x17F8D8C)
KASLR slide ≈ 183GB — 内核文本在运行时位于 0xFFFFFFED 范围,而非预编译的 0xFFFFFFC0。
二、关键工具和方法论
| 工具 | 用途 | 关键发现 |
|---|---|---|
vmlinux-to-elf | 解包 kernel Image → 带符号的 ELF | 一次提取全部 31 个符号,省去数百次手动逆向 |
/proc/slabinfo | 运行时 slab 参数 | mm_struct 确认为 960 字节(非 0x500) |
/proc/config.gz | 内核编译配置 | 确认 PAGE_SHIFT=12、KALLSYMS_ALL |
kasld (github.com/bcoles/kasld) | KASLR 分析框架 | 确认 P0_PAGE_OFFSET=0xFFFFFF8000000000 (48-bit) |
perf_event_open | 内核地址采样 | 泄露运行时内核地址,精确计算 KASLR slide |
| IDA Pro + MCP | 内核二进制静态分析 | 追踪 ashmem/configfs fops,反编译定位 init_task |
2.1 perf_event_open 泄露技术
这是本项目最大的突破。在 perf_event_paranoid=-1 的设备上:
struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, .sample_period = 100000, .sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_CALLCHAIN, .sample_max_stack = 24, .exclude_user = 1, // 只采内核 };
通过 mmap 映射 perf ring buffer,读取样本中的 IP 和 callchain。与 ELF 符号表比对即可确定 KASLR slide。
2.2 Boot Image 解析
# 解包 Android boot.img (v4 header, LZ4 ramdisk) python unpack_boot.py # PE/UEFI-wrapped ARM64 kernel Image # 内核段: .text @ 0x10000, .data @ 0x2A60000 # KIMAGE_TEXT_BASE = PE ImageBase + .text 偏移
三、失败的根本原因
3.1 KernelSnitch mm_struct 泄露不可行
KernelSnitch 技术依赖 futex 哈希碰撞时序测量:
- 堆积 futex waiter 到特定哈希桶
- 测量
FUTEX_WAKE延迟找到碰撞地址 - 在 direct map 中暴力扫描匹配碰撞
在 MediaTek MT6833 上,big.LITTLE 架构(A76 + A55)导致时序测量产生系统性假阳性。尝试了 30+ 轮参数调优:
| 参数 | 尝试范围 | 结果 |
|---|---|---|
| 扫描范围 | 8GB / 12GB / 64GB | 碰撞始终找到,bruteforce 始终失败 |
| MM_STRUCT_SZ | 0x500 / 0x3C0 (960) | /proc/slabinfo 确认后正确 |
| 扫描步长 | 16B / 64B / 128B / 0x500 / 0x3C0 | 无影响 |
| 碰撞数 | 2 / 4 / 8 / 16 | 1个碰撞也假阳性 |
| 时序阈值 | 10x / 20x | 无法消除 |
| futex_hashsize | 动态计算 / 2048 / 4096 / 8192 | 碰撞发现正常说明值正确 |
| P0_PAGE_OFFSET | 0xFFFFC0...(39-bit) / 0xFFFF80...(48-bit) | KASLD 确认后正确 |
3.2 fork/spray 导致内核资源耗尽
prepare_kernel_page 创建大量子进程并执行 SKB spray。在 12GB 内存的移动设备上,72 次 FOPS 重试会导致整体内核资源(PID、socket buffer、slab 页)耗尽,引发 kernel panic。
四、待续的任务
-
替换 KernelSnitch — 需要一个不依赖 futex 时序测量的 mm_struct 泄露技术。可能的候选:
- TLB 侧信道(USENIX '25 论文)
- Heap Localization cache 侧信道(IEEE S&P '26 论文)
- 直接利用
perf_event_open泄露 task_struct/mm_struct
-
绕过 fork/spray — 修改 exploit 使用不同的内核页面准备策略,避免大量 fork
-
验证结构体偏移量 — 当前 target.h 中的 struct field offsets 继承自 caiman (5.15/4KB),在 5.10 上可能有差异
五、完整文件清单
exploit/src/targets/vivo-PD2279J-12/target.h— 完整偏移量(31/31 确认)boot_unpacked/kernel.decompressed— 49MB ARM64 kernel Imageoutput.elf—vmlinux-to-elf生成的带符号 ELFperf_leak.c—perf_event_open内核地址泄露程序parse_kallsyms.py— kallsyms 解析尝试(未成功)unpack_boot.py— boot.img 解包脚本android/— 4.19 内核源码(版本不匹配,仅 defconfig 有用)vendor_ramdisk.cpio— vendor_boot 解包产物(65 个 .ko 模块)
如果你在继续这个项目: 先运行
perf_leak获取当前运行时 KIMAGE_TEXT_BASE(每次重启 KASLR 不同),然后专心解决 KernelSnitch 的替代方案。偏移量已经全部有了。