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
66 lines
3.0 KiB
Markdown
66 lines
3.0 KiB
Markdown
# 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):
|
|
|
|

|
|
|
|
Visit `http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php`, and you'll find that PHP has been parsed:
|
|
|
|

|
|
|
|
Note: [0x20] is a space, [0x00] is `\0`, and these characters don't need to be encoded.
|