Exploid:CVE-2009-1185 init未检查NETLINK消息来源,本地提权漏洞
来源:互联网 发布:淘宝卖家电话在哪里 编辑:程序博客网 时间:2024/06/06 14:16
一、背景知识
udev 是Linux kernel 2.6系列的设备管理器。它主要的功能是管理/dev目录底下的设备节点。它同时也是用来接替devfs及hotplug的功能,这意味着它要在添加/删除硬件时处理/dev目录以及所有用户空间的行为,包括加载firmware时。
udev是硬件平台无关的,属于user space的进程,它脱离驱动层的关联而建立在操作系统之上,基于这种设计实现,我们可以随时修改及删除/dev下的设备文件名称和指向,随心所欲地按照我们的愿望安排和管理设备文件系统,而完成如此灵活的功能只需要简单地修改udev的配置文件即可,无需重新启动操作系统。
对应android平台,linux上的udev模块功能赋予了vold守护程序。.具体可参考附录5。
Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能。使用netlink 进行应用与内核通信的应用很多,包括:路由 daemon(NETLINK_ROUTE),1-wire 子系统(NETLINK_W1),用户态 socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket 监视(NETLINK_INET_DIAG),netfilter 日志(NETLINK_NFLOG),ipsec 安全策略(NETLINK_XFRM),SELinux 事件通知(NETLINK_SELINUX),iSCSI 子系统(NETLINK_ISCSI),进程审计(NETLINK_AUDIT),转发信息表查询 (NETLINK_FIB_LOOKUP),netlink connector(NETLINK_CONNECTOR),netfilter 子系统(NETLINK_NETFILTER),IPv6 防火墙(NETLINK_IP6_FW),DECnet 路由信息(NETLINK_DNRTMSG),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用 netlink(NETLINK_GENERIC)。
二、漏洞原理
本漏洞编号为CVE-2009-1185,始现于linux操作系统udev模块,针对linux的poc见附录6。而针对Android系统,坊间称之为CVE-2010-EASY,具体漏洞原理描述如下:
kernel检测到硬件事件,如sd卡设备插拔等,然后广播出去,数据结构为uevent,Native层的init进程通知vold(root权限)去处理该广播信息,vold再通知JNI层的MountService,其与Java应用层交互。该关系见图1,详见附录7、8。
图1:vold架构
(init和vold的关系:init进程会解析init.rc,而init.rc中描述了vold服务,进而启动了vold进程)
vold进程应该只处理kernel发送的device的NETLINK的socket消息,但实际上并未检测NETLINK的socket消息的来源,这样攻击者可以广播add device的socket信息,触发硬件处理事件,将恶意代码传入kernel,由其写入设备文件。详细描述检附录9、11。
三、漏洞修复
对比2.3.7版本的源码,修复代码有:
1、首先在代码中设置socket参数,可以让接受者知道发送者的uid和gid:在system/core/init/device.c 的open_uevent_socket中增加了:
setsockopt(s,SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
2、然后在/system/core/init/device.c的handle_device_fd中,修订代码如下:
if ((snl.nl_groups != 1) || (snl.nl_pid != 0)) {
/* ignoring non-kernel netlink multicast message */
continue;
}
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&hdr);
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
/* no sender credentials received, ignore message */
continue;
}
struct ucred * cred = (struct ucred *)CMSG_DATA(cmsg);
if (cred->uid != 0) {
/* message from non-root user, ignore */
continue;
}
修复代码主要检查了nl_pid,通过CMSG_FIRSTHDR取得cmsg,检查cmsg->cmsg_type ,通过CMSG_DATA取得cred,检查cred->uid。从而对netlink消息的来源进行了检查,对非root用户发送的消息直接忽略,修补了漏洞。
可以发现所有修补代码都是在init目录下,按说都是init进程的代码,为什么说漏洞是vold没有检测NETLINK的socket消息的来源,而不是init进程没有检测NETLINK的socket消息的来源呢?
或者说所有的设备消息处理代码都是在init目录下的device.c中,为什么前文说是Native层的init进程通知vold(root权限)去处理该广播信息?
四、漏洞利用代码
CVE-2010-EASY poc,作者是著名的The AndroidExploid Crew,包含了Exploid.c和exploid2.c。该代码还被集成到z4root工具中。主要步骤如下:
1、初始化通过NET_LINK机制发送数据所需要的数据结构
2、获取程序的路径,为/data/local/tmp/exploid
3、改变工作目录为/data/local/tmp,(因为没有root权限,只可以在少数目录读写和执行)
4、创建NETLINK的套接字
5、当前目录创建热拔插文件hotplug,内容为/data/local/tmp/exploid
6、建立一data文件,为指向系统的hotplug的符号链接,/proc/sys/kernel/hotplug(为什么需要这样,可以参考附录9)
7、构建发送给内核的信息,内容为进行热拔插,固件位置在/data/local/tmp/hotplug(但实际发送数据为../../../data/local/tmp/hotplug,附录9中可以看到会拼接:/etc/firmware/../../../data/local/tmp/hotplug=/data/local/tmp/hotplug)。
8、Sendmsg发送该信息,将/data/local/tmp/hotplug文件中的内容(/data/local/tmp/exploid)写到了/proc/sys/kernel/hotplug中。
9、再次收到如wifi打开、usb插入等热拔插信息,内核就会以root权限加载/proc/sys/kernel/hotplug所指示的文件/data/local/tmp/exploid,从而达到提权的目的。
上述详细内容见附录10。
附录:参考资料
1、http://www.cnblogs.com/hnrainll/archive/2011/06/10/2077266.html udev详解
2、http://baike.baidu.com/link?url=6BuAcOFbER2KOEUEEuMjA69tpseiADYLBJsQHsTdLzR_iqOiZL0WIZcj8iXjtCAGLmAIFebUxQ8E0VDeKs7Vqa udev百科
3、http://www.cnblogs.com/iceocean/articles/1594195.html LINUX netlink机制
http://blog.csdn.net/zcabcd123/article/details/8275891
netlink---Linux下基于socket的内核和上层通信机制
4、http://blog.chinaunix.net/uid-27411029-id-3349524.html android启动—深入理解init进程
5、http://wenku.baidu.com/link?url=o31VINs-Q6FKUp46usW3BMBsMXWqjO1hhwWFOxzgCbzlxxEjqYtstE7X1tFp_i-mxbUY8yENu7WCNe9Df6R9mZ13UnCSnA764uk0B9NsSvW android系统vold透析
6、https://www.exploit-db.com/exploits/8478/ cve-2009-1185 linux poc
7、http://blog.chinaunix.net/uid-22935566-id-3039918.html Android Vold架构
8、http://blog.csdn.net/new_abc/article/details/7396733 android usb挂载分析----vold启动
9、http://bbs.pediy.com/showthread.php?t=139738 结合init源码剖析android root提权漏洞(CVE-2010-EASY)
10、http://bbs.pediy.com/showthread.php?t=139708 Android root源代码剖析--基于CVE - 2010 - EASY
11、http://blog.csdn.net/jackaduma/article/details/7286348 Android Root方法原理解析及Hook(二) udev漏洞
- Exploid:CVE-2009-1185 init未检查NETLINK消息来源,本地提权漏洞
- 【漏洞公告】CVE-2017-1000367:Sudo本地提权漏洞
- CVE-2017-2636【n_hdlc驱动模块 本地提权漏洞】
- CVE-2016-1240漏洞分析(Tomcat本地提权漏洞)
- CVE-2014-7911 Android本地提权漏洞分析与利用
- Tomcat曝本地提权漏洞 (CVE-2016-1240 附PoC)
- Mysql本地提权及远程代码执行漏洞浅析(CVE-2016-6662)
- Android提权漏洞CVE-2014-7920&CVE-2014-7921分析
- 安卓root漏洞分析——CVE-2009-1185
- android提权漏洞CVE-2010-EASY修复
- android提权漏洞CVE-2010-EASY修复
- zergRush (CVE-2011-3874) 提权漏洞分析
- ADB backupAgent 提权漏洞分析 (CVE-2014-7953)
- 微软“WebDAV”提权漏洞(cve-2016-0051)初探
- (CVE-2016-0728)Linux Keyring refcount 内核提权漏洞
- CVE-2015-8660 OverlayFS文件系统权限检查缺陷漏洞
- CVE-2015-8660 Overlay文件系统文件权限检查缺陷漏洞
- Linux CVE-2009-0029 漏洞解析
- #define宏中的“#”和“##”
- lightoj-1422-Halloween Costumes 区间dp
- 哈尔小波变换实例分析
- 服务器 Server installshield脚本
- HDOJ题目2196 Computer(树的直径)
- Exploid:CVE-2009-1185 init未检查NETLINK消息来源,本地提权漏洞
- VS2008到VS2010转换到 COFF 期间失败
- Android开发中EditText小技巧之如何设置光标颜色及粗细
- Android Fragment 生命周
- android 读取 AndroidManifest.xml 中的数据:版本号、应用名称、自定义K-V数据(meta-data)
- Android中多线程处理
- 改变与适应
- HDOJ Pupu 3003【快速幂】
- 队列