Android内核漏洞学习——CVE-2014-3153分析(2)
字数 1640 2025-08-26 22:11:40

Android内核漏洞分析与利用:CVE-2014-3153深度解析

漏洞概述

CVE-2014-3153是Android内核中的一个严重漏洞,存在于futex(快速用户空间互斥锁)的实现中。该漏洞允许攻击者通过精心构造的futex系统调用,实现内核空间的任意地址写入,最终获取root权限。该漏洞被广泛用于"towelroot"等Android提权工具中。

漏洞背景

前置知识

  1. futex机制:Linux内核提供的快速用户空间互斥锁,允许用户空间程序进行高效的线程同步
  2. pi_mutex:优先级继承互斥锁,用于解决优先级反转问题
  3. plist:内核中的优先级链表结构,包含prio_list和node_list两个链表

漏洞成因

漏洞源于futex的requeue_pi操作中存在两个关键问题:

  1. 允许对同一个uaddr进行requeue操作
  2. 在requeue和relock过程中,可能导致pi_state->pi_mutex残留一个在线程栈上的rt_waiter结构

漏洞利用详解

利用步骤概述

  1. 通过requeue和relock操作在pi_state->pi_mutex上留下栈上的rt_waiter
  2. 重用栈空间控制rt_waiter结构
  3. 构造fake_node并链接到rt_waiter后
  4. 利用plist链表实现可控地址写入
  5. 多线程协作修改addr_limit实现内核任意写
  6. 修改cred结构体实现提权

关键数据结构

rt_waiter结构

struct rt_waiter {
    struct plist_node list_entry;  // 优先级链表节点
    struct task_struct *task;      // 关联的任务结构
};

plist_node结构

struct plist_node {
    int prio;
    struct list_head prio_list;    // 优先级链表
    struct list_head node_list;   // 节点链表
};

详细利用过程

第一步:控制rt_waiter

  1. 通过__sys_sendmmsg系统调用使rt_waiter与用户可控数据重叠
    • rt_waiter与iovstackmsgvec.msg_iov)和msgvec.msg_name部分重叠
    • 通过精心构造的msg_name和msg_iov可以控制rt_waiter内容

第二步:链表操作利用

利用plist链表的两个链表(prio_list和node_list)实现任意地址写入:

  1. 链表操作原理

    void node_remove(struct node *n) {
        struct node *prevnode = n->prev;
        struct node *nextnode = n->next;
        nextnode->prev = prevnode;
        prevnode->next = nextnode;
    }
    
  2. 构造虚假节点

    • 设置n->prev = X-8
    • 设置n->next = fakenode
    • 调用node_remove会在X地址写入fakenode地址

第三步:获取内核栈地址

  1. 在用户空间通过mmap创建fake_node
  2. 将fake_node链接到rt_waiter后面
  3. 通过fake_node.list_entry.prio_list.next获取内核栈地址

第四步:修改addr_limit

  1. thread_info定位

    • $sp & 0xffffe000 == thread_info addr
    • addr_limit位于thread_info结构中
  2. 多线程协作写入

    • 线程A:循环读取addr_limit值,检测是否可写
    • 线程B:循环尝试写入addr_limit,直到成功将其改为0xffffffff

第五步:提权操作

  1. 定位当前进程的cred结构
  2. 修改cred中的权限字段:
    cred->uid = 0;
    cred->gid = 0;
    cred->suid = 0;
    // ...其他权限字段
    cred->cap_permitted.cap[0] = 0xffffffff;
    cred->cap_permitted.cap[1] = 0xffffffff;
    // ...其他capability字段
    

官方补丁分析

补丁地址:e9c243a5a6de0be8e584c604d353412584b592f8

关键修改:

if (requeue_pi) {
    if (uaddr1 == uaddr2)
        return -EINVAL;
}

补丁禁止了对同一个uaddr进行requeue_pi操作,从根本上修复了漏洞。

