专栏名称: 国舜股份
移动互联网时代的综合性网络安全解决方案供应商。专业的安全产品,专业的安全服务团队,全面的安全服务资质,安全不变,国舜同行。
目录
相关文章推荐
中科院物理所  ·  原子核的利用 ·  15 小时前  
中科院物理所  ·  “政和八闽鸟”,改写鸟类演化历史 ·  15 小时前  
中科院物理所  ·  申公...公...豹一家的真身是什么动物? ·  15 小时前  
环球物理  ·  【数字的魅力】数学中最重要的8个常数 ·  2 天前  
环球物理  ·  【物理笔记】高中物理学霸笔记 ·  3 天前  
51好读  ›  专栏  ›  国舜股份

利用目录遍历漏洞实现RCE(CVE-2019-16278漏洞分析,附GDB调试过程)

国舜股份  · 公众号  ·  · 2019-10-23 14:01

正文

0x00 前言

前几天有大佬放出了CVE-2019-16278和CVE-2019-16279的payload,16278可以利用跨目录遍历漏洞造成RCE(Remote Command Execute),16279可以实现DOS攻击。漏洞影响Nostromo webserver 1.9.6及以下所有版本,因为这是一个小众Web服务器,网络上的资料较少,笔者在搭建环境的过程中踩了不少坑,导致分析漏洞的时间周期较长,下面我们一起来看看这个利用跨目录遍历实现RCE的"神奇漏洞"。

0x01 影响版本

nhttpd: version <= 1.9.6 ,最近一次更新是16年,目测已流产。

0x02 漏洞分析

1. 环境搭建

在官方下载nostromo-1.9.6.tar.gz,使用tar命令解压:
root@Memory:~$ tar xvzf nostromo-1.9.6.tar.gz
nostromo-1.9.6nostromo-1.9.6/confnostromo-1.9.6/conf/mimesnostromo-1.9.6/conf/nhttpd.conf-dist......SNIP......
修改Makefile文件,添加 -g 参数并删除 strip 命令,编译debug版本支持GDB调试:

make命令编译

root@Memory:~/nostromo-1.9.6# make......SNIP......make[2]: Entering directory `/root/nostromo-1.9.6/src/nhttpd'cc -O2 -pipe -Wall -Wstrict-prototypes -c -g main.c......SNIP......make[2]: Leaving directory `/root/nostromo-1.9.6/src/tools'make[1]: Leaving directory `/root/nostromo-1.9.6/src'

make install安装

root@Memory:~/nostromo-1.9.6# make installinstall -c -o root -g bin -m 555 src/nhttpd/nhttpd \        /usr/local/sbin/nhttpd......SNIP......install -c -o root -g bin -m 644 icons/file.gif \        /var/




    
nostromo/icons/file.gif
readelf查看nhttpd可执行文件的section header,存在debug节说明可以GDB调试

配置nhttpd.conf,注意user不能是root

修改logs目录权限

启动nhttpd,8080端口开启说明服务器配置启动成功

2. GDB动态调试

从公布的漏洞详情可知,造成漏洞的原因是http_verify函数对路径校验不严导致的。先 make clean 清理一下编译过程中产生的目标文件,然后grep搜索http_verify函数所在的源码文件,从搜索结果可知,main函数里面调用了http_verify,代码实现在http.c文件中:

打开http.c文件,http_verify函数描述及部分关键代码如下

/* * http_verify() *  verify if incoming header is valid * Return: *  0 = invalid header, 1 = valid header */inthttp_verify(char *header, const int header_size, const char *cip, const int sfd,    const int hr){    int     r, proto;    char        *h, *b, line[1024], protocol[16];    time_t      tnow;    struct tm   *t;
r = proto = 0;
/* check if header URI needs to be decoded */ if (http_decode_header_uri(header, header_size) == -1) { h = http_head(http_s_400, "-", cip, 0); b = http_body(http_s_400, "", h, 0); ......SNIP...... return (0); }
......SNIP......
/* check for valid uri */ if (strstr(header, "/../") != NULL) { h = http_head(http_s_400, line, cip, 0); b = http_body(http_s_400, "", h, 0); ......SNIP...... return (0); } ......SNIP......}
分析代码,首先调用http_decode_header_uri函数对请求中URL编码的字符进行解码,然后使用strstr函数检测hader字符串中是否包含 /../ 字符串,如果包含就直接返回400错误。从代码逻辑可知,这里strstr检测方法有点暴力,它不允许header中存在 /../ 字符串,即使是"合法"的目录回溯也不允许,比如存在以下形式的工程目录:

先进入test目录,然后回溯访问首页index.html,这类合法的请求也会报400错误,如下:
具体GDB动态调试看一看,先使用命令 start-stop-daemon --stop -x /usr/local/sbin/nhttpd 停止已经运行的nhttpd,然后再启动gdb,因为需要调试的代码在子进程中,所以需要 set follow-fork-mode child ,具体如下:
重放数据包,程序自动停止在http_verify函数,调试过程如下,可以看见被url编码的 .. 符号先被解码,然后被strstr函数检测到并返回400错误:
从调试结果可知,header变量代表的是整个http请求头,假如请求头中的其他属性携带有 /../ 字符串一样会被strstr函数检测,这种一刀切的暴力检测方法明显存在不合理之处。
到这里,我们知道http_verify函数只是对请求头做了些解码检测的操作,如何绕过检测,看样子还得继续分析后续的代码逻辑。从开始grep搜索结果可知,http_verify函数是在main.c中被调用的,代码如下:

如果发送的是一个正常http请求,根据http_verify函数检测逻辑可知,如果验证全部通过,则返回1,所以1570行的if判断结果为true,接着进入http_proc函数,该函数定义也在http.c文件中,部分代码如下:

分析代码,关键代码是290行if语句中的http_header函数,根据注释可知该函数主要是对请求头进行解析,从296行代码开始就是处理response了。
跟进http_header函数,函数定义同样在http.c文件中,该函数处理完成之后返回一个结构体指针:

搜索结构体定义,在extern.h文件中,有兴趣的朋友可以自己看看,这里就不贴出来了:
继续分析http_header函数,先初始化header结构体,初始化完成以后开始解析request,具体代码如下:

下个断点,调试看看变量的具体值:

根据调试结果可知,1500行的strcutl函数先把请求头中的接口协议等信息解析出来放在line变量中,然后在1502行把接口赋值给header结构体的rq_uri成员。接口解析的主要逻辑在strcutl函数里面,搜索下函数定义,结果如下:

strcutl函数代码详情如下:


简单分析下代码,可知该函数主要是通过换行符( LF,ASCII转义字符\n ) 为特征来截取request中的第一行数据(接口、协议)






请到「今天看啥」查看全文


推荐文章
中科院物理所  ·  原子核的利用
15 小时前
中科院物理所  ·  “政和八闽鸟”,改写鸟类演化历史
15 小时前
中科院物理所  ·  申公...公...豹一家的真身是什么动物?
15 小时前
环球物理  ·  【物理笔记】高中物理学霸笔记
3 天前
槽边往事  ·  再见,科恩
8 年前
禅茶一味  ·  总想活给别人看,不累才怪呢!
8 年前