nginx常见漏洞解析_nginx漏洞(1),从入门到精通

autoindex on;

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;
add_header Content-Security-Policy “default-src ‘self’”;
add_header X-Frame-Options DENY;
rewrite ^(.*)$ /xss.html break;
}
}
#3.进入docker重启nginx
[root@blackstone configuration]# docker exec -it fa2e43aabeec /bin/bash
root@fa2e43aabeec:/# nginx -s reload

再次测试的话发现text2以及无法执行script。

4.nginx解析漏洞:

严格来说,这个漏洞的出现概率约等于0,甚至让人感觉非常的刻意而为之。请看:

这二者合在一起,在网页有文件上传功能时,百分百引发文件上传漏洞。属于高危配置手法。对于这个例子可能需要大家去看看nginx解析php原理。

总结来说,漏洞成因就是同时开启路径修复和图片后缀名解析(或者直接将解析配置为空)

[root@blackstone nginx_parsing_vulnerability]# cd /root/vulhub-master/nginx/nginx_parsing_vulnerability
[root@blackstone nginx_parsing_vulnerability]# docker-compose up -d

Nginx解析漏洞:

影响版本:全版本

影响说明:命令执行,获取服务器web权限

环境说明:Nginx 1.13.0

环境搭建: 此次环境使用docker环境搭建,环境采用地址Vulhub

4.1漏洞原因:

Nginx的解析漏洞的出现和Nginx的版本没有关系,漏洞的产生是由于php配置问题导致的。出现了如下

php.ini 目录修复,如果没找到则向上一级文件查找修复,为路径修复!

cgi.fix_pathinfo=1

php-fpm.conf 开启.php后缀和.jpg后缀解析功能,或者有一个可能,他压根为off或者空,压根没写也可以解析。

security.limit_extensions = .php .jpg

路径修复****以及PHP-fpm开启了图片jpg或者gif或者压根没开什么文件都能解析的,愚蠢

当访问http://127.0.0.1/test.jpg时显示图片解析错误,当访问http://127.0.0.1/test.jpg/test.php时结果显示Access denied,这个回显很奇怪,正常访问这个链接是不存在的,正常思维应该是404,这里就需要研究下Nginx的解析流程了:Nginx在收到/test.jpg/test.php路径时,首先判断文件类型,发现后缀是.php,便交给php处理,但php想要解析该文件时,发现并不存在,便删除掉/test.php,去找test.jpg,此时test.jpg是存在的,便要尝试解析它,但无奈后缀是.jpg,不是php,便报错Access denied。 上面的流程中提到了一个点,就是删除/test.php,这是Nginx的“修理”机制,由参数cgi.fix_pathinfo决定,当值为1时,便进行“修理”。例如,文件名为/aa.jpg/bb.png/cc.php,如果cc.php不存在就找/aa.jpg/bb.png,如果还不存在就找aa.jpg,如果存在将它视为php文件。 到目前为止我们并没有成功利用解析漏洞,因为php代码并没有执行。为什么呢? 因为在PHP的配置中没有定义降.jpg文件中的php代码也解析为php,这是在security.limit_extensions中定义的。由于security.limit_extensions的引入,漏洞难以利用。

演示如下:

加一个/.php试试?

ok,就是这么简单。不过这玩意出现不太可能。

能够实现这个效果得益于愚蠢的配置。

我们可以构造一个<?php phpinfo(); system($\_GET['var']); ?>图片马,则可以完成var=whomai

5.nginx本身的漏洞

对于程序本身的漏洞我们能做的就是版本升级,时刻保持程序为最新版,才有可能把风险降到最低。对于以下漏洞的修复方案就不在赘述。

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

影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
环境位置:/nginx/CVE-2013-4547

  1. Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
  2. php-fpm.conf中的security.limit_extensions为空,也就是说任意后缀名都可以解析为PHP
5.1.1漏洞原因

Nginx版本范围较大,比较好匹配,但php-fpm.conf的security.limit_extensions配置默认为php,一般鲜有管理员允许所有类型都可以解析为PHP,所以该漏洞比较鸡肋,但这是在Linux的服务器中,而在Windows中便影响极大,这点我们后面再讲,先说下在Linux下的复现步骤。

5.1.1.1漏洞前置知识

要理解这个漏洞我们先需要了解nginx解析php的原理,放一张图:

图中的几个定义:

