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/CVE-2013-4547/01.png
Normal file
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
BIN
nginx/CVE-2013-4547/02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
65
nginx/CVE-2013-4547/README.md
Normal file
65
nginx/CVE-2013-4547/README.md
Normal 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):
|
||||
|
||||

|
||||
|
||||
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.
|
65
nginx/CVE-2013-4547/README.zh-cn.md
Normal file
65
nginx/CVE-2013-4547/README.zh-cn.md
Normal 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 ",注意后面的空格:
|
||||
|
||||

|
||||
|
||||
访问`http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php`,即可发现PHP已被解析:
|
||||
|
||||

|
||||
|
||||
注意,[0x20]是空格,[0x00]是`\0`,这两个字符都不需要编码。
|
17
nginx/CVE-2013-4547/docker-compose.yml
Normal file
17
nginx/CVE-2013-4547/docker-compose.yml
Normal 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
|
33
nginx/CVE-2013-4547/index.php
Normal file
33
nginx/CVE-2013-4547/index.php
Normal 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;
|
33
nginx/CVE-2013-4547/nginx.conf
Normal file
33
nginx/CVE-2013-4547/nginx.conf
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
7
nginx/CVE-2013-4547/www.conf
Normal file
7
nginx/CVE-2013-4547/www.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
[global]
|
||||
daemonize = no
|
||||
|
||||
[www]
|
||||
listen = 9000
|
||||
security.limit_extensions =
|
||||
php_admin_flag[cgi.fix_pathinfo] = off
|
Reference in New Issue
Block a user