我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1475|回复: 1

[技术讨论] Linux内核Waitid系统调用本地提权漏洞(CVE-2017-5123)的分析

[复制链接]
  • TA的每日心情

    昨天 18:16
  • 签到天数: 99 天

    [LV.6]常住居民II

    3万

    主题

    8253

    回帖

    8万

    积分

    三级逆天

    积分
    81480

    终身成就奖特殊贡献奖原创先锋奖金点子奖优秀斑竹奖宣传大使奖

    发表于 2017-11-7 09:08:32 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×
    最近在整理Linux内核漏洞利用的一些场景,比如利用系统调用漏洞、利用一些比较容易fuzz的漏洞,通过对这类场景的总结可以帮助我们快速发现0day,积累漏洞挖掘的经验。虽然这一类型的漏洞出现的频率很低但是优点也很显著,这类漏洞利用比较简单、直接。我通过查看github上Linux源代码patch日志发现CVE-2017-5123就是我要收集的目标,这类漏洞的攻击面是内核处理用户态指针出错,一般是内核没有检查用户态指针就直接使用,或者是对用户态指针检查不正确(本来是用来read的指针,却用来write)等, 一般会在access_ok、copy_from_user、copy_to_user 等几个函数使用中出现漏洞。

                                   
    登录/注册后可看大图

    著名exploit网站Exploit Database对于CVE-2017-5123的介绍
    链接地址:https://www.exploit-db.com/exploits/43029/
    漏洞针对的Linux内核版本: Linux version 4.14.0-rc4+ (fuzz@ns388631) (gcc version 7.1.1 20170621 (GCC)) #1 SMP Mon Oct 16 21:54:35 CEST 2017
    Android系统不受此漏洞影响。
    0×1 测试环境
    在virtualbox虚拟机ubuntu 14.04上测试。测试流程和视频中完全一样。
    https://asciinema.org/a/BeRNWtrX27yF28CMeflqHQT0H
    (exploit代码不是在Host系统中测试,通过qemu挂载有漏洞的kernel和filesystem 镜像测试exploit)
    0×2 漏洞原理
    漏洞出现在waitid系统调用中,因为没有检查用户态传入的指针的有效性导致用户态可以任意内核地址写漏洞。
    int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
    patch是调用access_ok检查infop参数的有效性。
    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96ca579a1ecc943b75beba58bebb0356f6cc4b51

                                   
    登录/注册后可看大图

    patch中添加了检查参数infop用户态指针是否可以写入的检测。如果infop指向无效地址, 或者内核地址空间都是非法的。
    0×3 Exploit 分析
    在github上有人提供了一份利用内核任意地址写漏洞本地提权的exploit,要执行此 exploit 必须关闭mmap_min_addr 和 SMEP 防护。
    这份exploit 比较简单,学习的重点放在如何修改的内核内存达到劫持控制流。

                                   
    登录/注册后可看大图


                                   
    登录/注册后可看大图


                                   
    登录/注册后可看大图


                                   
    登录/注册后可看大图

    首先exploit从内核符号表获取了commit_creds,prepare_kernel_cred函数的地址。 commit_creds(cred *)函数可以更新当前进程的cred凭据。prepare_kernel_cred()函数可以创建一个凭据。
    接下来申请一片内存用来存储shellcode。这里从0地址开始映射了4096 byte内存。

                                   
    登录/注册后可看大图

    这里先是向0xffffffff81f3f45a 地址写入0, 然后跳转到get_root 函数处去刷新当前进程的 凭据, 刷新凭据的代码使用通用的提权代码,如下:

                                   
    登录/注册后可看大图

    上述权限提升有效载荷会分配一个新的凭证结构(uid=0, gid=0等)并将它应用到调用进程中, 当前这个exploit就是使用的这个payload达到提权的目的。因为关闭SMEP所以免去了用rop翻转smep绕过SMEP的限制。
    最后该触发漏洞漏洞了,这里先调用waitid(1, pid,0xffffffff81f3f45a,…)修改内核地址0xffffffff81f3f45a的内容,然后调用fork函数。一般的套路是修改内核data段内一个全局结构体中的函数指针地址,然后在调用此函数指针跳转到我们的目标地址。
    内核中有很多这样的结构,比如avc_callbacks、cgroup_subsys、have_fork_callback 等等。这里作者只给了一个地址没有说明是那个函数,需要动态调试内核到这个地址查看内容才能知道使用的是哪个函数指针。
    目前受到网络影响没办法调试漏洞,暂且分析作者的调试日志,可以发现漏洞触发过程的调用栈。
    Trace:
    [blockquote]
    [ 6.371828] ? cgroup_can_fork+0×63/0xb0
    [ 6.372082] copy_process.part.55+0x115f/0x19e0
    [ 6.372328] _do_fork+0xbd/0×370
    [ 6.372454] SyS_clone+0×14/0×20
    [ 6.372560] do_syscall_64+0x4e/0×100
    [ 6.372669] entry_SYSCALL64_slow_pat[/blockquote]根据调用栈 我们就知道是修改了fork函数实现中的某个函数指针,下面继续分析源代码。

                                   
    登录/注册后可看大图


                                   
    登录/注册后可看大图

    (linux/kernel/cgroup/cgroup.c)
    cgroup_subsys结构体数组是一个全局变量伴随内核启动初始化完毕,这里调用cgroup_subsys结构体中的can_fork函数指针,所以可以猜测 0xffffffff81f3f45a地址就在 cgroup_subsys对象附近。

                                   
    登录/注册后可看大图

    再来看下waitid是如何写入0到0xffffffff81f3f45a地址。

                                   
    登录/注册后可看大图


                                   
    登录/注册后可看大图

    waitid中多处调用unsafe_put_user()向infop指针(0xffffffff81f3f45a)写入数据。
    exploit中调用完waitid紧接着调用了fork函数触发了can_fork函数跳转到0地址执行shellcode。
    漏洞分析和exploit的原理分析完毕,我在本地做了测试非常稳定的exploit,感兴趣可以看看文章开头的提权视频。
    0×4 exploit 代码说明 exploit 执行
    exploit代码执行顺序:
    1、run_kernel.sh在qemu中启动vul linux(开启靶场),从qemu 启动日志和脚本可以看到系统防护的状态(NX开启了,kaslr关闭了)
    2、setup_exploit.sh在1执行完以后,当前的终端会进入vul linux系统,此时是root 用户。此脚本会关闭mmap_min_addr限制允许exploit mmap 0地址,并输出”./exploit 0xffffffff81f3f45a”。这里要启动一个普通用户,准备提升权限。
    3、./exploit 0xffffffff81f3f45a在2中输出了这条命令,exploit是二进制程序没有源代码,可以逆向或者自己分析漏洞写exp。此exp已经具有任意内核地址写的能力。
    编译kernel & filesystem方法
    kernel和filesystem的编译方法在 kernel_compilation_cheatsheet.md文件中。
    安装软件

                                   
    登录/注册后可看大图

    0×5 测试截图:

                                   
    登录/注册后可看大图

    exploit 代码:
    https://github.com/nongiach/CVE/tree/master/CVE-2017-5123
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    887

    回帖

    450

    积分

    二级逆天

    积分
    450

    终身成就奖社区居民优秀斑竹奖

    QQ
    发表于 2017-11-29 10:25:31 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    每日签到,有金币领取。


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    ( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

    平平安安
    TOP
    快速回复 返回顶部 返回列表