Nginx漏洞—解析漏洞、配置不当和(CVE-2013-4547)

Nginx是一款轻量级的web服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器。

一、目录跨越及代码执行漏洞(CVE-2013-4547)

CVE-2013-4547则是Nginx目录跨越及代码执行漏洞,也被称为是文件名逻辑漏洞。

涉及版本:Nginx 0.8.41~1.4.3 / 1.5.0<=1.5.7

漏洞原理

这个漏洞虽然也被称为代码执行漏洞,但跟代码执行没有太大关系,主要是由于非法的字符空格和截止符(\0)导致Nginx解析URI时的有限状态机混乱,攻击者通过一个非编码的空格绕过后缀名限制,导致出现权限绕过,代码执行等影响。
payload如下:

http://127.0.0.1/test.jpg \0.php

在存在CVE-2013-4547的状态下,我们构造payload如上,请求的是test.jpg \0.php,在Nginx解析URI时,由于文件名后面的字符串为.php,而.会被当做URI扩展名的分隔符,所以Nginx认为是此次处理是.php,就会通过配置传给fastcgi处理,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;
}

fastcgi在查找文件“test.jpg \0.php”时被\0截断,所以找到的文件为“test.jpg ”文件,将其当做php文件进行解析,造成了解析漏洞。

漏洞复现

测试环境:vulhub靶场(具体搭建请看上一篇文章)

启动漏洞环境

docker-compose up -d

访问环境

http://you-ip:8080/

开始测试:
上传页面如下:
在这里插入图片描述
由于该上传环境环境是黑名单验证,我们无法上传php后缀的文件,需要利用CVE-2013-4547。所以首先创建一个含有php代码的jpg文件,php代码为:

<?php
phpinfo();
?>

