ysoserial icon indicating copy to clipboard operation
ysoserial copied to clipboard

Test harness

Open jasinner opened this issue 8 years ago • 3 comments

Works well on MacOSX and Linux. Need to test on Windows.

A couple of test fail for me on JDK 8 < 72: BeanShell1: Caused by: java.io.IOException: Cannot run program "touch /var/folders/p9/x43p6nms3jng27wcmq5xs20w0000gn/T//BeanShell1": error=2, No such file or directory at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at bsh.Reflect.invokeMethod(Reflect.java:134)

JRMPClient: I think because I'm using SunJDK, and not JavaSE, which apparently is required.

jasinner avatar Mar 14 '16 07:03 jasinner

This definitely doesn't work for me on windows. The tests all seem to be failing.

frohoff avatar Mar 18 '16 15:03 frohoff

Hi Chris, I spent a bit of time on this today, and added support for calling Runtime.exec() with String[] instead of a single String. This will be more useful on Windows, and required for the test harness I'm proposing as you need to do: "cmd.exe", "\C", "copy NUL test.txt" However now Runtime.exec fails to be called, and I get a stack trace like: java.lang.IllegalArgumentException: wrong number of arguments at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:125) Any idea why?

jasinner avatar Mar 24 '16 06:03 jasinner

This is a tricky change. A couple thoughts:

  • Your error probably arises from trying to directly pass the String[] command array as the arguments to invoke the method when it should probably be wrapped in an additional Object[] argument array.
  • This change is somewhat invasive and may cause subtle, environment-specific errors to surface at runtime, so it should probably be very well tested. It would probably be a good idea to have the test harness verify that the final "sink" invocation (i.e. Runtime.exec(String[])) works properly on the running platform outside of a payload before testing it within a payload to ensure errors can be traced to a buggy sink call vs one or more buggy gadget chains.
  • Changing everything to use the Runtime.exec(String[]) method instead of the Runtime.exec(String) method may change semantics in unexpected ways since invocations like java -jar ysoserial-*.jar CommonsCollections1 "curl google.com" will no longer tokenize curl and google.com separately before passing them to Runtime.exec(String[]) which expects the first argument to be an executable file. For example, using groovysh:
groovy:000> Runtime.getRuntime().exec("curl google.com").inputStream.text
Runtime.getRuntime().exec("curl google.com").inputStream.text
===> <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>...

groovy:000> Runtime.getRuntime().exec(["curl google.com"] as String[]).inputStream.text
Runtime.getRuntime().exec(["curl google.com"] as String[]).inputStream.text
ERROR java.io.IOException:
Cannot run program "curl google.com": CreateProcess error=2, The system cannot find the file specified
  • You might consider using Arrays.copyOfRange instead of writing your of Gadgets.removeFirst(int,String[]) method

frohoff avatar Apr 04 '16 21:04 frohoff