CVE-2013-6123分析

0x00 CVE-2013-6123分析

0x01 漏洞描述

CVE-2013-6123是MSM摄像头驱动的漏洞,在MSM摄像头驱动中的msm_cam_server.c文件中的‘msm_ctrl_cmd_done’,‘msm_ioctl_server’及‘msm_server_send_ctrl’函数存在数组索引错误漏洞。攻击者可通过摄像头设备节点的访问权限利用该漏洞获取特权。该漏洞的主要是存在数组下标越界,使得用户端可以利用该漏洞突破内核地址防护,实现任意地址写。

0x02 漏洞补丁

在这里插入图片描述

补丁代码
在msm_ioctl_server这个方法里面加了一句关于这个值得校验
u_isp_event.isp_data.ctrl.queue_idx

poc的思路就简单了,我们就看越过这个值得范围会数组越界异常

0x03 代码分析

static int msm_ctrl_cmd_done(void *arg)
{
	void __user *uptr;
	struct msm_queue_cmd *qcmd;
	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
	struct msm_ctrl_cmd *command;
	D("%s\n", __func__);

	command = kzalloc(sizeof(struct msm_ctrl_cmd), GFP_KERNEL);
	if (!command) {
		pr_err("%s Insufficient memory. return", __func__);
		goto command_alloc_fail;
	}

	qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
	if (!qcmd) {
		pr_err("%s Insufficient memory. return", __func__);
		goto qcmd_alloc_fail;
	}

	mutex_lock(&g_server_dev.server_queue_lock);
	if (copy_from_user(command, (void __user *)ioctl_ptr->ioctl_ptr,
					   sizeof(struct msm_ctrl_cmd))) {
		pr_err("%s: copy_from_user failed, size=%d\n",
			   __func__, sizeof(struct msm_ctrl_cmd));
		goto ctrl_cmd_done_error;
	}

	if (!g_server_dev.server_queue[command->queue_idx].queue_active) {
		pr_err("%s: Invalid queue\n", __func__);
		goto ctrl_cmd_done_error;
	}

	D("%s qid %d evtid %d %d\n", __func__, command->queue_idx,
		command->evt_id,
		g_server_dev.server_queue[command->queue_idx].evt_id);
	if (command->evt_id !=
		g_server_dev.server_queue[command->queue_idx].evt_id) {
		pr_err("%s Invalid event id from userspace cmd id %d %d qid %d\n",
			__func__, command->evt_id,
			g_server_dev.server_queue[command->queue_idx].evt_id,
			command->queue_idx);
		goto ctrl_cmd_done_error;
	}

	atomic_set(&qcmd->on_heap, 1);
	uptr = command->value;//1.command->value的值可控
	qcmd->command = command;

//2.queue_idx的值,用户态可控,而且没有下标检查
//ctrl_data的值,用户态可控 而且内核可访问
	if (command->length > 0) {
		command->value =
			g_server_dev.server_queue[command->queue_idx].ctrl_data;
		if (command->length > max_control_command_size) {
			pr_err("%s: user data %d is too big (max %d)\n",
				__func__, command->length,
				max_control_command_size);
			goto ctrl_cmd_done_error;
		}
		//3.command->length用户态可控,任意地址写
		if (copy_from_user(command->value, uptr, command->length)) {
			pr_err("%s: copy_from_user failed, size=%d\n",
			__func__, sizeof(struct msm_ctrl_cmd));
			goto ctrl_cmd_done_error;
		}
	}
	msm_enqueue(&g_server_dev.server_queue
		[command->queue_idx].ctrl_q, &qcmd->list_control);
	mutex_unlock(&g_server_dev.server_queue_lock);
	return 0;

ctrl_cmd_done_error:
	mutex_unlock(&g_server_dev.server_queue_lock);
	free_qcmd(qcmd);
qcmd_alloc_fail:
	kfree(command);
command_alloc_fail:
	return -EINVAL;
}

我们已经拥有了一个任意地址写的漏洞:

此时的提权思路:

权限获取的几种方式
1.通过commit_creds(prepare_kernel_cred(0)方式。
这种漏洞方式的一般方法是通过patch ptmx_fsync,然后通过访问ptmx设备的fsync来触发。
fd = open(ptmx_device), O_WRONLY);

ret = fsync(fd);
这个的前提是我们可以获得ptmx_fync的地址。在获取不到ptmx_fync的时侯。
我们也可以通过patch相关的系统调用来实现。在本文中是利用patch settimeofday的方式,然后通过调用settimeofday函数来触发。
2.通过 patch uid、gid、capability、selinux的状态位。
这种方式是在漏洞利用不方便的时侯,随着安卓漏洞缓解技术的发展,这种方式越来越普遍。

0x04漏洞利用流程

获得root的步骤如下:
调用get_symbols_from_kernel,获取设备的地址。
通过驱动的任意写漏洞,通过patch_sys_settimeofday函数,将settimeofday的系统调用改成commit_creds(prepare_kernel_cred(0)的实现。
调用trigger_syscall_hook函数,使得获取ROOT权限的commit_creds(prepare_kernel_cred(0)代码得以运行。
fix_syscall_hook()将settimeofday的系统调用改成空实现,防止其他进程调用settimeofday而使系统崩溃。

0x05总结:

1.解包流程
得到rom包后,通过bootimg.py或者是bootimg.exe解压rom包,得到kernel。
从github中(https://github.com/fi01/kallsymsprint)下载kallsymsprint,运行以下命令得到
adb push kernel /local/tmp/kernel
adb push kallsymsprint /local/tmp/kallsymsprint
adb chmod 777 /local/tmp/kallsymsprint
adb shell . /local/tmp/kallsymsprint kernel > kallsyms.txt

https://github.com/fi01/kallsymsprint

2.编译我们自己的内核进行调试
启动模拟器
emulator -verbose -show-kernel -kernel
/Users/goldfish/arch/arm/boot/zImage -avd avd_test
exploit代码编译及运行
cd run_cve
ndk-build
adb push ./obj/local/armeabi/run_cve /data/local/tmp/
adb shell chmod 777 /data/local/tmp/run_cve

参考

https://source.codeaurora.org/quic/la/kernel/msm/tree/drivers/media/video/msm/server/msm_cam_server.c?id=384d474eeb86a507e357a7856ffd4bce4d5765c4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值