0x00 前言我們知道,當我們訪問jsp文件時,Java環境會先將jsp文件轉換成.class字節碼文件,再由Java虛擬機進行加載,這導致了Java服務器上會生成對應名稱的.class字節碼文件。對於webshell,這會留下痕跡。
為了實現自刪除.class字節碼文件,我們可以通過反射獲得.class字節碼文件的路徑,再進行刪除。本文將以Zimbra環境為例,結合AntSword-JSP-Template,分析利用思路。
0x01 簡介本文將要介紹以下內容:
◼通過反射實現webshell編譯文件的自刪除
◼通過反射實現AntSword-JSP-Template
0x02 通過反射實現webshell編譯文件的自刪除根據上篇文章《Java利用技巧——通过反射修改属性》 的內容,我們按照映射request-_scope-_servlet-rctxt-jsps,通過多次反射最終能夠獲得JspServletWrapper實例
查看JspServletWrapper類中的成員,jsps-value-ctxt-servletJavaFileName保存.java編譯文件的路徑,jsps-value-ctxt-classFileName保存.class編譯文件的路徑,示例如下圖
為了只篩選出當前jsp,可以通過request類的getServletPath()方法獲得當前Servlet,如下圖
從ctxt對象獲取servletJavaFileName可以調用JspCompilationContext類的getServletJavaFileName()方法,如下圖
從ctxt對象獲取classFileName可以調用JspCompilationContext類的getClassFileName()方法,如下圖
綜上,由此我們可以得出通過反射獲取編譯文件路徑的實現代碼如下:
刪除編譯文件的代碼如下:
0x03 通過反射實現AntSword-JSP-Templaterebeyond在《利用动态二进制加密实现新型一句话木马之Java篇》 介紹了Java一句話木馬的實現方法,AntSword-JSP-Template也採用了相同的方式
我在測試AntSword-JSP-Template的過程中,發現編譯文件會多出一個,例如test.jsp,訪問後,生成的編譯文件為test_jsp.class和test_jsp.java,如果使用了AntSword-JSP-Template,會額外生成編譯文件test_jsp$U.class
rebeyond在《利用动态二进制加密实现新型一句话木马之Java篇》 提到:
“正常情況下,Java並沒有提供直接解析class字節數組的接口。不過classloader內部實現了一個protected的defineClass方法,可以將byte[]直接轉換為Class
因為該方法是protected的,我們沒辦法在外部直接調用,當然我們可以通過反射來修改保護屬性,不過我們選擇一個更方便的方法,直接自定義一個類繼承classloader,然後在子類中調用父類的defineClass方法。 ”
這裡我打算通過反射修改保護屬性,調用ClassLoader類的defineClass()方法
在ClassLoader類中,defineClass()方法有多個重載,如下圖
這裡選擇defineClass(byte[] b, int off, int len)
rebeyond在《利用动态二进制加密实现新型一句话木马之Java篇》 還提到:
“如果想要順利的在equals中調用Request、Response、Seesion這幾個對象,還需要考慮一個問題,那就是ClassLoader的問題。JVM是通過ClassLoader+類路徑來標識一個類的唯一性的。我們通過調用自定義ClassLoader來defineClass出來的類與Request、Response、Seesion這些類的ClassLoader不是同一個,所以在equals中訪問這些類會出現java.lang.ClassNotFoundException異常”
解決方法同樣是複寫ClassLoader的如下構造函數,傳遞一個指定的ClassLoader實例進去:
最終,得到通過反射實現AntSword-JSP-Template的核心代碼:
訪問通過反射實現AntSword-JSP-Template的test.jsp後,額外生成的編譯文件為test_jsp$1.class
0x04 小結本文介紹了通過反射實現webshell編譯文件自刪除和AntSword-JSP-Template,記錄關於反射的學習心得。
Recommended Comments