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

This commit is contained in:
2025-09-06 16:08:15 +08:00
commit 63285f61aa
2624 changed files with 88491 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

View 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:
![image](1.jpg)
After adding the `/.php` suffix, the file is parsed as a PHP file:
![image](2.jpg)
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:
![image](3.jpg)
![image](4.jpg)
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

View 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`即可查看效果。
正常显示:
![image](1.jpg)
增加`/.php`后缀被解析成PHP文件
![image](2.jpg)
访问`http://your-ip/index.php`可以测试上传功能上传代码不存在漏洞但利用解析漏洞即可getshell
![image](3.jpg)
![image](4.jpg)
为防止此漏洞:
1. 正确配置Nginx的文件扩展名处理
2. 实施严格的文件类型验证
3. 将上传的文件存储在Web根目录之外
4. 使用随机文件名存储上传的文件
5. 实施适当的访问控制

View 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

View 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;
}
}

View File

@@ -0,0 +1,2 @@
[www]
security.limit_extensions =

View 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

View 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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB