欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

CVE-2016-8655内核竞争条件漏洞调试分析

来源:本站整理 作者:佚名 时间:2016-12-20 TAG: 我要投稿

12月5日,hilipPettersson公布了一枚已存在Linux kernel长达5年的本地提权漏洞,几乎影响所有Linux主流发行版本,一时风头无二,绝不亚于前段时间的“Dirty Cow”。对于这个黑魔法漏洞,只有走进源码才不会管中窥豹,正是源于好奇,于是开始了整个漏洞的调试和分析。
漏洞调试是乏味的,建议大家在调试的过程中,保持心静,捋清步骤,逐渐展开。
感谢cyg07的敦促和指导!
漏洞技术分析
1、漏洞描述
漏洞作者:hilipPettersson(philip.pettersson@gmail.com)
漏洞危害:低权限用户提权到root
影响范围:Linuxkernel version
修复方案:Linuxkernel升级到最新版本(>=4.8.13)
官方补丁:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=84ac7260236a49c79eede91617700174c2c19b0cLinuxkernel(net/packet/af_packet.c)代码中存在条件竞争,可造成低权限用户提权到root。漏洞利用要创建原始套接字,需具备CAP_NET_RAW能力。 然而在某些特定的Linux发行版本(Ubuntu、Fedora)允许非特权用户创建的网络命名空间具备该能力,可成功利用。
2、漏洞成因
 packet_set_ring函数在创建ringbuffer的时候,如果packet版本为TPACKET_V3,则会初始化struct timer_list,如下图所示。packet_set_ring函数返回之前,其他线程可调用setsockopt函数将packet版本设定为TPACKET_V1。前面初始化的timer未在内核队列中被注销,timer过期时触发struct timer_list中回调函数的执行,形成UAF漏洞。
switch(po->tp_version){
case TPACKET_V3:
/* Transmit path isnot supported. We checked
* it above but justbeing paranoid
*/
if(!tx_ring)
init_prb_bdqc(po, rb, pg_vec, req_u);
         break;
         default:
         break;
}
当套接字关闭,packet_set_ring函数会再次被调用,如果packet的版本大于TPACKET_V2,内核会在队列中注销掉先前的这个定时器,如下图所示。
if(closing &&(po->tp_version > TPACKET_V2)){
         /* Because we don't support block-based V3 on tx-ring */
         if(!tx_ring)
                   prb_shutdown_retire_blk_timer(po, rb_queue);
}
但是packet版本被更改为TPACKET_V1后,原本的执行流程就发生了改变,使得 prb_shutdown_retire_blk_timer()函数不被执行,timer结构体也没有在内核的队列中被注销,一旦timer过期,内核就会执行相应的处理函数。timer的类型是struct timer_list,定义如下:
struct timer_list {
         /*     * All fields that change during normal runtimegrouped to the
          * same cacheline  */
         struct hlist_node        entry;
         unsignedlong             expires;
         void                    (*function)(unsignedlong);
         unsignedlong             data;
         u32                     flags;
         int                       slack;
#ifdefCONFIG_TIMER_STATS
         int                       start_pid;
         void                    *start_site;
         char                    start_comm[16];
#endif
#ifdefCONFIG_LOCKDEP
         struct lockdep_maplockdep_map;
#endif
};
3、漏洞利用
漏洞利用的本质是通过触发竞态,使得内核不注销socket内部的timer,然后使用内存喷射的方法覆盖timer未释放前的内核空间,将timer内部的函数替换成想要执行的函数,一旦timer时间过期,内核就会执行timer的过期处理函数,实际就是替换后的函数,从而达到漏洞利用的目的。触发竞态的代码如下:
void*vers_switcher(void*arg)
{
    int val,x,y;
    while(barrier){}
    while(1){
        val = TPACKET_V1;
        x = setsockopt(sfd, SOL_PACKET, PACKET_VERSION,&val,sizeof(val));

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载