防御建议

  1. 及时更新内核补丁
  2. 使用SELinux等安全机制限制进程权限
  3. 监控可疑的futex系统调用模式
  4. 实施内核地址空间布局随机化(KASLR)

总结

CVE-2014-3153是一个典型的内核UAF(Use-After-Free)漏洞,其利用过程展示了:

  1. 如何通过精心构造的系统调用控制内核数据结构
  2. 利用链表操作实现任意地址写入
  3. 多线程协作突破内核保护机制
  4. 最终实现权限提升的完整链条

该漏洞利用手法精巧,对内核数据结构和同步机制有深入理解,是研究内核漏洞利用的经典案例。

Android内核漏洞分析与利用:CVE-2014-3153深度解析 漏洞概述 CVE-2014-3153是Android内核中的一个严重漏洞,存在于futex(快速用户空间互斥锁)的实现中。该漏洞允许攻击者通过精心构造的futex系统调用,实现内核空间的任意地址写入,最终获取root权限。该漏洞被广泛用于"towelroot"等Android提权工具中。 漏洞背景 前置知识 futex机制 :Linux内核提供的快速用户空间互斥锁,允许用户空间程序进行高效的线程同步 pi_ mutex :优先级继承互斥锁,用于解决优先级反转问题 plist :内核中的优先级链表结构,包含prio_ list和node_ list两个链表 漏洞成因 漏洞源于futex的 requeue_pi 操作中存在两个关键问题: 允许对同一个uaddr进行requeue操作 在requeue和relock过程中,可能导致pi_ state->pi_ mutex残留一个在线程栈上的rt_ waiter结构 漏洞利用详解 利用步骤概述 通过requeue和relock操作在pi_ state->pi_ mutex上留下栈上的rt_ waiter 重用栈空间控制rt_ waiter结构 构造fake_ node并链接到rt_ waiter后 利用plist链表实现可控地址写入 多线程协作修改addr_ limit实现内核任意写 修改cred结构体实现提权 关键数据结构 rt_ waiter结构 plist_ node结构 详细利用过程 第一步:控制rt_ waiter 通过 __sys_sendmmsg 系统调用使rt_ waiter与用户可控数据重叠 rt_ waiter与 iovstack ( msgvec.msg_iov )和 msgvec.msg_name 部分重叠 通过精心构造的msg_ name和msg_ iov可以控制rt_ waiter内容 第二步:链表操作利用 利用plist链表的两个链表(prio_ list和node_ list)实现任意地址写入: 链表操作原理 : 构造虚假节点 : 设置 n->prev = X-8 设置 n->next = fakenode 调用 node_remove 会在X地址写入fakenode地址 第三步:获取内核栈地址 在用户空间通过mmap创建fake_ node 将fake_ node链接到rt_ waiter后面 通过 fake_node.list_entry.prio_list.next 获取内核栈地址 第四步:修改addr_ limit thread_ info定位 : $sp & 0xffffe000 == thread_info addr addr_ limit位于thread_ info结构中 多线程协作写入 : 线程A:循环读取addr_ limit值,检测是否可写 线程B:循环尝试写入addr_ limit,直到成功将其改为0xffffffff 第五步:提权操作 定位当前进程的cred结构 修改cred中的权限字段: 官方补丁分析 补丁地址: e9c243a5a6de0be8e584c604d353412584b592f8 关键修改: 补丁禁止了对同一个uaddr进行requeue_ pi操作,从根本上修复了漏洞。 防御建议 及时更新内核补丁 使用SELinux等安全机制限制进程权限 监控可疑的futex系统调用模式 实施内核地址空间布局随机化(KASLR) 总结 CVE-2014-3153是一个典型的内核UAF(Use-After-Free)漏洞,其利用过程展示了: 如何通过精心构造的系统调用控制内核数据结构 利用链表操作实现任意地址写入 多线程协作突破内核保护机制 最终实现权限提升的完整链条 该漏洞利用手法精巧,对内核数据结构和同步机制有深入理解,是研究内核漏洞利用的经典案例。