Nginx越界读取缓存漏洞(CVE-2017-7529)—— vulhub漏洞复现 005

╄→гoц情女王★ 提交于 2020-01-20 02:25:12

前言

Vulhub是一个基于docker和docker-compose的漏洞环境集合,进入对应目录并执行一条语句即可启动一个全新的漏洞环境,让漏洞复现变得更加简单,让安全研究者更加专注于漏洞原理本身

Voulhub靶机平台环境搭建和使用:

https://blog.csdn.net/qq_41832837/article/details/103948358

目录:

漏洞原理

Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件。缓存的部分存储在文件中,每个缓存文件包括“文件头”+“HTTP返回包头”+“HTTP返回包体”。如果二次请求命中了该缓存文件,则Nginx会直接将该文件中的“HTTP返回包体”返回给用户。
如果我的请求中包含Range头,Nginx将会根据我指定的start和end位置,返回指定长度的内容。而如果我构造了两个负的位置,如(-600, -9223372036854774591),将可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于“HTTP返回包体”前的“文件头”、“HTTP返回包头”等内容。当Nginx服务器使用代理缓存的情况下,攻击者通过利用该漏洞可以拿到服务器的后端真实IP或其他敏感信息。

漏洞详情

影响版本:Nginx version 0.5.6 - 1.13.2
漏洞原因:是由于对http header中range域处理不当造成。主要代码是ngx_http_range_parse函数中的循环:

for(;;) {
start = 0;
end = 0;
suffix = 0:
while (*p == '') { p++;}
if (*p !='-'){
if(*p<'0'||*p>'9'){
return NGX_HTTP_RANGE_ NOT_ SATISFIABLE;
while(*p>='0'&&*p<='9'){
if (start >= cutoff && (start > cutoff II *p - '0' > cutlim)) {
return NGX_ HTTP_ RANGE_ NOT_ SATISFIABLE;
start = start *10 + *p++ -'0';
}
while (*p == '') { p++; }
if (*p++ != '-') {
return NGX_ HTTP_ RANGE_ NOT_ SATISFIABLE ;
}
while(*p==' '){p++;}
if(*p==','|| *p=='\0'){
end = content_ length; 
goto found;
}
} else {
suffix = 1;
p++;
}
if (*p<'0'll*p>'9') {
return NGX_ HTTP RANGE NOT_ SATISFIABLE;
}
while(*p>='0'&&*p<='9'){
if (end >= cutoff && (end > cutoff II *p - '0' > cutlim)) {
return NGX_ HTTP_ RANGE_ NOT_ SATISFIABLE;
}
end=end*10+*p++-'0';
}
while(*p==' '){p++;}
if(*p!=','&&*p!='0'){
return NGX_ HTTP_ RANGE_ NOT_ SATISFIABLE;
}
if (suffix) {
start = content_ length - end;
end = content_ length - 1;
}
if (end >= content_ _length) {
end = content_ length;
} else {
end++ ;
}
found : 
if (start < end) {
range = ngx_ array_ push( &ctx- >ranges);
if (range == NULL) {
return NGX_ ERROR;
}
range- >start = start;
range- >end = end;
size += end - start;
if (ranges-- ==0) {
return NGX_ DECLINED;
}
if (*p++ != ',') {
break ;
}
}

了解到HTTP头部range域的表示方式是:bytes=<start>-<end> 范围大概是: bytes=4096-8192,字符串指针p的内容即为bytes的范围。

这段代码是要把“-”两边的数字取出分别赋值给start和end变量,标记读取文件的偏移和结束位置。

也就是说bytes=<start>-<end>这个范围内读取到的是缓存文件内容本身。假如这个缓存文件是有文件头,把start设置成负数呢?很好理解,那么它读取的位置就会往前面移动,导致文件头的信息也会被读取出来。

好啦知道原理后开始我们复现过程,在此感谢大牛们提供的poc。

漏洞复现

找到该路径下的poc.py直接利用即可

在这里插入图片描述

python ./poc.py http://192.168.232.135:8080

读取返回结果:
在这里插入图片描述
可见,越界读取到了位于“HTTP返回包体”前的“文件头”、“HTTP返回包头”等内容。
如果读取有误,请调整poc.py中的偏移地址

在这里插入图片描述

也可以用github上的另一个脚本:
https://github.com/en0f/CVE-2017-7529_PoC

在这里插入图片描述

END

每天积累一点点,终究有一天爆发出来强大的力量。我是jammny,喜欢的点个赞!加个关注吧!持续更新vulhub漏洞复现系列。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!