CVE-2017-7529 README文件
# Nginx越界读取缓存漏洞(CVE-2017-7529)
## 漏洞原理
参考阅读:
- https://cert.360.cn/detailnews.html?id=b879782fbad4a7f773b6c18490d67ac7
- http://galaxylab.org/cve-2017-7529-nginx%E6%95%B4%E6%95%B0%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件。缓存的部分存储在文件中,每个缓存文件包括“文件头”+“HTTP返回包头”+“HTTP返回包体”。如果二次请求命中了该缓存文件,则Nginx会直接将该文件中的“HTTP返回包体”返回给用户。
如果我的请求中包含Range头,Nginx将会根据我指定的start和end位置,返回指定长度的内容。而如果我构造了两个负的位置,如(-600, -9223372036854774591),将可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于“HTTP返回包体”前的“文件头”、“HTTP返回包头”等内容。
## 复现漏洞
运行测试环境:
```
docker compose up -d
```
访问`http://your-ip:8080/`,即可查看到Nginx默认页面,这个页面实际上是反向代理的8081端口的内容。
调用`python3 poc.py http://your-ip:8080/`,读取返回结果:
![](01.png)
可见,越界读取到了位于“HTTP返回包体”前的“文件头”、“HTTP返回包头”等内容。
如果读取有误,请调整poc.py中的偏移地址(605)。
insecure-configuration README文件
# Nginx 配置错误导致漏洞
## 运行测试环境
```
docker compose up -d
```
运行成功后,Nginx将会监听8080/8081/8082三个端口,分别对应三种漏洞。
## Mistake 1. CRLF注入漏洞
Nginx会将`$uri`进行解码,导致传入%0d%0a即可引入换行符,造成CRLF注入漏洞。
错误的配置文件示例(原本的目的是为了让http的请求跳转到https上):
```
location / {
return 302 https://$host$uri;
}
```
Payload: `http://your-ip:8080/%0d%0aSet-Cookie:%20a=1`,可注入Set-Cookie头。
![](5.png)
利用《[Bottle HTTP 头注入漏洞探究](https://www.leavesongs.com/PENETRATION/bottle-crlf-cve-2016-9964.html)》中的技巧,即可构造一个XSS漏洞:
![](1.png)
## Mistake 2. 目录穿越漏洞
Nginx在配置别名(Alias)的时候,如果忘记加`/`,将造成一个目录穿越漏洞。
错误的配置文件示例(原本的目的是为了让用户访问到/home/目录下的文件):
```
location /files {
alias /home/;
}
```
Payload: `http://your-ip:8081/files../` ,成功穿越到根目录:
![](2.png)
## Mistake 3. add_header被覆盖
Nginx配置文件子块(server、location、if)中的`add_header`,将会覆盖父块中的`add_header`添加的HTTP头,造成一些安全隐患。
如下列代码,整站(父块中)添加了CSP头:
```
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;
location = /test1 {
rewrite ^(.*)$ /xss.html break;
}
location = /test2 {
add_header X-Content-Type-Options nosniff;
rewrite ^(.*)$ /xss.html break;
}
```
但`/test2`的location中又添加了`X-Content-Type-Options`头,导致父块中的`add_header`全部失效:
![](3.png)
XSS可被触发:
8080这是正常访问情况
构造payload 随便设置cookie后可以看到回显带着cookie
8081一般
目录穿梭过后
8082看到location2块中的add没有显示,被替代了
容器内部
nginx_parsing_vulnerability README文件
# Nginx 解析漏洞复现
Nginx解析漏洞复现。
版本信息:
- Nginx 1.x 最新版
- PHP 7.x最新版
由此可知,该漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞。
直接执行`docker compose up -d`启动容器,无需编译。
访问`http://your-ip/uploadfiles/nginx.png`和`http://your-ip/uploadfiles/nginx.png/.php`即可查看效果。
正常显示:
![image](1.jpg)
增加`/.php`后缀,被解析成PHP文件:
![image](2.jpg)
访问`http://your-ip/index.php`可以测试上传功能,上传代码不存在漏洞,但利用解析漏洞即可getshell:
按照要求访问png和php,因为配置解析不当图片被解析成了php文件
接下来测试上传功能,应该是上传一个带后门代码的图片
这里选择上传一张图片,抓包将一句话木马添加进去,发送得到图片路径,对图片路径添加/.php就可以将图片以php解析
用webshell连接就拿到shell
CVE-2013-4547 README 文件
Nginx 文件名逻辑漏洞(CVE-2013-4547)
影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
参考链接:
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4547
- https://blog.werner.wiki/file-resolution-vulnerability-nginx/
- http://www.91ri.org/9064.html
漏洞原理
这个漏洞其实和代码执行没有太大关系,其主要原因是错误地解析了请求的URI,错误地获取到用户请求的文件名,导致出现权限绕过、代码执行的连带影响。
举个例子,比如,Nginx匹配到.php结尾的请求,就发送给fastcgi进行解析,常见的写法如下:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}
正常情况下(关闭pathinfo的情况下),只有.php后缀的文件才会被发送给fastcgi解析。
而存在CVE-2013-4547的情况下,我们请求1.gif[0x20][0x00].php
,这个URI可以匹配上正则\.php$
,可以进入这个Location块;但进入后,Nginx却错误地认为请求的文件是1.gif[0x20]
,就设置其为SCRIPT_FILENAME
的值发送给fastcgi。
fastcgi根据SCRIPT_FILENAME
的值进行解析,最后造成了解析漏洞。
所以,我们只需要上传一个空格结尾的文件,即可使PHP解析之。
再举个例子,比如很多网站限制了允许访问后台的IP:
location /admin/ {
allow 127.0.0.1;
deny all;
}
我们可以请求如下URI:/test[0x20]/../admin/index.php
,这个URI不会匹配上location后面的/admin/
,也就绕过了其中的IP验证;但最后请求的是/test[0x20]/../admin/index.php
文件,也就是/admin/index.php
,成功访问到后台。(这个前提是需要有一个目录叫“test ”:这是Linux系统的特点,如果有一个不存在的目录,则即使跳转到上一层,也会爆文件不存在的错误,Windows下没有这个限制)
漏洞复现
启动漏洞环境:
docker compose up -d
环境启动后,访问http://your-ip:8080/
即可看到一个上传页面。
这个环境是黑名单验证,我们无法上传php后缀的文件,需要利用CVE-2013-4547。我们上传一个“1.gif ”,注意后面的空格:
访问http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php
,即可发现PHP已被解析:
注意,[0x20]是空格,[0x00]是\0
,这两个字符都不需要编码
但是我这里一直测试成功不了,具体操作就是先上传一个后门代码php文件,通过bp抓包将后缀名改成gif,还要再gif后面加一个空格,然后上传得到文件路径/var/www/html/uploadfiles/文件名.gif,访问http://ip:8080/uploadfiles/文件名.gif.php,通过抓包发到repeater模块,进入hex功能,在66和2e的十六进制码中右键添加两个字节,分别为20和00,代表空格和截断符,发包后再用webshll连接,具体路径就是刚刚构造的算上空格和截断符,如果使用phpinfo效果会更直观
Comments NOTHING