将文件名改为“test2.jpg ”并上传!(注意jpg后面的空格
界面提示上传成功。
在这里插入图片描述
尝试去该路径下访问“test2.jpg ”文件,界面报404错误。
在这里插入图片描述
上传的文件找不到,是因为浏览器自动将空格编码为%20,服务器中找不到名为“test2.jpg%20”的文件。
接下来,我们想要上传的jpg文件作为php解析,就需要利用未编码的空格和截止符(\0)进行构造,构造请求如下:

http://ip:8080/uploadfiles/test2.jpgAAAphp

发送请求并使用burpsuite抓包。使用burpsuite将AAA分别更改为20(空格)、00(截止符\0)和2e(分隔符号.)。
在这里插入图片描述
这样我们发送的请求就变为:

http://you-ip:8080/uploadfiles/test2.jpg[0x20][0x00].php

Nginx解析后,将“test2.jpg ”文件当做php文件解析。
在这里插入图片描述

二、Nginx配置不当漏洞(CRLF和目录穿越)

1、CRLF注入漏洞

漏洞原理

CRLF是回车换行(\r\n)的简称,其十六进制的编码分别为0x0b和0x0a。在http协议中,http消息头以明文的字符串格式传送,以冒号分隔的键/值对,如:Accept-Charset: utf-8,每一个消息头以回车符(CR)和换行符(LF)结尾。而在http消息头结束后,会使用两个连续的CR-LF来进行标识,用来分隔http 消息头 和 http 消息体(请求或响应的内容)。

Nginx中错误的配置文件示例(原本的目的是为了让http的请求跳转到https上):

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

该漏洞是由于Nginx将$uri进行解码,导致传入%0d%0a即可引入换行符,造成CRLF注入。

漏洞利用

启动容器并查看端口映射:
在这里插入图片描述
正常发送请求:
在这里插入图片描述
页面响应包如下:
在这里插入图片描述
接下来开始漏洞利用:

(1)会话固定

构造payload:

http://127.0.0.1:8080/%0d%0aSet-Cookie:%20session=hacker

发送请求:
在这里插入图片描述
页面响应包:
在这里插入图片描述
可以从响应包中看出,我们利用该漏洞成功了控制了cookie。

(2)反射型XSS

构造payload:

http://127.0.0.1:8080/%0d%0a%0d%0a<img src=1 onerror=alert(/xss/)>

发送请求:
在这里插入图片描述
页面响应包:
在这里插入图片描述
我们可以看到响应包中,标签已经插入页面中,但是由于浏览器的Filter是浏览器应对一些反射型XSS做的保护策略,当url中含有XSS相关特征的时候就会过滤掉不显示在页面中,所以不能触发XSS。
离别歌在其这篇文章中介绍到可以将数据包中http头的X-XSS-Protection设为0,浏览器就不会开启filter。(当然此处还是利用CRLF注入)
但我试了并不行,不知道为啥(╥╯^╰╥)

漏洞修复

Nginx获取用户请求路径时,有三个可以表示uri的变量:

  • $uri:表示解码以后的请求路径(不带参数)

  • $document_uri:表示解码以后的请求路径(不带参数)

  • $request_uri:表示完整的uri,没有解码

所以修复该漏洞,我们需要将配置文件改为:

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

2、目录穿越漏洞

漏洞原理

Nginx在配置别名(Alias)的时候,如果忘记在file后加’/’,将造成一个目录穿越漏洞。
错误的配置文件示例(原本的目的是为了让用户访问到/home/目录下的文件):

location /files {
	alias /home/;
}
漏洞利用

访问files目录:
在这里插入图片描述
目录穿越到根目录:
在这里插入图片描述

漏洞修复

将/加在files后:

location /files/ {
	alias /home/;
}

三、Nginx解析漏洞

1、配置错误导致的解析漏洞

Nginx解析漏洞是由于Nginx中php配置不当而造成的,与Nginx版本无关,但在高版本的php中,由于“security.limit_extensions”的引入,使得该漏洞难以被成功利用。

漏洞原理

当用户请求的url后缀为123.jpg/123.php时,location对请求进行选择的时候会使用URI环境变量进行选择,其中传递到后端Fastcgi的关键变量SCRIPT_FILENAME由Nginx生成的$fastcgi_script_name决定。

location ~ \.php$ {
		fastcgi_index index.php;

		include fastcgi_params;

		fastcgi_param  REDIRECT_STATUS    200;
		fastcgi_param  SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
		fastcgi_param  DOCUMENT_ROOT /var/www/html;
		fastcgi_pass php:9000;
	}

而为了较好的支持PATH_INFO的提取,在PHP的配置选项里存在cgi.fix_pathinfo选项,其目的是为了从SCRIPT_FILENAME里取出真正的脚本名。
一般情况下cgi.fix_pathinfo的值默认为1,也就是开启,从而引发该漏洞。当Nginx遇到文件路径“123.jpg/123.php”时,由于其后缀为.php文件,所以会被传到上述所示代码中,在查找文件时,若“123.jpg/123.php”不存在,则会去掉最后的“123.php”,然后判断“123.jpg”是否存在,若存在,则把“123.jpg”当做php解析。

漏洞复现

在这里插入图片描述
这是一个文件上传页面,我们先写一个phpinfo函数,将其保存为test1.jpg,上传该文件,页面响应如下:
在这里插入图片描述
于是我们查看一下后台是如何过滤的。后台部分代码如下:
在这里插入图片描述
发现在后台代码中,存在getimagesize()函数来检测文件信息,所以用burpsuite添加一些信息绕过,添加信息如下:

GIF89a
(...some binary data for image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)

抓包更改后,文件被重命名,并上传成功!
在这里插入图片描述
接下来我们去尝试访问该文件,文件打不开
在这里插入图片描述
根据文件解析漏洞,我们构造payload格式如下:

http://ip/重命名.jpg/.php

运行后phpinfo()函数执行:
在这里插入图片描述
当然也可以构造成下面这样:

http://ip/重命名.jpg/重命名.php

在这里插入图片描述
效果和原理是一样的。

漏洞修复

(1)修改php.ini,设置

cgi.fix_pathinfo = 0

(2)在nginx的配置文件添加

if ( $fastcgi_script_name ~ ..*/.*php ) {
return 403;
}

(3)前两种方法可能会导致一些伪静态网页或者特殊的路径无法显示。第三种方法将以下代码写在fcgi.conf文件中,(参考:https://www.cnblogs.com/dami520/archive/2012/08/22/2651113.html)

if ($request_filename ~* (.*).php) {
    set $php_url $1;
}
if (!-e $php_url.php) {
    return 403;
}

2、%00截断

影响版本:
nginx 0.5.*
nginx 0.6.*
nginx 0.7 <= 0.7.65
nginx 0.8 <= 0.8.37

漏洞原理

一般的利用方式如下,发送的请求为:

http://127.0.0.1/test1.jpg.php

使用burpsuite抓包,对后缀进行更改,更改为后上传:

http://127.0.0.1/test1.jpg%00.php

在url中加%00会被url解码为\0,由于Nginx是由c语言写的,在c语言中,\0就是终止符,所以文件系统读取时,会认为文件名已经结束了,读取的就是test1.jpg,从而绕过检测。

漏洞修复

升级Nginx版本

四、整数溢出漏洞(CVE-2017-7529)

这个漏洞级别太低,参考以下文章即可:
https://cert.360.cn/warning/detail?id=b879782fbad4a7f773b6c18490d67ac7
http://galaxylab.org/cve-2017-7529-nginx整数溢出漏洞分析/

猜你喜欢

转载自blog.csdn.net/m0_37711941/article/details/88222605