Fixed bypass-by-createclassloader?
Hi there,
Nice work, really appreciate the sandbox escape techniques. I was wondering if maybe the new JRE fixed the bypass-by-createclassloader technique? I don't seem to be able to reproduce in newer versions. I switched the Runtime exec in EvilClass.java from calc to /Applications/Calculator.app/Contents/MacOS/Calculator as I am on a MacOS.
Without a policy manager the calculator opens fine:
$ javac *.java && java Poc
Note: Poc.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: EvilClass.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
jdk.internal.loader.ClassLoaders$AppClassLoader@55054057
And the calculator really opens.
However, with bypass-by-createclassloader.policy it will still use the wrong class loader:
javac *.java && java -Djava.security.manager -Djava.security.policy=bypass-by-createclassloader.policy Poc
Note: Poc.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: EvilClass.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
java.security.AccessControlException: access denied ("java.io.FilePermission" "/Applications/Calculator.app/Contents/MacOS/Calculator" "execute")
at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.base/java.security.AccessController.checkPermission(AccessController.java:1042)
at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408)
at java.base/java.lang.SecurityManager.checkExec(SecurityManager.java:655)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1096)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
at java.base/java.lang.Runtime.exec(Runtime.java:589)
at java.base/java.lang.Runtime.exec(Runtime.java:413)
at java.base/java.lang.Runtime.exec(Runtime.java:310)
at EvilClass$1.run(EvilClass.java:13)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:310)
at EvilClass.<clinit>(EvilClass.java:8)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:415)
at Poc.main(Poc.java:7)
jdk.internal.loader.ClassLoaders$AppClassLoader@55054057
From above we can see that EvilClass is run. However, except for the construct we call ourselves of MyClassLoader, no other method is called... this looks very much like a fix... was it fixed JRE internally? Any other reason why our malicious ClassLoader is not used even though we have createClassLoader privileges?