ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • two targets - pwnable.xyz
    Write-ups/pwnable.xyz 2020. 2. 12. 00:10

    Prob Info
    Checksec

     

    두가지 방법으로 풀 수 있게 만든 문제이다. 

    int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      char *v3; // rsi
      const char *v4; // rdi
      int v5; // eax
      char s; // [rsp+10h] [rbp-40h]
      __int64 v7; // [rsp+30h] [rbp-20h]
      char *v8; // [rsp+40h] [rbp-10h]
      unsigned __int64 v9; // [rsp+48h] [rbp-8h]
    
      v9 = __readfsqword(0x28u);
      setup(*(_QWORD *)&argc, argv, envp);
      v3 = 0LL;
      v4 = &s;
      memset(&s, 0, 0x38uLL);
      while ( 1 )
      {
        while ( 1 )
        {
          print_menu(v4, v3);
          v5 = read_int32();
          if ( v5 != 2 )
            break;
          printf("nationality: ");
          v3 = (char *)&v7;
          v4 = "%24s";
          __isoc99_scanf("%24s", &v7);
        }
        if ( v5 > 2 )
        {
          if ( v5 == 3 )
          {
            printf("age: ");
            v3 = v8;
            v4 = "%d";
            __isoc99_scanf("%d", v8);
          }
          else if ( v5 == 4 )
          {
            v4 = &s;
            if ( (unsigned __int8)auth((__int64)&s) )
              win();
          }
          else
          {
    LABEL_14:
            v4 = "Invalid";
            puts("Invalid");
          }
        }
        else
        {
          if ( v5 != 1 )
            goto LABEL_14;
          printf("name: ");
          v3 = &s;
          v4 = "%32s";
          __isoc99_scanf("%32s", &s);
        }
      }
    }

     

    _BOOL8 __fastcall auth(__int64 a1)
    {
      signed int i; // [rsp+18h] [rbp-38h]
      char s1[8]; // [rsp+20h] [rbp-30h]
      __int64 v4; // [rsp+28h] [rbp-28h]
      __int64 v5; // [rsp+30h] [rbp-20h]
      __int64 v6; // [rsp+38h] [rbp-18h]
      unsigned __int64 v7; // [rsp+48h] [rbp-8h]
    
      v7 = __readfsqword(0x28u);
      *(_QWORD *)s1 = 0LL;
      v4 = 0LL;
      v5 = 0LL;
      v6 = 0LL;
      for ( i = 0; (unsigned int)i <= 0x1F; ++i )
        s1[i] = ((*(_BYTE *)(a1 + i) >> 4) | 16 * *(_BYTE *)(a1 + i)) ^ *((_BYTE *)main + i);
      return strncmp(s1, &s2, 0x20uLL) == 0;
    }

    이 함수에서 main함수의 바이트 값을 하나씩 연산하여 일치하면 통과할 수 있다. 

    Exploit 1


    첫번째 방법은 간단하게 생각해 auth함수를 그대로 역산하는 것이다. 메인 함수의 바이트값들과 auth 값을 이용해 그대로 연산을 해줘 값을 입력하면 플래그를 받을 수 있다.

     

    Exploit 2


    두번째 방법은 취약점을 이용하는 것이다. 

          printf("nationality: ");
          v3 = (char *)&v7;
          v4 = "%24s";
          __isoc99_scanf("%24s", &v7);

    이 부분에서 bof가 일어나는데, v7 다음의 v8을 덮을 수 있다. 

            printf("age: ");
            v3 = v8;
            v4 = "%d";
            __isoc99_scanf("%d", v8);

    v8은 이곳에서 쓰이는데, 숫자를 입력할 수 있다. 이를 이용해 v8을 GOT로 덮고 win 함수의 주소로 GOT Overwrite해주면 된다.

     

    Exploit 3


    두번째 풀이를 하고나서 잘 생각해보니 쉘을 딸 수 있을것 같았다. 같은 방법으로 atoi의 GOT를 system@plt로 덮고 "/bin/sh"을 넣어줬다. 하지만 scanf()에서 %d로 받기 때문에 4바이트만 덮을 수 있어 이미 한 번 호출된 atoi는 상위 4바이트에 값이 남아있어 strcmp의 GOT를 덮었다.

     

    Shell

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

    TLSv00 - pwnable.xyz  (0) 2020.02.12
    Free Spirit - pwnable.xyz  (0) 2020.02.12
    xor - pwnable.xyz  (0) 2020.02.11
    note - pwnable.xyz  (0) 2020.02.11
    GrownUp - pwnable.xyz  (0) 2020.02.11

    댓글

Designed by Tistory.