Skip to content

Fixed bypass-by-createclassloader? #1

@floyd-fuh

Description

@floyd-fuh

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions