本篇主講RASP實現(簡易版),所有的環境可參考: 淺談RASP技術攻防之實戰[環境配置篇]
程式碼上傳GitHub地址:https://github.com/iiiusky/java_rasp_example
關於 ASM 中不同類不同方法之間的關係圖如下
簡易版RASP實現
建立入口類
在cn.org.javaweb.agent包下新建一個類。
內容如下:
建立Transform
然後我們再新建一個AgentTransform類,該類需要實現ClassFileTransformer的方法,內容如下:
build Agent配置
點選右上角的agent[clean,intall]進行build。
由上圖可見我們的包的位置為
將改包的位置記錄下來,然後點開tomcat配置(這邊沒有對idea如何配置tomcat進行講解,不會的可以自行百度|谷歌)
在VM options處填寫以下內容:
其中/Volumes/Data/code/work/JavawebAgent/agent/target/agent.jar的路徑為你在上一步編譯出來的agent的路徑,注意替換。
這時候我們在啟動tomcat,就可以看到我們在AgentTransform中寫的列印包名已經生效了,如下圖:
上圖紅框區域為tomcat啟動的時候載入的所有類名。然後我們開啟瀏覽器檢視web是否正常。
可以看到web也正常啟動了。
建立ClassVisitor類
然後我們新建一個TestClassVisitor類,需要繼承ClassVisitor類並且實現Opcodes類,程式碼如下
對ProcessBuilder(命令執行)類進行hook使用者執行的命令
≡≡ 使用transform對類名進行過濾
然後回到AgentTransform中,對transform方法的內容進行修改,transform方法程式碼如下:
簡單介紹一下程式碼塊內容
首先判斷類名是否包含ProcessBuilder,如果包含則使用ClassReader對位元組碼進行讀取,然後新建一個ClassWriter進行對ClassReader讀取的位元組碼進行拼接,然後在新建一個我們自定義的ClassVisitor對類的觸發事件進行hook,在然後呼叫classReader的accept方法,最後給classfileBuffer重新賦值修改後的位元組碼。
可能看起來比較繞,但是如果學會使用以後就比較好理解了。
≡≡ 建立測試環境
我們在tomcat中新建一個jsp,用來呼叫命令執行,程式碼如下:
可以看到就是一個簡單的執行命令的程式碼;下面我們對就此更改過的內容進行build,看一下會輸出點什麼。
biuld完成,啟動tomcat。
訪問
可以看到已經成功執行命令,我們回到idea裡面的控制檯看一下輸出了什麼。
通過上圖可以完整的看到一個執行命令所呼叫的所有呼叫鏈。
≡≡ 拿到使用者所執行的命令
接下來我們看看嘗試一下能否拿到所執行的命令
新建一個名為ProcessBuilderHook的類,然後在類中新建一個名字為start的靜態方法,完整程式碼如下:
這個方法幹啥用的我們一會在說,先看下面。
≡≡ 複寫visitMethod方法
開啟TestClassVisitor,對visitMethod方法進行更改。具體程式碼如下:
給大家解釋下新增加的程式碼,從if判斷開始
判斷傳入進來的方法名是否為start以及方法描述符是否為()Ljava/lang/Process;,如果是的話就新建一個AdviceAdapter方法,並且複寫visitCode方法,對其位元組碼進行修改,
拿到棧頂上的this
拿到this裡面的command
然後呼叫我們上面新建的ProcessBuilderHook類中的start方法,將上面拿到的this.command壓入我們方法。
ProcessBuilderHook類的作用就是讓這部分進行呼叫,然後轉移就可以轉入到我們的邏輯程式碼了。
我們再次編譯一下,然後啟動tomcat,訪問cmd.jsp看看.
≡≡ 測試hook使用者執行的命令引數是否拿到
訪問
可以看到已經將當前目錄下的內容列印了出來。
我們到idea中看看控制檯輸出了什麼。
可以看到我們輸入的命令
已經輸出出來了,到此為止,我們拿到了要執行的命令.
總結
對於拿到要執行的命令以後怎麼做,是需要攔截還是替換還是告警,這邊就需要大家自己去實現了。當然,如果要實現攔截功能,還需要注意要獲取當前請求中的的response,不然無法對response進行復寫,也無法對其進行攔截。這邊給大家提供一個思路,對應攔截功能,大家可以去hook請求相關的類,然後在危險hook點結合http請求上下文進行攔截請求。
對於其他攻擊點的攔截,可以參考百度開源的OpenRasp進行編寫hook點。
如需在Java中實現RASP技術,筆者建議好好了解一下ASM,這樣對以後JAVA的執行機制也會有一定的瞭解,方便以後除錯以及寫程式碼。
參考
https://rasp.baidu.com/doc/hacking/architect/hook.html#java-server
https://github.com/anbai-inc/javaweb-codereview
https://static.javadoc.io/org.ow2.asm/asm/5.2/org/objectweb/asm/ClassReader.html
http://www.blogjava.net/vanadies10/archive/2011/02/23/344899.html
http://www.blogjava.net/DLevin/archive/2014/06/25/414292.html