first commit
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
This commit is contained in:
BIN
nginx/nginx_parsing_vulnerability/1.jpg
Normal file
BIN
nginx/nginx_parsing_vulnerability/1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
nginx/nginx_parsing_vulnerability/2.jpg
Normal file
BIN
nginx/nginx_parsing_vulnerability/2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
BIN
nginx/nginx_parsing_vulnerability/3.jpg
Normal file
BIN
nginx/nginx_parsing_vulnerability/3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 156 KiB |
BIN
nginx/nginx_parsing_vulnerability/4.jpg
Normal file
BIN
nginx/nginx_parsing_vulnerability/4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
63
nginx/nginx_parsing_vulnerability/README.md
Normal file
63
nginx/nginx_parsing_vulnerability/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Nginx Parsing Vulnerability
|
||||
|
||||
[中文版本(Chinese version)](README.zh-cn.md)
|
||||
|
||||
Nginx is a web server that can be used as a reverse proxy, load balancer, mail proxy, and HTTP cache. This environment contains a parsing vulnerability caused by improper user configuration.
|
||||
|
||||
Version information:
|
||||
|
||||
- Latest version of Nginx 1.x
|
||||
- Latest version of PHP 7.1.x
|
||||
|
||||
This indicates that the vulnerability is not related to specific Nginx or PHP versions, but rather is caused by improper user configuration leading to parsing vulnerabilities.
|
||||
|
||||
The vulnerability exists because of how Nginx handles file extensions in its configuration. When a request is made to a file with multiple extensions (like `file.jpg.php`), Nginx may process it based on the last extension, even if the file was originally uploaded as an image.
|
||||
|
||||
This misconfiguration commonly occurs in the following Nginx configuration:
|
||||
|
||||
```nginx
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
```
|
||||
|
||||
When a request is made to `file.jpg/.php`, Nginx will treat it as a PHP file and send it to the PHP-FPM for processing, even though it's actually an image file. This behavior can be exploited to execute malicious code that was uploaded as an image file.
|
||||
|
||||
## Environment Setup
|
||||
|
||||
Execute the following command to start a Nginx server with a parsing vulnerability:
|
||||
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
After successful execution, the Nginx server will listen on port 80.
|
||||
|
||||
## Vulnerability Reproduce
|
||||
|
||||
Visit `http://your-ip/uploadfiles/nginx.png` and `http://your-ip/uploadfiles/nginx.png/.php` to see the effect.
|
||||
|
||||
Normal display:
|
||||
|
||||

|
||||
|
||||
After adding the `/.php` suffix, the file is parsed as a PHP file:
|
||||
|
||||

|
||||
|
||||
Visit `http://your-ip/index.php` to test the upload functionality. While the upload code itself has no vulnerabilities, you can get a shell by exploiting the parsing vulnerability:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
To prevent this vulnerability:
|
||||
|
||||
1. Configure proper file extension handling in Nginx
|
||||
2. Implement strict file type validation
|
||||
3. Store uploaded files outside of the web root
|
||||
4. Use random file names for uploaded files
|
||||
5. Implement proper access controls
|
61
nginx/nginx_parsing_vulnerability/README.zh-cn.md
Normal file
61
nginx/nginx_parsing_vulnerability/README.zh-cn.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Nginx 解析漏洞
|
||||
|
||||
Nginx是一款Web服务器,可以作为反向代理、负载均衡、邮件代理、HTTP缓存等。这个Vulhub环境包含一个由用户配置不当导致的解析漏洞。
|
||||
|
||||
版本信息:
|
||||
|
||||
- Nginx 1.x 最新版
|
||||
- PHP 7.1.x 最新版
|
||||
|
||||
由此可知,该漏洞与Nginx、PHP版本无关,属于用户配置不当造成的解析漏洞。
|
||||
|
||||
该漏洞存在的原因是Nginx在配置中对文件扩展名的处理方式。当请求一个具有多个扩展名的文件(如`file.jpg.php`)时,Nginx可能会根据最后一个扩展名来处理,即使该文件最初是作为图片上传的。
|
||||
|
||||
这种配置错误通常出现在以下Nginx配置中:
|
||||
|
||||
```nginx
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
```
|
||||
|
||||
当请求`file.jpg/.php`时,Nginx会将其作为PHP文件处理并发送给PHP-FPM解析,尽管它实际上是一个图片文件。这种行为可以被利用来执行作为图片文件上传的恶意代码。
|
||||
|
||||
## 环境搭建
|
||||
|
||||
直接执行如下命令启动一个包含解析漏洞的Nginx服务器:
|
||||
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
运行成功后,Nginx将会监听80端口。
|
||||
|
||||
## 漏洞复现
|
||||
|
||||
访问`http://your-ip/uploadfiles/nginx.png`和`http://your-ip/uploadfiles/nginx.png/.php`即可查看效果。
|
||||
|
||||
正常显示:
|
||||
|
||||

|
||||
|
||||
增加`/.php`后缀,被解析成PHP文件:
|
||||
|
||||

|
||||
|
||||
访问`http://your-ip/index.php`可以测试上传功能,上传代码不存在漏洞,但利用解析漏洞即可getshell:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
为防止此漏洞:
|
||||
|
||||
1. 正确配置Nginx的文件扩展名处理
|
||||
2. 实施严格的文件类型验证
|
||||
3. 将上传的文件存储在Web根目录之外
|
||||
4. 使用随机文件名存储上传的文件
|
||||
5. 实施适当的访问控制
|
18
nginx/nginx_parsing_vulnerability/docker-compose.yml
Normal file
18
nginx/nginx_parsing_vulnerability/docker-compose.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:1
|
||||
volumes:
|
||||
- ./www:/usr/share/nginx/html
|
||||
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||
depends_on:
|
||||
- php
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
php:
|
||||
image: php:7.1-fpm
|
||||
command: /bin/sh /var/www/start.sh
|
||||
volumes:
|
||||
- ./start.sh:/var/www/start.sh
|
||||
- ./www:/var/www/html
|
||||
- ./php-fpm/www-2.conf:/usr/local/etc/php-fpm.d/www-2.conf
|
25
nginx/nginx_parsing_vulnerability/nginx/default.conf
Normal file
25
nginx/nginx_parsing_vulnerability/nginx/default.conf
Normal file
@@ -0,0 +1,25 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
index index.html index.php;
|
||||
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
2
nginx/nginx_parsing_vulnerability/php-fpm/www-2.conf
Normal file
2
nginx/nginx_parsing_vulnerability/php-fpm/www-2.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
[www]
|
||||
security.limit_extensions =
|
6
nginx/nginx_parsing_vulnerability/start.sh
Normal file
6
nginx/nginx_parsing_vulnerability/start.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||
|
||||
chmod 777 /var/www/html/uploadfiles
|
||||
php-fpm
|
49
nginx/nginx_parsing_vulnerability/www/index.php
Normal file
49
nginx/nginx_parsing_vulnerability/www/index.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?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;
|
BIN
nginx/nginx_parsing_vulnerability/www/uploadfiles/nginx.png
Normal file
BIN
nginx/nginx_parsing_vulnerability/www/uploadfiles/nginx.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Reference in New Issue
Block a user