0X00漏洞描述
Wget在401的情况时,会调用skip_short_body()函数
在skip_short_body()中,会对分块的编码进行strtol()函数调用,来读取每个块的长度
漏洞发生在没有对这个块的长度进行检查,如:是否为负数,在wget通过使用MIN()跳过512字节,将负数传递给fd_read(),但是fd_read接受的参数类型为INT,导致其高32位会被丢弃,进而可以控制传给fd_read()的参数
漏洞复现:
环境如下:
Ubuntu 16.04
Gdb-peda
Wget(versino:1.19.1)
Wget环境配置:
sudo apt-get install libneon27-gnutls-dev
在这一步时,遇到了一个小问题,安装报错了
解决办法:
cd /var/lib/dpkg sudo mv info info.bak sudo mkdir info sudo apt-get update
获取wget,由于网站证书过期了,所以需要加入 --no-check-certificate 参数
wget https://ftp.gnu.org/gnu/wget/wget-1.19.1.tar.gz --no-check-certificate
编译完成后查看信息
wget -V
版本位 无误
为了方便复现,加上本身能力有限,这里关掉堆栈保护技术
操作如下:
进行重新编译
可以开始搞事情了
0x01分析
跟到skip_short_body()
箭头所指的HTTP_STATUS_UNAUTHORIZED在一开始被定义为401
在payload中
由于content-type 不为warc
所以会进入下面的else分支
进一步判断keep_alive head_only然后调用skip_short-body这个问题函数
跟进一下skip_short_body函数
看看到底写了多么伟大的函数
三个参数,除了第一个是sock的描述符外,剩余的两个我并不认识(好像没啥用
先利用sock获取fd_line的指针(http相应包的指针)
Char *line = fd_read_line(fd)
然后调用strtol函数
Strtol函数的定义如下:
Long int strtol (const char * nptr ,char ** endptr ,int base);
参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换
但遇到如’0x’前置字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’的时候会使用8进制做转换。
一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('