FindShell內(nèi)存馬查殺工具
FindShell 是一個自動的內(nèi)存馬查殺工具,可以用于普通內(nèi)存馬和Java Agent內(nèi)存馬。
尤其針對難以查殺的Java Agent型內(nèi)存馬,例如冰蝎等主流工具的內(nèi)存馬都是Java Agent
主要分為以下四步:
- 利用
JDK提供的sa-jdi的API基于黑名單dump存在于JVM中真正的字節(jié)碼 - 這種字節(jié)碼在很多情況下是非法的,所以我修改了
ASM源碼以分析非法字節(jié)碼 - 基于
ASM做普通的分析和模擬棧幀做深入的分析 - 如果發(fā)現(xiàn)內(nèi)存馬將會嘗試自動修復(fù)目標(biāo)(利用
Java Agent動態(tài)恢復(fù)原始字節(jié)碼)
檢測
基本檢測:java -jar FindShell.jar --pid [目標(biāo)JVM的PID]
這個pid的獲取方式可以通過jps命令找到你需要的目標(biāo)JVM的pid
這種情況下默認(rèn)必檢測的類有以下四個(最常見的Java Agent內(nèi)存馬出現(xiàn)的地方)
| 類名 | 方法名 |
|---|---|
| javax/servlet/http/HttpServlet | service |
| org/apache/catalina/core/ApplicationFilterChain | doFilter |
| org/springframework/web/servlet/DispatcherServlet | doService |
| org/apache/tomcat/websocket/server/WsFilter | doFilter |
并對以下的黑名單類進(jìn)行檢測(如果類名出現(xiàn)關(guān)鍵字則dump并分析該類字節(jié)碼)
keyword.add("shell"); keyword.add("memshell"); keyword.add("agentshell"); keyword.add("exploit"); keyword.add("payload"); keyword.add("rebeyond"); keyword.add("metasploit");
注意:
- 修改
org.sec.Constant代碼可以自定義黑名單和關(guān)鍵字 - 加入
--debug參數(shù)保留從JVM中dump出的字節(jié)碼供自行分析 - 并不是所有類的字節(jié)碼都可以
dump成功,但常見的這些類測試中沒問題
修復(fù)
目前僅做了Java Agent內(nèi)存馬的自動修復(fù),支持最常見的HttpServlet和ApplicationFilterChain
檢測和修復(fù):java -jar FindShell.jar --pid [PID] --repair
根目錄存在一個RepairAgent.jar文件,這不屬于該項目,但我將代碼放在org.sec.repair包中供參考
注意:修復(fù)手段僅靶機(jī)測試成功,在真實(shí)環(huán)境中使用請慎重
原理
- 為什么不直接用
Java Agent或Alibaba Arthas工具對JVM當(dāng)前字節(jié)碼進(jìn)行dump
Java Agent內(nèi)存馬是調(diào)用redefineClass方法對字節(jié)碼進(jìn)行修改的。而調(diào)用retransformClass方法的時候參數(shù)中的字節(jié)碼并不是調(diào)用redefineClass后被修改的類的字節(jié)碼。對于冰蝎來講,根本無法獲取被冰蝎修改后類的字節(jié)碼。我們自己寫Java Agent清除內(nèi)存馬的時候,同樣也是無法獲取到被redefineClass修改后的字節(jié)碼,只能獲取到被retransformClass修改后的字節(jié)碼。通過Javaassist等ASM工具獲取到類的字節(jié)碼,也只是讀取磁盤上響應(yīng)類的字節(jié)碼,而不是JVM中的字節(jié)碼
- 那么怎樣獲得存在于
JVM中真正的字節(jié)碼
之前有寬字節(jié)安全的師傅提到利用sa-jdi工具對真正的當(dāng)前字節(jié)碼進(jìn)行dump后反編譯結(jié)合人工分析,該工具也是基于JDK自帶的sa-jdi庫實(shí)現(xiàn)的,不過加入了一些過濾的選項
- 什么情況下這樣的字節(jié)碼為什么是非法的
當(dāng)目標(biāo)類存在lambda表達(dá)式的時候會導(dǎo)致非法字節(jié)碼,具體可以參考我的文章
- 修改了哪些源碼以解析非法字節(jié)碼
參考連接:修改源碼說明
- 為什么要結(jié)合普通字節(jié)碼分析和模擬棧幀分析兩種呢
因?yàn)?code>Runtime.exec這種調(diào)用很不常見且過程簡單,用普通的字節(jié)碼分析即可解決。但是冰蝎的反射調(diào)用defineClass并反射invoke以實(shí)現(xiàn)代碼執(zhí)行效果的方式,過程比較復(fù)雜,且反射調(diào)用是程序中的常見功能,簡單的分析會導(dǎo)致誤報
- 什么是模擬棧幀分析
參考文章:詳解Java自動代碼審計工具實(shí)現(xiàn) 和 基于污點(diǎn)分析的JSP Webshell檢測
免責(zé)聲明
工具僅用于安全研究以,由于使用該工具造成的任何后果使用者負(fù)責(zé)
