Nginx 解析漏洞

0x01 漏洞原理

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

这里我们先上传一句话木马 webshell.jpg,然后构造 http://your-ip/uploadfiles/webshell.jpg/1.php 去访问它,发现其被当作 PHP 文件解析。

这是由于 Nginx 把以 .php 结尾的文件交给 fastcgi 处理,但 fastcgi 处理的时候发现并没有这个文件,于是 fastcgi 会继续向上查找,然后找到了上级文件 .jpg,于是就把 .jpg 当作 PHP 文件处理,导致漏洞产生。

问题一:为什么 fastcgi 会向上查找?
这是因为 PHP 配置文件 php.ini 中 cgi.fix_pathinfo=1,这项配置用于修复路径,如果当前路径不存在则采用上层路径。

问题二:为什么 fastcgi 会把 jpg 文件当作 PHP 文件解析?
这是因为 php-fpm.conf 的配置项 security.limit_extensions 限制了 fastcgi 解析文件的类型。此项设置为空时,fastcgi 会将 jpg 等文件当做 PHP 代码解析。

0x02 漏洞环境

# cd vulhub/nginx/nginx_parsing_vulnerability/
# docker-compose up -d
# docker-compose ps

               Name                              Command               State                    Ports                  
-----------------------------------------------------------------------------------------------------------------------
nginx_parsing_vulnerability_nginx_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
nginx_parsing_vulnerability_php_1     docker-php-entrypoint /bin ...   Up      9000/tcp                                

0x03 漏洞复现

分析文件上传页面 index.php 源码

发现其使用了 getimagesize 函数检查所上传的文件是否为图片,并且检查 MIME 类型,然后再白名单检查后缀名,最后重命名后上传。
那么我们就不能上传由 webshell.php 直接改名 webshell.jpg 的文件,而是应该上传图片马才行。

# cat /root/vulhub/nginx/nginx_parsing_vulnety/www/index.php
<?php

if (!empty($_FILES)):

// Check for errors
if($_FILES['file_upload']['error'] > 0){
    die('An error ocurred when uploading.');
}

if(!getimagesize($_FILES['file_upload']['tmp_name'])){
    die('Please ensure you are uploading an image.');
}

// Check filetype
if(stripos($_FILES['file_upload']['type'], 'image/') !== 0){
    die('Unsupported filetype uploaded.');
}

// Check filesize
if($_FILES['file_upload']['size'] > 500000){
    die('File uploaded exceeds maximum upload size.');
}

// 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 (!in_array($ext, ['gif', 'png', 'jpg', 'jpeg'])) {
    die('Unsupported filetype uploaded.');
}


$new_name = __DIR__ . '/uploadfiles/' . md5($_FILES['file_upload']['name']) . ".{$ext}";
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:
?>
<form method="post" enctype="multipart/form-data">
    File: <input type="file" name="file_upload">
    <input type="submit">
</form>
<?php
endif;

成功上传图片马 webshell.jpg,页面返回了上传路径。
在这里插入图片描述

构造 http://192.168.1.103/uploadfiles/85bb6e49a1be4be02eefb660f9d8cf68.jpg/1.php 去访问它,发现其被当作 PHP 文件解析。
在这里插入图片描述

0x04 漏洞修复

1、 将 php.ini 文件中的配置项 cgi.fix_pathinfo 的值设置为 0,这样 PHP 解析 webshell.jpg/1.php 这样的目录时,只要 1.php 不存在就会显示404页面。

2、将 php-fpm.conf 中的 security.limit_extensions 后面的值设置为 .php,限制 fastcgi 解析文件的类型仅为 .php,无法解析其他类型。
在这里插入图片描述
重启环境

# docker-compose restart

重新访问 http://192.168.1.103/uploadfiles/85bb6e49a1be4be02eefb660f9d8cf68.jpg/1.php,发现提示拒绝访问,漏洞被修复。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值