From 38b4fc0a04408c77d9f6541a9d7f31836a34c84e Mon Sep 17 00:00:00 2001 From: Alexander Ponticello Date: Sun, 19 Jan 2020 18:59:16 +0100 Subject: [PATCH] Again fixing images --- writeups/aliponti/asis19.md | 2 +- writeups/aliponti/otw_advent_bonanza19.md | 2 +- writeups/aliponti/ructfe19.md | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/writeups/aliponti/asis19.md b/writeups/aliponti/asis19.md index 1b65cde..9e5dd1c 100644 --- a/writeups/aliponti/asis19.md +++ b/writeups/aliponti/asis19.md @@ -120,7 +120,7 @@ My next thought was that some kind of steganography was used in order to hide da Next I tried one of the useful online tools. [https://aperisolve.fr/](https://aperisolve.fr/) let's you upload images for analysis. So I did that for all the images and bingo, 3 of them (exactly the ones with no text comment) had some suspicious looking least significant bit (LSB) values. When split into plains for every bit of every color channel, one could see that the least-significant bits where almost all black, except for a single line at the beginning. This is a very common technique to hide data in images, since the change introduced is almost invisible to the naked eye. I used the website and also some scripts to extract the data but it did not make any sense. I tried several permutations and different was of extracting it, without any luck. I also checked different CTF challenges from previous contests ([1](https://github.com/krx/CTF-Writeups/blob/master/CSAW%2016%20Quals/for250%20-%20Watchword/jk_actual_writeup.md), [2](https://hexpresso.wordpress.com/2014/05/10/asis-ctf-quals-2014-stego-100-blocks-write-up/), [3](https://honeysec.blogspot.com/2019/05/writeup-csactf19-challenges.html?m=1), [4](https://veteransec.com/2018/10/18/vetsec-takes-first-in-the-hacktober-ctf-summary-steganography-write-up/), [5](https://shankaraman.wordpress.com/category/ctf/stegano/) to find any other method I could use but did not find anything so after some time I gave up. -[Image split into planes](asis19/plain_analysis.png) +![Image split into planes](asis19/plain_analysis.png) After the CTF was over, I checked the write ups and found a [solution to this challenge by p4](https://github.com/p4-team/ctf/tree/master/2019-11-16-asis-finals/secrets). Apparently the authors used [this tool](https://github.com/mgeitz/albumfs) from github to create the challenge. It's a steganography tool that hides a file system in a bunch of images, using the LSB method as well as XOR-encryption with a key. I never saw this tool before as I do not think it is very popular, judging by the relatively few stars and forks it got on github. However, now it became clear that the challenge name was a hint to this tool, as well as the comment I found. With more profound research from my side I should have been able to find this tool and make more sense of this challenge. I tried using the tool to solve the challenge at this point but apparently the code does not compile without editing and since my C skills are scary low, I did not proceed with it. diff --git a/writeups/aliponti/otw_advent_bonanza19.md b/writeups/aliponti/otw_advent_bonanza19.md index 4b06bdc..158a8a0 100644 --- a/writeups/aliponti/otw_advent_bonanza19.md +++ b/writeups/aliponti/otw_advent_bonanza19.md @@ -14,7 +14,7 @@ The second Easter egg had no description at all just the link to the CTFs websit For Easter egg number 3 we got a link to a tweet by the organizers showing a picture of a matrix barcode that had the characteristic corner elements of a QR-code. So i scanned it, obtaining the resulting string `137:64:137:154:171:146:63:175`. This fits the format of an IPv6 address. So I checked, but no server was responding to this IP. I also tried converting the numbers to ASCII symbols, since the numbers would be in the range of octal numbers for ASCII characters. but the result did not look like anything meaningful to me `_4_lyf3}`. What I missed, but luckily not one of my colleagues who solved the challenge in the end, is that the middle part of the matrix code was in fact not part of the QR-encoding, but is part is the position marker for another matrix encoding known as [Aztec Code](https://en.wikipedia.org/wiki/Aztec_Code). So what we have after all is a matrix barcode polyglot, since the code is both a valid QR-Code as well as Aztec-Code. This is possible because such codes have error correcting properties that allow for extra stuff to be included while keeping the code readable. [1](https://hackaday.com/2011/08/11/how-to-put-your-logo-in-a-qr-code/) -[Easter Egg 3](otw_advent19/easter_egg3.jpeg) +![Easter Egg 3](otw_advent19/easter_egg3.jpeg) ## Time report diff --git a/writeups/aliponti/ructfe19.md b/writeups/aliponti/ructfe19.md index 7c51bef..71f44c7 100644 --- a/writeups/aliponti/ructfe19.md +++ b/writeups/aliponti/ructfe19.md @@ -10,11 +10,11 @@ I work on the locator service together with Markus Bauer. The service was, simil This already made it clear what we want to achieve, namely access other users (the GS) info data. In order to find a vulnerability we looked through the code and fund a hardcoded `secretHashKey`, which was used in the context of session generation (see Figure 1). -[Fixed hash key](ructfe19/fixed_secret.png) +![Fixed hash key](ructfe19/fixed_secret.png) So our first thought was that maybe we are able to generate a valid session for another user. We generated some sessions for ourself, trying to find some pattern in it but without any luck. So we looked further into the code in order to understand, how sessions generation was done and where the hardcoded secret was used. But by doing so, we stumbled over something even more interesting. The service included a class with the sounding name `RuntimeClassLoader`, which did exactly as its name suggests, loading classes at runtime. -[RuntimeClassLoader class](ructfe19/fclass_loader.png) +![RuntimeClassLoader class](ructfe19/fclass_loader.png) This is known to cause problems [1](https://stackoverflow.com/questions/42720149/what-is-a-purpose-of-the-secureclassloader), also the IDE I used highlighted already that the `defineClass` method used had been deprecated. If we are able to inject arbitrary bytecode into this method, we have a potential RCE. We found one usage of the method in question in the `Decoder` class `isValidKey` method, which gets its input from the `isValid` method of the `RegisterData` class. This class is annotated as serializable. We figured out that the registers frontend sends the data as a json-encoded serialized Java object. So in order in get our custom class loaded we have to compile it, encode it and send it to the `/register` endpoint as a custom filed. Another important puzzle piece was found in the `decodeMessage` method of the `Decoder` class. Here, the previously input class gets instanciated, resulting the execution of its constructor method. We can use this to execute arbitrary code and retrieve the output via a call to the `/info` endpoint. @@ -22,7 +22,7 @@ This is known to cause problems [1](https://stackoverflow.com/questions/42720149 In order to exploit this, the first thing to do is write a Java class where to constructor contains the code one wants to execute. In this case, we retrieved a list of users and read their message data containing the flags. We made use of the service's OR mapping functionality. The so build Java class can the be compiled, also using the pre-build Java jar. By doing so we obtain the Java bytecode. This can then be send to the `/register` endpoint, along with the other necessary data. We did so using a python script and the requests library. The output of the code can then be accessed via the `/info` endpoint. -[Java class used in the exploit](ructfe19/fexploit_class.png) +![Java class used in the exploit](ructfe19/fexploit_class.png) #### Considerations @@ -32,17 +32,17 @@ Since this was an attack-defense CTF, there are some additional steps one might Before exploiting the services of other teams, we tried to fix our own service, since we expected other teams to copy our exploit rather quickly. So we deployed a quick-and-dirty fix by filtering out every request that was larger than a certain threshold. We check typical GS requests to the `/register` endpoint and noticed that they where significantly smaller than requests produced by our exploit. This fix proved sufficient for the rest of the CTF since it constrained other teams well enough in the exploiting that we did not loose any flags. Of course, in a real-world scenario this is not an ideal solution. A better patch would be letting `RuntimeClassLoader` inherit from `SecureClassLoader` provided by Java/Kotlin and restrain the loaded class accordingly. This could prove efficient since a standard class used by this service does not run any code so restrictions could be quite strict. -[Patched RuntimeClassLoader class](ructfe19/fpatch_classloader.png) +![Patched RuntimeClassLoader class](ructfe19/fpatch_classloader.png) ### Further developing the exploit When the fix was deployed and the first version of the exploit was busy stealing flags, we had still plenty of time left in the CTF to become creative with this RCE. The most promising idea that came up was, using the RCE to patch other teams services in order for them to not be vulnerable to the exploit any more. This should prevent other teams from exploiting weaker teams who did not patch their service and where therefore an easy target. Of course, in order for us to be able to still exploit the service, we implemented a backdoor in our patch. So we patched the `RuntimeClassLoader` class to include a blacklist for the `loadClass` method, filtering out malicious functionality such as accessing user messages. The backdoor was a simple hard coded string that let every input get through. We then modified our exploit Java class to replace the `RuntimeClassLoader` in the original service jar with our adapted version. -[Placing the modified class in the jar](ructfe19/fpatch_class.png) +![Placing the modified class in the jar](ructfe19/fpatch_class.png) Lastly, we had to force the container to restart to use the patched version of the code. This was easy, since the Docker-compose configuration used had `restart: always` set, meaning the container restarts automatically once the executed program terminates. So we could just call `System.exit(0)` inside our malicious Java class. During the CTF, other teams adapted their exploits to bypass our implemented patch, which in order made us adapt our blacklist and repatch services through our backdoor and so on and so fourth. -[Final version of the patch blacklist](ructfe19/fpatch_advances.png) +![Final version of the patch blacklist](ructfe19/fpatch_advances.png) ### The take away -- 2.43.0