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?
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
calcto/Applications/Calculator.app/Contents/MacOS/Calculatoras I am on a MacOS.Without a policy manager the calculator opens fine:
And the calculator really opens.
However, with bypass-by-createclassloader.policy it will still use the wrong class loader:
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?