CVE-2013-4547-nginx文件名逻辑漏洞
漏洞原理
这个漏洞其实和代码执行没有太大关系,其主要原因是错误地解析了请求的URI,错误地获取到用户请求的文件名,导致出现权限绕过、代码执行的连带影响。
我们请求1.gif[0x20][0x00].php
,这个URI可以匹配上正则\.php$
,可以进入这个Location块;但进入后,Nginx却错误地认为请求的文件是1.gif[0x20]
,就设置其为SCRIPT_FILENAME
的值发送给fastcgi。fastcgi根据SCRIPT_FILENAME
的值进行解析,最后造成了解析漏洞。
环境搭建
启动漏洞环境:
1 | docker-compose up -d |
环境启动后,访问http://your-ip:8080/
即可看到一个上传页面。
漏洞复现过程
这个环境是黑名单验证,我们无法上传php后缀的文件,先创建一个test.png
1 | GIF98A |
上传抓包修改,后缀加上一个空格
上传成功,成功显示文件路径
%00截断解析php文件,访问路径
http://your-ip:8080/uploadfiles/test.pngaaaphp
抓包修改hex,将61 61 61修改为20 00 2e,然后放包
回显phpinfo
CVE-2017-7529 NGINX越界读取缓存漏洞-nginx整数溢出漏洞
漏洞原理:
在nginx作为反向代理服务器,且开启了缓存时,攻击者可以构造恶意的range域,来获取相应的服务器中的缓存文件头部信息,导致敏感的服务器信息泄露
影响版本:0.5.6-1.13.2
漏洞危害:敏感信息泄露
在header中range的解析过程
在ngx_http_range_parse
函数中有这样一个循环, 这段代码是要把“-”
两边的数字取出分别赋值给start
和end
变量,字符串指针p
中即为bytes=
后面的内容
1 | //部分源码如下 |
在该段代码中存在cutoff
和cutlim
阈值限定了从字符串中读取时不会让start
或end
为负值, 所以这里需要进入suffix = 1
的分支,因此使用Range:bytes=-xxx
,(-end
的格式)即省略初始start
值的形式,由此可以绕过*p != '-'
的限制,进入suffix=1
的分支。
1 | if (suffix) |
start
等于content_length
减去end
值,所以如果传入的end
比实际长度还要长,就可以使start
变为负数。其中content_length
为不包含文件头的文件长度。最终end
的值会被设定为content_length - 1
(因此我们需要构造一个小包)
1 | if (start < end) |
start
相当于分片区间的头指针,end
相当于分片区间的尾指针。如果此时end
值要比文件长度(content_length
)数值大的话,就可以将start
解析为负值。与Range
相关的还有一个size
值,它是每段Range
相加后的总长度
1 | if (size > content_length) |
当size
(即所有range
相加的总长度)超过文件长度content_length
时,会返回默认的NGX_DELINED
。
注意到此处有一个退出条件:
1 | if (*p++ != ',') |
支持支持range
的值为start1-end1,start2-end2……
的形式。
因此,可以构造range:bytes=-x,-y
。一大一小两个end
值,只需要 控制前面一个end
值小而后一个end
值大,从而实现start
值和size
值皆为负数,控制start
值负到一个合适的位置,那么就能成功读到缓存文件头部了。
环境搭建
启动漏洞环境:
1 | docker-compose up -d |
访问http://your-ip:8080/
,即可查看到Nginx默认页面,这个页面实际上是反向代理的8081端口的内容。
漏洞复现过程
调用python3 poc.py http://your-ip:8080/
,读取返回结果:
Nginx 配置错误导致漏洞
环境搭建
启动漏洞环境:
1 | docker-compose up -d |
运行成功后,Nginx将会监听8080/8081/8082三个端口,分别对应三种漏洞。
CRLF注入漏洞
漏洞原理
CRLF是“回车 + 换行”(\r\n)
的简称。在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF(使用payload %0a%0d%0a%0d
进行测试)来取出HTTP内容并显示出来。所以,一旦我们能够控制HTTP消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie([http://www.xx.com%0a%0d%0a%0dSet-cookie:JSPSESSID%3Dxxx)或者HTML代码(http://www.xx.com/?url=%0a%0d%0a%0d](https://www.freebuf.com/articles/web/265135.html?url= )<img src=1 onerror=alert("xss")>)
,所以CRLF Injection
又叫HTTP Response Splitting
,简称HRS。
Nginx会将$uri
进行解码,导致传入%0a%0d即可引入换行符,造成CRLF注入漏洞。
错误的配置文件示例(原本的目的是为了让http的请求跳转到https上):
Payload: http://your-ip:8080/%0a%0dSet-Cookie:%20a=1
也可以利用这个漏洞进行xss
目录穿越漏洞
Nginx在配置别名(Alias)的时候,如果忘记加/
,将造成一个目录穿越漏洞。
错误的配置文件示例(原本的目的是为了让用户访问到/home/目录下的文件):
1 | location /files { |
Payload:http://your-ip:8081/files../
,成功穿越到根目录:
add_header被覆盖
Nginx配置文件子块(server、location、if)中的add_header
,将会覆盖父块中的add_header
添加的HTTP头,造成一些安全隐患。
文件解析漏洞
漏洞描述
该漏洞与nginx、php版本无关,属于用户配置不当造成的解析漏洞。由于nginx.conf的如下配置导致nginx把以’.php’结尾的文件交给fastcgi处理,对于任意文件名,在后面添加/xxx.php(xxx)为任意字符后,即可将文件作为php解析。
环境搭建
启动漏洞环境:
1 | docker-compose up -d |
环境启动后,访问http://your-ip/
即可看到一个上传页面。
漏洞复现过程
上传一个test.png