ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • l33t-ness - pwnable.xyz
    Write-ups/pwnable.xyz 2020. 2. 12. 20:43

    Prob Info


    Prob Info
    Checksec

     

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      setup();
      puts("The l33t-ness level.");
      if ( (unsigned __int8)round_1() && (unsigned __int8)round_2() && (unsigned __int8)round_3() )
        win();
      return 0;
    }

    main함수는 간단하다. round_1, 2, 3을 모두 통과하면 된다. 하나씩 살펴보자.

     

    _BOOL8 round_1()
    {
      _BOOL8 result; // rax
      int v1; // [rsp+8h] [rbp-38h]
      int v2; // [rsp+Ch] [rbp-34h]
      char s; // [rsp+10h] [rbp-30h]
      __int64 v4; // [rsp+20h] [rbp-20h]
      unsigned __int64 v5; // [rsp+38h] [rbp-8h]
    
      v5 = __readfsqword(0x28u);
      puts("=== 1eet ===");
      memset(&s, 0, 0x20uLL);
      printf("x: ", 0LL);
      read(0, &s, 0x10uLL);
      printf("y: ", &s);
      read(0, &v4, 0x10uLL);
      if ( strchr(&s, '-') || strchr((const char *)&v4, '-') )
        return 0LL;
      v1 = atoi(&s);
      v2 = atoi((const char *)&v4);
      if ( v1 <= 1336 && v2 <= 1336 )
        result = v1 - v2 == 1337;
      else
        result = 0LL;
      return result;
    }

    입력받은 값에 '-'가 들어가면 안되고 둘 다 1336보다 작아야하며 두 값을 빼면 1337이 되어야 한다. 두 숫자 모두 atoi함수로 받고 있으니 signed int형으로 반환될 것이다. 4바이트에서 2의 보수를 통해 음수값을 나타내면 조건을 우회할 수 있다. 

     

    _BOOL8 round_2()
    {
      __int64 v0; // rcx
      __int64 v1; // r8
      __int64 v2; // r9
      int v4; // [rsp+0h] [rbp-10h]
      int v5; // [rsp+4h] [rbp-Ch]
      unsigned __int64 v6; // [rsp+8h] [rbp-8h]
    
      v6 = __readfsqword(0x28u);
      puts("=== t00leet ===");
      v4 = 0;
      v5 = 0;
      _isoc99_scanf("%d %d", &v4, &v5, v0, v1, v2);
      return v4 > 1 && v5 > 1337 && v4 * v5 == 1337;
    }

    이 문제도 v4가 1보다 커야하고 v5가 1337보다 클 때 곱해서 1337을 만들어야하는데, int32이기 때문에 곱해서 4바이트 이하가 1337만 되면 통과할 수 있다.

     

    _BOOL8 round_3()
    {
      signed int i; // [rsp+0h] [rbp-30h]
      __int64 v2; // [rsp+10h] [rbp-20h]
      __int64 v3; // [rsp+18h] [rbp-18h]
      int v4; // [rsp+20h] [rbp-10h]
      unsigned __int64 v5; // [rsp+28h] [rbp-8h]
    
      v5 = __readfsqword(0x28u);
      puts("=== 3leet ===");
      v2 = 0LL;
      v3 = 0LL;
      v4 = 0;
      _isoc99_scanf("%d %d %d %d %d", &v2, (char *)&v2 + 4, &v3, (char *)&v3 + 4, &v4);
      for ( i = 1; i <= 4; ++i )
      {
        if ( *((_DWORD *)&v2 + i) < *((_DWORD *)&v2 + i - 1) )
          return 0LL;
      }
      return HIDWORD(v3) + (_DWORD)v3 + HIDWORD(v2) + (_DWORD)v2 + v4 == HIDWORD(v3)
                                                                       * (_DWORD)v3
                                                                       * HIDWORD(v2)
                                                                       * (_DWORD)v2
                                                                       * v4;
    }

    for문 내의 첫번째 조건은 입력받은 4바이트 짜리 값 4개가 모두 다음값보다 크면 안된다는 것이다. 그리고 네 값을 더한 값과 곱한 값이 같으면 되는데, 이 조건은 네 값이 모두 같으면 안된다는 조건이 없으므로 모두 0을 넣어주면 된다.

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

    fspoo - pwnable.xyz  (0) 2020.02.13
    Game - pwnable.xyz  (0) 2020.02.12
    Jmp table - pwnable.xyz  (0) 2020.02.12
    TLSv00 - pwnable.xyz  (0) 2020.02.12
    Free Spirit - pwnable.xyz  (0) 2020.02.12

    댓글

Designed by Tistory.