linux下oob_cmd命令,Linux netfilter OOB root提权漏洞分析 | CN-SEC 中文网

摘要

* 本文原创作者:肥肥草,本文属FreeBuf原创奖励计划,未经许可禁止转载

Linux netfilter OOB

* 本文原创作者:肥肥草,本文属FreeBuf原创奖励计划,未经许可禁止转载

著名的ExploitDatabase网站(www.exploit-db.com)最近贴出了一个netfilter模块的提权POC,作者是Vitaly Nikolenko。OOB!Netfilter!顿感好奇,决定分析一下,现将分析过程和成果分享如下。

0×0 依葫芦画瓢提权成功

参照文章的提示,下载Ubuntu16.04并成功安装,uname -a确认版本号为4.4.0-21-generic。

e89dd586a418936c1b55154d898c54ac.png

下载POC,编译,按照提示关闭SMEP,加载ip_tables.ko,运行decr,等到出现“Done!Nowrun.pwn”后运行pwn,成功获得root shell。

47112a5d57a9c1ab487879f912097627.png

6ef4f226cb0856437dbba33ad2625d9e.png

0×01 漏洞初识

查看pwn.c的代码,可以看出POC采用了常见的通过ptmx提权方法:

d8dc81013868a2bd864c9e859e726bf8.png

猜测decr中修改了ptmx_fops的release指针,并根据代码可推断出修改后该指针的值为0xff814e30b0。然后pwn中调用close(fd)调用ptmx_fops->release函数,从而

事实是否如此呢?

通过cat/proc/kallsyms查看ptmx_fops的地址为0xffffffff821de3e0,则release指针所在地址为0xffffffff821de3e0 + 13*8 = 0xffffffff821de448。

通过kgdb进行调试,查看在decr运行之前,0xffffffff821de448的值0xffffffff814e30b0,如下图所示:

9dbf77414e0d5f6e0da200a504da3d3f.png

行decr之后,0xffffffff821de448地址的值,为0x ff814e30b0,如下图所示:

bebfa062b4f7d7cc43f16d43ea53a68f.png

也就是说,decr运行之后,0xffffffff821de448地址的值由0xffffffff814e30b0被修改为0xff814e30b0,而0xff814e30b0地址是应用层地址,是可控的,在pwn代码中向0xff814e30b0地址写入了提权ShellCode。

下面的问题就是decr是如何做到的,内核漏洞在哪?

0×02 定位修改ptmx_fops关键指令

仔细分析decr.c,无非是设置了ipt_replace、ipt_entry等数据结构,然后调用setsockopt函数设置内核,看完之后仍然毫无头绪,还得从内核着手,看看应用层在调用完setsockopt函数之后内核到底做了那些事。

一种思路是重新编译内核,这样可以实现源码级的内核调试,但是重新编译之后一些内核参数(如ptmx_fops)地址发生改变,POC可能会运行失败,这样不利于定位修改ptmx_fops的漏洞代码。

所以还是针对Ubuntu16.04原生的内核进行调试,采用源码分析+动态调试的方法定位修改ptmx_fops的关键指令。本次采用的动态调试方法为vmware双虚拟机kgdb调试方法,具体方法可以通过

查看ip_tables.c源码,首先找到模块初始化函数ip_tables_init:

360cb668ba2972279794671a0c4238cb.png

在ip_tables_init中,调用nf_register_sockopt注册处理函数,注册参数如下所示。

291f4cc3d998471f55ace60b9dca03d7.png

set函数有两个,do_ipt_set_ctl和compat_do_ipt_set_ctl,内核会调用哪一个函数呢?

通过kgdb双虚拟机调试,分别设置两个函数为断点,发现当应用层调用setsockopt时,内核调用的是compat_do_ipt_set_ctl,如下图所示。

e375ececeedbfb305e63142b346fe44a.png

继续分析,获得如下函数执行路径:

compat_do_ipt_set_ctl--> compat_do_replace --> translate_compat_table --> check_compat_entry_size_and_hooks

POC代码中提示check_compat_entry_size_and_hooks/check_entry有问题,那么重点分析check_compat_entry_size_and_hooks函数,看是在那一步去修改了ptmx_fops,最好的办法是动态调试。

经过痛苦的、纯体力活的kgdb汇编代码调试,最终定位到是在compat_release_entry函数中修改了ptmx_fops,并且修改了两次,进一步跟踪定位到是该函数中的两个module_put函数修改了ptmx_fops。

f8284e8584b43c293d58ee6235ee63be.png

同时通过打印$rdi(module_put的第一个参数)的值,发现该值为0xffffffff821de10d,如下所示

ca29ae73b82a6d8f0bb5c8781b90058a.png

而该值正是decr.c中设置的magicnumber,如下图所示:

a1d324ca9d17fc3d6461119584c64bbd.png

再看module_put函数:

162258079a8cc59f2c76a9f5ba6d53bd.png

其中最关键的就是对modue->refcnt减一。

refcnt在structmodule结构中的偏移为0×340,因此&module->refcnt的值为 0xffffffff821de10d + 0×340 = 0xffffffff821de44d, 而ptmx_fops->tty_release的地址为0xffffffff821de448,因此当执行减一操作后,会将0xffffffff821de44d开始的0xff 0xff 0xff逐步减为0,最终ptmx_fops->tty_release的值变为0xff814e30b0。

4588aaa39604275996c707b60ad8a790.png

到此,总算搞明白了,应用层通过构造特殊的ipt_replace、ipt_entry、xt_entry_match、xt_standard_target结构,将一个值为magic number的地址传到内核,并让内核中对该地址的内容执行多次-1操作,从而达到修改ptmx_fops的目的。

0×03 漏洞成因分析

通过上节分析知道,该漏洞可以在内核中修改应用层指定的地址,执行递减1的修改操作。那么内核代码中的漏洞到底在哪呢?

继续分析内核源代码ip_tables.c,既然问题出在ematch->u.kernel.match->me和t->u.kernel.target->me上,那么转到与之相关的代码处,即compat_copy_entry_from_user函数内部的代码,重点分析以下代码:3ac1d2c537845164f53702153be838ed.png

将xt_ematch_foreach函数展开,如下:

a023705c267ab62a15ee77a9496a11e8.png

entry->elems指向的是紧跟在ipt_entry后的xt_entry_match(见如下示意图),即entry->elems= entry + sizeof(ipt_entry),而sizeof(ipt_entry) = 112字节。

630bab7844db0c415bb21ded02b45108.png

由于应用层设置的target_offset为74,导致判断语句

(pos)< (struct xt_entry_match *)((char *)(entry) + /

(entry)->target_offset); /

返回的结果为false,因此整个循环一次未能执行,也即compat_find_calc_match函数未能执行,本应在compat_find_calc_match函数中设置ematch->u.kernel.match->me的指令也未能执行。

与ematch错误处理情况类似,这段代码中,由于应用层设置的target_offset为74,导致t = compat_ipt_get_target()函数获取的target是错误的,后面尽管通过t->u.kernel.target= target;设置了target,但设置到了错误的地址,未改变真正的t->u.kernel.target值。

0×4漏洞总结

综上所属,该

该漏洞要利用内核模块的module_put函数,而Android系统一般不打开内核模块动态加载功能,因此本文介绍的

最近爆出和netfilters/getsockopt相关的漏洞不少,如CVE-2016-3134,后期将继续分析其他漏洞。

欢迎技术交流。本人QQ:16588753,root技术交流群:437812386。

* 本文原创作者:肥肥草

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值