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效果会更直观