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.6
nostromo-1.9.6/conf
nostromo-1.9.6/conf/mimes
nostromo-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中存在/../
字符串,即使是"合法"的目录回溯也不允许,比如存在以下形式的工程目录:
start-stop-daemon --stop -x /usr/local/sbin/nhttpd
停止已经运行的nhttpd,然后再启动gdb,因为需要调试的代码在子进程中,所以需要set follow-fork-mode child
,具体如下:
..
符号先被解码,然后被strstr函数检测到并返回400错误:
/../
字符串一样会被strstr函数检测,这种一刀切的暴力检测方法明显存在不合理之处。到这里,我们知道http_verify函数只是对请求头做了些解码检测的操作,如何绕过检测,看样子还得继续分析后续的代码逻辑。从开始grep搜索结果可知,http_verify函数是在main.c中被调用的,代码如下:
跟进http_header函数,函数定义同样在http.c文件中,该函数处理完成之后返回一个结构体指针:


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

strcutl函数代码详情如下:
\r
符号,结合上下文可知,如果检测到了回车符,会自动把回车符号删掉,而不影响后续字符的拼接。所以,如果在/../
中插入回车符号,不就可以绕过http.c中http_verify函数的检测而不影响语义吗?
0x03 漏洞复现
1. POC构造
根据上述的代码分析可知,可以在/../
字符串中插入回车符号绕过http_verify函数的检测,然后程序会在strcutl函数里面自动把回车符号删除恢复原本语义,构造poc如下:GET /..%0d/..%0d/..%0d/..%0d/..%0d/..%0d/etc/passwd HTTP/1.1
测试结果如下,成功读取etc/passwd文件内容
2. RCE POC分析
该漏洞最初公布的poc可以达到远程命令执行的效果,如下所示





0x04 结语
本想把这个漏洞分析透彻的,结果RCE部分应该是利用到了溢出漏洞,奈何笔者功力不够,暂不能进一步深入分析,搞的文章有点虎头蛇尾的感觉,安全的道路真是路漫漫其修远兮,待学习下相关知识,找机会再写篇文章单独分析下RCE部分详情。笔者水平有限,文章如有理解错误的地方,还请不吝赐教。References:https://git.sp0re.sh/sp0re/Nhttpd-exploits发现 | 发掘
为随时发生的网安动态发声

资讯|干货|案例|威胁|动态