博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nginx越界读取缓存漏洞(CVE-2017-7529)
阅读量:3916 次
发布时间:2019-05-23

本文共 2332 字,大约阅读时间需要 7 分钟。

前言

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

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

漏洞原理

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上的另一个脚本:

在这里插入图片描述

END

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

转载地址:http://jpirn.baihongyu.com/

你可能感兴趣的文章
五年了,别再把务虚会开 “虚” 了
查看>>
一文看懂"async"和“await”关键词是如何简化了C#中多线程的开发过程
查看>>
每天都在支付,你真的了解信息流和资金流?
查看>>
.Net Core 自定义配置源从配置中心读取配置
查看>>
基于.NetCore3.1系列 —— 日志记录之日志配置揭秘
查看>>
设计模式之享元模式
查看>>
单例模式最佳实践
查看>>
.NET Core + Spring Cloud:服务注册与发现
查看>>
今天你内卷了吗?
查看>>
设计模式之代理模式
查看>>
在 MySQL 中使用码农很忙 IP 地址数据库
查看>>
结构型设计模式总结
查看>>
dotNET:怎样处理程序中的异常(实战篇)?
查看>>
What is 测试金字塔?
查看>>
api接口返回动态的json格式?我太难了,尝试一下 linq to json
查看>>
.Net Core HttpClient处理响应压缩
查看>>
十分钟搭建自己的私有NuGet服务器-BaGet
查看>>
efcore 新特性 SaveChanges Events
查看>>
龙芯3A5000初样顺利交付流片
查看>>
用了Dapper之后通篇还是SqlConnection,真的看不下去了
查看>>