淺談變形PHP webshell檢測(cè)
一、變形webshell
webshell比如eval($_POST[])大家都耳熟能詳,近幾年在常見(jiàn)的webshell基礎(chǔ)上衍生了很多變種,加大了檢測(cè)難度,下面先看幾個(gè)從網(wǎng)上摘取的樣本:
1、無(wú)ascii碼和數(shù)字的webshell
2、隱藏關(guān)鍵字
3、編碼 + 隱藏關(guān)鍵字
從目前已經(jīng)公開(kāi)的樣本來(lái)看,變形的php webshell都是采取了隱藏關(guān)鍵字(eval、system等)的方法來(lái)躲避查殺。有一位monyer同學(xué)寫(xiě)過(guò)一篇webshell的檢測(cè)文章,他把webshell拆分為下面的結(jié)構(gòu),執(zhí)行數(shù)據(jù)和數(shù)據(jù)傳遞,檢測(cè)思路是:以小括號(hào)為界限,匹配執(zhí)行數(shù)據(jù)部分是否命中收集的樣本的關(guān)鍵字。這種思路很好,個(gè)人覺(jué)得有兩處不足:
1、需要人工維護(hù)收集新樣本。
2、誤報(bào)量不可預(yù)估。
再看這個(gè)結(jié)構(gòu),變形的webshell無(wú)非是隱藏了執(zhí)行數(shù)據(jù)部分或者數(shù)據(jù)傳遞部分,不過(guò)無(wú)論怎么變形本質(zhì)上還是去調(diào)用eval、調(diào)用system、exec等命令執(zhí)行函數(shù),殺毒軟件通過(guò)異常行為來(lái)檢測(cè)木馬病毒,比如開(kāi)機(jī)自啟動(dòng),這種思想同樣也可以用在webshell的檢測(cè)中。獲取行為數(shù)據(jù)是第一步。
二、PHP HOOK
這里我們只需要一些敏感的行為數(shù)據(jù),比如eval、system的調(diào)用。實(shí)現(xiàn)方法很簡(jiǎn)單,hook這些php函數(shù)或語(yǔ)法結(jié)構(gòu),這里通過(guò)php擴(kuò)展來(lái)實(shí)現(xiàn)hook。下面以eval和system來(lái)簡(jiǎn)要概述下hook的方法。
Eval是一個(gè)語(yǔ)法結(jié)構(gòu),調(diào)用eval最終會(huì)調(diào)用php內(nèi)核的zend_compile_string函數(shù),hook eval的只需要重寫(xiě)zend_complie_string函數(shù)即可,流程如下:
System是php的一個(gè)內(nèi)部函數(shù),php代碼是轉(zhuǎn)化為opcode(指令)來(lái)執(zhí)行,函數(shù)調(diào)用的指令是ZEND_DO_FCALL,風(fēng)雪之隅大牛在taint擴(kuò)展(詳見(jiàn)參考二)就是通過(guò)重載ZEND_DO_FCALL的方法實(shí)現(xiàn)了。因?yàn)槲覀儾⒉恍枰猦ook每個(gè)內(nèi)部函數(shù),所以這里介紹另外一種方法,流程如下:
上報(bào)的數(shù)據(jù)寫(xiě)在一個(gè)日志文件中,包括文件名、調(diào)用函數(shù)名、代碼在文件的行數(shù)。日志結(jié)構(gòu)和內(nèi)容如下:
附件中有eval、system函數(shù)hook實(shí)現(xiàn)的demo,具體細(xì)節(jié)可以查看代碼。demo只在php-5.3.6上測(cè)試過(guò),不兼容之處忘見(jiàn)諒。
三、檢測(cè)
變形webshell分為兩大類(lèi),下面依次說(shuō)明一下檢測(cè)邏輯。
1、執(zhí)行數(shù)據(jù)隱藏
一個(gè)正常的程序員如果使用eval、system是不會(huì)刻意的轉(zhuǎn)換隱藏的,如果發(fā)現(xiàn)某個(gè)函數(shù)執(zhí)行了,代碼中卻找不到這個(gè)函數(shù)名,我們認(rèn)為這是一個(gè)異常行為。以下面這個(gè)變形為例
比如黑客傳入?yún)?shù)nonalpha.php?_=system&__=whoami執(zhí)行了一條命令,日志會(huì)記錄
我們?cè)诤蠖巳onalpha.php文件的第7行內(nèi)容匹配system(字符串,如果沒(méi)找到,則認(rèn)為是一個(gè)變形webshell。
2、數(shù)據(jù)傳遞隱藏
先看下面這個(gè)例子
這個(gè)webshell通過(guò)編碼的referer來(lái)傳遞攻擊載荷,利用日志文件記錄到的文件名和行數(shù)把代碼上報(bào)到后端,和后端svn中的代碼做對(duì)比,如果不一致,則認(rèn)為是一個(gè)webshell。
四、不足
web承受著大量的訪(fǎng)問(wèn)請(qǐng)求,增加的php擴(kuò)展的性能和穩(wěn)定性是一個(gè)嚴(yán)峻的考驗(yàn),另外在服務(wù)器比較多的公司還存在一個(gè)推廣和部署成本。