ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • xor - pwnable.xyz
    Write-ups/pwnable.xyz 2020. 2. 11. 23:45

    Prob Info

     

    Checksec

     

    int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      int v3; // [rsp+Ch] [rbp-24h]
      __int64 v4; // [rsp+10h] [rbp-20h]
      __int64 v5; // [rsp+18h] [rbp-18h]
      __int64 v6; // [rsp+20h] [rbp-10h]
      unsigned __int64 v7; // [rsp+28h] [rbp-8h]
    
      v7 = __readfsqword(0x28u);
      puts("The Poopolator");
      setup("The Poopolator", argv);
      while ( 1 )
      {
        v6 = 0LL;
        printf(format);
        v3 = _isoc99_scanf("%ld %ld %ld", &v4, &v5, &v6);
        if ( !v4 || !v5 || !v6 || v6 > 9 || v3 != 3 )
          break;
        result[v6] = v5 ^ v4;
        printf("Result: %ld\n", result[v6]);
      }
      exit(1);
    }

    숫자 세개를 입력받는데 모두 0이 아니고 v6는 9보다 커야한다.

     

    .text:0000000000000AB3                 mov     rax, [rbp+var_10]
    .text:0000000000000AB7                 cmp     rax, 9
    .text:0000000000000ABB                 jg      short loc_AC3

    v6가 음수여도 조건문을 통과할 수 있다. 그렇게 되면 result보다 아래에 있는 영역에 접근 할 수 있는데, Full RELRO와 PIE가 걸려있어 GOT Overwrite도 불가능하다. 일단 gdb에서 vmmap을 확인해 봤다.

     

    pwndbg> vmmap
    LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
        0x555555554000     0x555555555000 rwxp     1000 0      /home/dpster/Desktop/Pwnable/pwnable_xyz/xor/image/challenge/challenge
        0x555555755000     0x555555756000 r--p     1000 1000   /home/dpster/Desktop/Pwnable/pwnable_xyz/xor/image/challenge/challenge
        0x555555756000     0x555555757000 rw-p     1000 2000   /home/dpster/Desktop/Pwnable/pwnable_xyz/xor/image/challenge/challenge
        0x555555757000     0x555555778000 rw-p    21000 0      [heap]
        0x7ffff7a0d000     0x7ffff7bcd000 r-xp   1c0000 0      /lib/x86_64-linux-gnu/libc-2.23.so
        0x7ffff7bcd000     0x7ffff7dcd000 ---p   200000 1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
        0x7ffff7dcd000     0x7ffff7dd1000 r--p     4000 1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
        0x7ffff7dd1000     0x7ffff7dd3000 rw-p     2000 1c4000 /lib/x86_64-linux-gnu/libc-2.23.so
        0x7ffff7dd3000     0x7ffff7dd7000 rw-p     4000 0
        0x7ffff7dd7000     0x7ffff7dfd000 r-xp    26000 0      /lib/x86_64-linux-gnu/ld-2.23.so
        0x7ffff7fdd000     0x7ffff7fe0000 rw-p     3000 0
        0x7ffff7ff7000     0x7ffff7ffa000 r--p     3000 0      [vvar]
        0x7ffff7ffa000     0x7ffff7ffc000 r-xp     2000 0      [vdso]
        0x7ffff7ffc000     0x7ffff7ffd000 r--p     1000 25000  /lib/x86_64-linux-gnu/ld-2.23.so
        0x7ffff7ffd000     0x7ffff7ffe000 rw-p     1000 26000  /lib/x86_64-linux-gnu/ld-2.23.so
        0x7ffff7ffe000     0x7ffff7fff000 rw-p     1000 0
        0x7ffffffde000     0x7ffffffff000 rw-p    21000 0      [stack]
    0xffffffffff600000 0xffffffffff601000 r-xp     1000 0      [vsyscall]

    특이하게 code영역에 w 권한을 줘서 쓰기가 가능하다. 일단 PIE가 걸려있어도 offset은 같기 때문에 code영역에 접근해 수정을 할 수 있다.

     

    .bss:0000000000202200 ; _QWORD result[10]
    .bss:0000000000202200 result          dq 0Ah dup(?)           ; DATA XREF: main+B0↑o
    .bss:0000000000202200                                         ; main+C7↑o
    .text:0000000000000AC3                 mov     edi, 1          ; status
    .text:0000000000000AC8                 call    exit

    이 부분을 수정할 것이다. 헥스로 보면 아래와 같다.

     

    E8 63 FD FF FF

    call의 opcode는 오프셋을 구해서 만들 수 있다.

    E8 54 FF FF FF

    저 위치에서 win을 호출하기 위한 opcode이다. 이를 0xAC8에 적어주면 된다.

     

    Reference


    https://umbum.tistory.com/102

    'Write-ups > pwnable.xyz' 카테고리의 다른 글

    Free Spirit - pwnable.xyz  (0) 2020.02.12
    two targets - pwnable.xyz  (0) 2020.02.12
    note - pwnable.xyz  (0) 2020.02.11
    GrownUp - pwnable.xyz  (0) 2020.02.11
    misalignment - pwnable.xyz  (0) 2020.02.11

    댓글

Designed by Tistory.