He began to practice [red] team of PHP-Audit-Labs code audit Day16
link: https://github.com/hongriSec/PHP-Audit-Labs
interested students can go to Exercise
Prior knowledge:
content title comes from PHP SECURITY 2017 CALENDAR
Day 16 - Poem code is as follows:
class FTP {
public $sock;
public function __construct($host, $port, $user, $pass) {
$this->sock = fsockopen($host, $port);
$this->login($user, $pass);
$this->cleanInput();
$this->mode($_REQUEST['mode']);
$this->send($_FILES['file']);
}
private function cleanInput() {
$_GET = array_map('intval', $_GET);
$_POST = array_map('intval', $_POST);
$_COOKIE = array_map('intval', $_COOKIE);
}
public function login($username, $password) {
fwrite($this->sock, "USER " . $username . "\n");
fwrite($this->sock, "PASS " . $password . "\n");
}
public function mode($mode) {
if ($mode == 1 || $mode == 2 || $mode == 3) {
fputs($this->sock, "MODE $mode\n");
}
}
public function send($data) {
fputs($this->sock, $data);
}
}
new FTP('localhost', 21, 'user', 'password');
Vulnerability Analysis:
This question includes the 两个漏洞
use of these loopholes, we can go to FTP连接资源
inject malicious data, perform FTP命令
.
First to see the 第7行
code, you can find uses cleanInput
methods
$this->cleanInput();
Filtration GET, POST, COOKIE number.
private function cleanInput() {
$_GET = array_map('intval', $_GET);
$_POST = array_map('intval', $_POST);
$_COOKIE = array_map('intval', $_COOKIE);
}
They will be forced to turn to 整型数据
. However, in the 第8行
office.
$this->mode($_REQUEST['mode']);
It has passed from a REQUEST
get way mode
variables. We all know that super global array $_REQUEST
data, is $_GET 、 $_POST 、 $_COOKIE
the collection, and the data is copied in the past, not a reference. Let's look at an example to validate this view:
can be found REQUEST
affect the function of the data did not filter.
Return to this example, in the example program filter function only to GET 、 POST 、 COOKIE
manipulate the data, and finally make use of them it is REQUEST
data, which will obviously be a security risk.
$_REQUEST :
(PHP 4, PHP 5, PHP 7)
Features:
$_REQUEST — HTTP Request 变量
definition:
By default contains $_GET
, $_POST
and $_COOKIE
arrays.
Description:
-
“Superglobal”
Also known as automated global variables. This means that all of its scope in the script are available. The method need not be used or functionglobal $variable
; to access it. -
Run command line, it will not contain
argv
andargc
information; they will be present in$_SERVER
the array. -
Because of
$_REQUEST
the variablesGET
,POST
andCOOKIE
passed to the script file input mechanism, and therefore can be tampered with remote users and can not be trusted. This array depends on the sequence of items and the PHPvariables_order
command configuration.
The second vulnerability, then the code 第24行
, here used == 弱比较
.
==
And===
==
weak equal, i.e.12=="12"
->true
and12=="12cdf"
->true
only taking the integer part of the beginning of the string, but1e3dgf
so that the string comparison, is taking part in line with scientific notation:1e3
that is1000
.
Recommended here PHP type comparison vulnerability weak (relatively loose) areas
As for this case of attack payload
, you can use: ?mode=1%0a%0dDELETE%20test.file
This can be achieved by deleting the FTP服务器
effect file.
Case Analysis:
本次实例分析, 我们选取的是
WordPress
的All In One WP Security & Firewall
插件 。
该插件在4.1.4 - 4.1.9
版本中存在反射型XSS
漏洞,漏洞原因和本次案例中的漏洞成因一致,官方也在4.2.0
版本中修复了该漏洞。本次,我们将以4.1.4
版本插件作为案例讲解。
漏洞POC 本站提供安全工具、程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!
漏洞分析:
将下载下来的插件zip包,通过后台插件管理上传压缩包安装即可。
本次发生问题的文件在于 admin\wp-security-dashboard-menu.php
,为了方便大家理解,我将问题代码抽取出来,简化如下:
我们可以很清晰的看到,问题就出在 第25行
的render_tab3
方法中,这里直接将 REQUEST
方式获取的tab
变量拼接并输出。而实际上,在第20行
已经获取了经过过滤处理的 $tab
变量。我们来看一下get_current_tab
方法:
过滤函数的调用链如下图第1行
,接着 $tab
变量就会经过wp_check_invalid_utf8
方法的检测。
漏洞利用:
下面我们来看看攻击 payload
(向 http://10.211.55.5/phpcode/day16/wordpress/wp-admin/admin.php?page=aiowpsec&tab=tab3
POST数据 tab="><script>alert(1)</script>
):
可以看到成功引发XSS攻击
。我们最后再根据payload
对代码的调用过程进行分析。
首先,我们的 payload
会传入 wp-admin/admin.php
文件中,最后进入 第14行
的 do_action('toplevel_page_aiowpsec');
代码。
在wp-includes/plugin.php
文件中,程序又调用了 WP_Hook
类的 do_action
方法,该方法调用了自身的 apply_filters
方法。
然后apply_filters
方法调用了wp-content\plugins\all-in-one-wp-security-and-firewall\admin\wp-security-admin-init.php
文件的 handle_dashboard_menu_rendering
方法,并实例化了一个 AIOWPSecurity_Dashboard_Menu
对象。
接下来就是开头文章分析的部分,也就是下面这张图片:
整个漏洞的攻击链就如下图所示:
这里还有一个小知识点要提醒大家的是,案例中 $_REQUEST["tab"]
最后取到的是 $_POST["tab"]
的值,而不是 $_GET["tab"]
变量的值。这其实和 php.ini
中的 request_order
对应的值有关。例如在我的环境中, request_order
配置如下:
这里的 "GP"
表示的是 GET
和POST
,且顺序从左往右
。例如我们同时以GET
和 POST
方式传输 tab
变量,那么最终用 $_REQUEST['tab']
获取到的就是 $_POST['tab']
的值。
修复建议:
对于这个漏洞的修复方案,我们只要使用过滤后的 $tab
变量即可,且变量最好经过HTML
实体编码后再输出,例如使用htmlentities
函数等。
结语
再次感谢【红日团队】