CGI:CGI是一种协议,它定义了Nginx或者其他Web Server传递过来的数据格式,全称是(Common Gateway Interface,CGI),CGI是一个独立的程序,独立与WebServer之外,任何语言都可以写CGI程序,例如C、Perl、Python等。
FastCGI:FastCGI是一种协议,它的前身是CGI,可以简单的理解为是优化版的CGI,拥有更够的稳定性和性能。
PHP-CGI:只是一个PHP的解释器,本身只能解析请求,返回结果,不会做进程管理。
PHP-FPM:全称FastCGI Process Manager,看名称就可以知道,PHP-FPM是FastCGI进程的管理器,但前面讲到FastCGI是协议并不是程序,所以它管理的是PHP-CGI,形成了一个类似PHP-CGI进程池的概念。
Wrapper:字母意思是包装的意思,包装的是谁呢?包装的是FastCGI,通过FastCGI接口,Wrapper接收到请求后,会生成一个新的线程调用PHP解释器来处理数据。

Nginx调用PHP的过程是比较复杂的,需要花大量的时间来学习和梳理。通过原理图和刚才的定义,我们对Nginx处理PHP请求有了大致的了解。那么,Nginx是如何知道将什么样的文件当作PHP文件处理?是在nginx.conf配置文件中的:

location ~ .php$ {
root html;
include fastcgi_params;

fastcgi_pass IP:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}

locating后边的 .php是一个正则,代表了以.php结尾的文件都必须按照括号内的命令来执行,fastcgi是一个协议,具象化理解为nginx和php之间的一个媒介一个沟通交流方式,有点想路由协议但又不全是。nginx将请求通过fastcgi发送给PHP-fpm。其中nginx和fastcgi_pass可以不在同一台服务器上,用fastcgi_pass以ip和port端口的方式进行通信功能。

5.1.1.2漏洞引发条件:

作为相应版本的程序,其在解析URL时存在一定的缺陷,我们请求wbe-php.jpg[0x20][0x00].php,这个URI可以匹配上正则.php$,可以进入这个Location块;但进入后,Nginx却错误地认为请求的文件是1.jpg[0x20],就设置其为SCRIPT_FILENAME的值发送给fastcgi。也就是说后端的php代码在处理的过程中所接受到的文件名就是web-php.jpg。

同时查看php-fpm的配置文件可以看到:

我们来看一下官方配置文件给出的建议:

[root@blackstone php-fpm]# vim /etc/php-fpm.d/www.conf

; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
#这一句是重点,在设置解析时,为空则表示允许所有的后缀解析
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5

在此漏洞的加持下,我们可以利用对nginx对截断符号的错误判断,可以轻松上传非法文件绕过php对其的检测,在加上php-fpm配置文件中的错误配置。就有可能实现上传非法的webshell或者实现RCE。

5.1.2如何实际利用:

开启靶场:docker-compose -d

这个文件上传点,看一下源码发现对其做了严格但是又不严格的限制:

<?php if (!empty($_FILES)): // Check for errors if($_FILES['file_upload']['error'] > 0){ die('An error ocurred when uploading.'); } // Check filesize if(!is_uploaded_file($_FILES['file_upload']['tmp_name'])) { die('File is not uploaded file'); } //字符过滤防御文件上传漏洞 $ext = pathinfo($_FILES['file_upload']['name'], PATHINFO_EXTENSION); if (empty($ext) || in_array($ext, ['php', 'php3', 'php5', 'phtml'])) { die('Unsupported filetype uploaded.'); } $new_name = __DIR__ . '/uploadfiles/' . $_FILES['file_upload']['name']; if(!move_uploaded_file($_FILES['file_upload']['tmp_name'], $new_name)){ die('Error uploading file - check destination is writeable.'); } die('File uploaded successfully: ' . $new_name); else: ?> File: <?php endif

但是我们可以利用cev-2013-4547来绕过。

用vscode构造一个jpg文件里边包含php的get方法。 开启环回代理使用burp抓到上传的包,如下:

找到jgp.php文件的那一行,2e代表 . 70 60 70代表php(16机制),给前边添加20 和00代表空格和阶段,类似于上边c语言的[0x20][0x00]

ps:因为php是使用c编写的,所以c的一些内容php是可以识别的

欧克改完只够go一下:

可以发现改上传成功的了jpg后边有一个空格,截断看不见~

但这只是上传,上传完之后我们访问该文件的时候需要在后缀加入php即执行攻击命令。如果在图片文件中嵌入system[$get’var’]这种后果自然而然~

5.2Nginx越界读取缓存漏洞(CVE-2017-7529)

影响版本:Nginx 0.5.6 ~ 1.13.2

