记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

​再探CVE-2016-0728

2016-03-05 06:15

​再探CVE-2016-0728

2016-03-04 15:46:00 来源:360安全播报 作者:VulpeckerTeam
阅读:1857次 点赞(0) 收藏


分享到:

http://pic1.hackdig.com/pp/7c360a5426b1886df0a9cfdd6f6282834fbde78c2af3d3c00d2adeae39e4704f0ee128f5bc10fc4d88711664a7c58850.jpg

        By 360 Vulpecker Team  少仲

0x0  漏洞信息

https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-0728

 

0x1  漏洞描述

        cve-2016-0728是一个linux平台上的UAF漏洞.漏洞主要的原因是由于keyrings组件当中的引用计数问题导致的.它使用一个32位的无符号整数做引用计数,但是在计数器出现溢出的时候没有进行合理的处理.当对象的引用计数达到最大时会变成0,因此释放对象的内存空间.而此时程序还保留对引用对象的引用,所以形成了UAF漏洞.

 

0x2  代码分析

long join_session_keyring(const char *name)
{
    const struct cred *old;
    struct cred *new;
    struct key *keyring;
    long ret, serial;
 
    new = prepare_creds();
    if (!new)
        return -ENOMEM;
    old = current_cred();
 
    /* if no name is provided, install an anonymous keyring */
    if (!name) {
        ret = install_session_keyring_to_cred(new, NULL);
        if (ret < 0)
            goto error;
 
        serial = new->session_keyring->serial;
        ret = commit_creds(new);
        if (ret == 0)
            ret = serial;
        goto okay;
    }
 
    /* allow the user to join or create a named keyring */
    mutex_lock(&key_session_mutex);
 
    /* look for an existing keyring of this name */
    keyring = find_keyring_by_name(name, false);  //key->usage + 1
    if (PTR_ERR(keyring) == -ENOKEY) {
        /* not found - try and create a new one */
        keyring = keyring_alloc(name, old->uid, old->gid, old,
            KEY_ALLOC_IN_QUOTA, NULL);
        if (IS_ERR(keyring)) {
            ret = PTR_ERR(keyring);
            goto error2;
        }
    } else if (IS_ERR(keyring)) {
        ret = PTR_ERR(keyring);
        goto error2;
    } else if (keyring == new->session_keyring) {  //keyname == 当前cred中的key name
        ret = 0;                //直接返回,绕过key_put
        goto error2;
    }
 
    /* we've got a keyring - now to install it */
    ret = install_session_keyring_to_cred(new, keyring);
    if (ret < 0)
        goto error2;
 
    commit_creds(new);
    mutex_unlock(&key_session_mutex);
 
    ret = keyring->serial;
    key_put(keyring);
okay:
    return ret;
 
error2:
    mutex_unlock(&key_session_mutex);
error:
    abort_creds(new);
    return ret;
}

 

        通过以上代码可以得出只要进程使用当前正在使用的keyring名,程序就会跳过kref_put(keyring),造成引用计数的只增不减.由于引用计数是无符号整形,可以通过循环调用,整数溢出的方法来将它置0.

 

0x3  如何利用

        1.  造成引用计数溢出,int所能保存最大值为232  - 1.所以只要进行4294967295次循环,就可以将它清零.

        2.  释放引用计数为0的keyring对象

        3.  使用slab机制分配内核对象来覆盖之前已经释放的keyring对象

        4.  获得内核代码的执行权限.使用keyctl(KEY_REVOKE,key_name) 这个API来调用revoke().当我们覆盖keyring对象的时候,我们可以控制指向revoke()的函数指针,让其指向我们准备好的提权代码.

 

0x4  POC问题主要分析

        1.    漏洞代码所在的内核版本应该是3.8以后.但是大部分安卓5.0的设备都运行在3.4的内核版本之中.

        2.    网上的poc没有成功的原因是因为没有获得commit_creds和prepare_kernel_cred的地址,攻击者需要得到root权限,将kptrstrict标志置为0后,才能通过/proc/kallsyms来查看符号的地址.

        3.    在用户空间的提权代码则需要commit_creds(prepare_kernel_cred (0));函数将cred结构置为0,从而获取root权限.

        4.    使用ret2usr来在用户态调用提权代码需要考虑pxn的问题.在没有pxn防护的手机中可以在内核空间执行用户态代码.然而在有pxn防护的情况下,则需要考虑使用ROP来寻找内核gadget来绕过保护.

        5.    需要调用4294967295次,时间过长有可能导致shell反弹超时.所以很难利用.

        6.    出现漏洞的代码存在于linux内核中的keyring服务.但是该服务必须在内核编译时启用CONFIG_KEYS 选项.在AOSP内核的config文件中,并没有发现CONFIG_KEYS被启用.所以说android设备并没有包含漏洞相关的代码,因此就是说android设备没有被该漏洞所影响.

        7.    在安卓4.4版本以后,强制开启了SELinux的策略.SELinux减少了Linux内核的攻击面.SELinux的策略也限制了ASOP在设备上通过非授信app调用exp的权限.比如当一个app尝试去执行keyctl系统调用去创建一个keyring的对象时,系统调用会被拒绝. 开源的poc代码使用了SysV IPC (msgget) 来分配内存传递漏洞利用代码.安卓5.0的SELinux策略限制了SysV IPC因此阻止了包含利用的代码.

 

0x5  实测

        1.  首先去掉get_symbol的函数,root掉手机以后,直接将kptrstrict置为0,读取kallsyms的全部信息.获取相关符号地址

http://p7.qhimg.com/t01fbc44f2f19545d73.jpg

        2.  arm版的通过使用syscall来取代keyctl调用.

        3.  通过添加一个计算来显示循环的百分比

http://p2.qhimg.com/t01a1d4755039998be6.png

        在我的设备上测试的时间为12:00 – 16:46 ,进度显示为0.1%.

http://p6.qhimg.com/t01ecb731b5d3f0f94a.png

        所以大约要执行166天左右才能跑完…

参考文章:

http://bobao.360.cn/learning/detail/2576.html

https://www.mulliner.org/blog/blosxom.cgi/security/CVE-2016-0728_vs_android.html

https://github.com/nardholio/cve-2016-072

本文由 360安全播报 原创发布,如需转载请注明来源及本文地址。
本文地址:http://www.hackdig.com/03/hack-32750.htm

知识来源: bobao.360.cn/learning/detail/2780.html

阅读:91298 | 评论:0 | 标签:无

想收藏或者和大家分享这篇好文章→复制链接地址

“​再探CVE-2016-0728”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

关注公众号hackdig,学习最新黑客技术

推广

工具

标签云