影响说明:信息泄漏

环境说明:Nginx 1.13.2

环境搭建: 此次环境使用docker环境搭建,环境采用地址Vulhub

5.2.1 引发原因

Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件。缓存的部分存储在文件中,每个缓存文件包括“文件头”+“HTTP返回包头”+“HTTP返回包体”。如果二次请求命中了该缓存文件,则Nginx会直接将该文件中的“HTTP返回包体”返回给用户。

如果我的请求中包含Range头,Nginx将会根据我指定的start和end位置,返回指定长度的内容。而如果我构造了两个负的位置,如(-600, -9223372036854774591),将可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于“HTTP返回包体”前的“文件头”、“HTTP返回包头”等内容。

说实话,这样的漏洞危害几乎为0,因为缓存下来的文件通常为自己的静态文件,并不敏感。但是确实造成了用户的缓存信息泄露。值得一看。

Nginx越界读取缓存漏洞产生的原因是Nginx读取http请求时,如果包含range,那么Nginx会根据range指定的数据范围读取文件数据内容,如果该range是负数,并且读到了缓存文件,那么会返回缓存文件中的“文件头”或“HTTP返回包头”,缓存文件头可能包含IP地址的后端服务器或其他敏感信息,从而导致信息泄露。

5.2.2概念介绍:

0×1

HTTP返回包头:就是httprespons

HTTP返回包体:就是请求的具体文件,例如出来个网页资源,网页内嵌套的内容等等。

content-range是什么?

range是什么? 存在于HTTP请求头中,表示请求目标资源的部分内容,例如请求一个图片的前半部分,单位是byte,原则上从0开始,但今天介绍的是可以设置为负数。 range的典型应用场景例如:断点续传、分批请求资源。

content-range的表达方式:

Range:bytes=0-1024  表示访问第0到第1024字节;
Range:bytes=100-200,601-999,-300 表示分三块访问,分别是100到200字节,601到600字节,最后的300字节;
Range:-100 表示访问最后的100个字节

range在HTTP Response表示:

Accept-Ranges:bytes 表示接受部分资源的请求;
Content-Range: bytes START-END/SIZE  START-END表示资源的开始和结束位置,SIZE表示资源的的长度

什么是缓存?

分布式缓存介绍

当请求服务器的资源时,如果在缓存服务器中存在,则直接返回,不在访问应用服务器,可以降低应用服务器的负载。 例如网站的首页的缓存,nginx的默认缓存路径在/tmp/nginx下,例如:当请求服务器的资源时,如果在缓存服务器中存在,则直接返回,不在访问应用服务器,可以降低应用服务器的负载。 例如网站的首页的缓存,nginx的默认缓存路径在/tmp/nginx下,例如:

再次访问该页面时会首先读取该缓存内容,其他的静态资源,例如:图片、CSS、JS等都会被缓存。

5.2.3漏洞利用:

1 .现在我要读取刚才讲到的缓存文件头,他的Content-Length时612,那么我读取正常缓存文件的range是设置为

Range: bytes=0-612

使用curl工具测试下,命令如下,执行后发现,返回的内容是正常的。

curl -i http://127.0.0.1:8080 -r 0-612

  1. 接下来要读取缓存头,读取前面600个字节,也就是

range=content_length + 偏移长度
即:
range = 612 + 600
取负值为-1212

此时知道range的start是-1212,那么end呢?nginx的源码在声明start,end时用的是64位有符号整型,所以最大可表示:

-263-263-1
也就是
-9223372036854775808 到 9223372036854775807

所以只要start+end为9223372036854775807即可,故:

end = 9223372036854775808 - 1212
取负
为-9223372036854774596

执行结果为下图,可以发现读取到了缓存文件头,里面的8081端口在实际的业务场景中可能是其他的地址,这样便会造成信息泄漏。

[root@blackstone CVE-2017-7529]# python3 poc.py http://192.168.247.150:8080/

–00000000000000000002
Content-Type: text/html; charset=utf-8
Content-Range: bytes -605-611/612

A@�cb`RY�=�cr�\me"59526062-264"
KEY: http://127.0.0.1:8081/
HTTP/1.1 200 OK
Server: nginx/1.13.2
Date: Thu, 09 Feb 2023 00:27:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 612
Last-Modified: Tue, 27 Jun 2017 13:40:50 GMT
Connection: close
ETag: “59526062-264”

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
img

写在最后

在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。

需要完整版PDF学习资源私我

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。**

需要完整版PDF学习资源私我

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值