• [Reversing.kr] Position.exe

    2020. 2. 7.

    by. ugonfor

    먼저 문자열을 뽑아보면,,,, correct를 확인할 수 있어요!!

    그래서 당장 그 문자열을 참조하는 곳을 가보죠.

     

    이처럼 되어있는 데, v2의 값을 참조하기때문에, v2값을 정해주는 함수를 check이라 명명했습니다.

     

    그리고 check함수를 열어봐야죠!

    int __stdcall check(int vftable)
    {
      int count_3; // edi
      int count_1; // esi
      int count_2; // esi
      __int16 v5; // bx
      unsigned __int8 name_0; // al
      unsigned __int8 name_1; // al
      unsigned __int8 v8; // bl
      wchar_t *buf_get; // eax
      __int16 serial_7; // di
      wchar_t *v11; // eax
      __int16 serial_6; // di
      wchar_t *v13; // eax
      __int16 v14; // di
      wchar_t *v15; // eax
      __int16 v16; // di
      wchar_t *v17; // eax
      __int16 v18; // di
      unsigned __int8 v19; // al
      unsigned __int8 v20; // al
      unsigned __int8 v21; // bl
      wchar_t *v22; // eax
      __int16 v23; // di
      wchar_t *v24; // eax
      __int16 v25; // di
      wchar_t *v26; // eax
      __int16 v27; // di
      wchar_t *v28; // eax
      __int16 v29; // di
      wchar_t *v30; // eax
      __int16 v31; // si
      unsigned __int8 v32; // [esp+10h] [ebp-28h]
      unsigned __int8 v33; // [esp+10h] [ebp-28h]
      unsigned __int8 v34; // [esp+11h] [ebp-27h]
      unsigned __int8 v35; // [esp+11h] [ebp-27h]
      unsigned __int8 v36; // [esp+13h] [ebp-25h]
      unsigned __int8 v37; // [esp+13h] [ebp-25h]
      unsigned __int8 v38; // [esp+14h] [ebp-24h]
      unsigned __int8 v39; // [esp+14h] [ebp-24h]
      unsigned __int8 v40; // [esp+18h] [ebp-20h]
      unsigned __int8 v41; // [esp+18h] [ebp-20h]
      unsigned __int8 v42; // [esp+19h] [ebp-1Fh]
      unsigned __int8 v43; // [esp+19h] [ebp-1Fh]
      unsigned __int8 v44; // [esp+1Ah] [ebp-1Eh]
      unsigned __int8 v45; // [esp+1Ah] [ebp-1Eh]
      unsigned __int8 v46; // [esp+1Bh] [ebp-1Dh]
      unsigned __int8 v47; // [esp+1Bh] [ebp-1Dh]
      unsigned __int8 v48; // [esp+1Ch] [ebp-1Ch]
      unsigned __int8 v49; // [esp+1Ch] [ebp-1Ch]
      int name; // [esp+20h] [ebp-18h]
      int serial; // [esp+24h] [ebp-14h]
      char buf[4]; // [esp+28h] [ebp-10h]
      int v53; // [esp+34h] [ebp-4h]
    
      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&name);
      count_3 = 0;
      v53 = 0;
      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&serial);
      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(buf);
      LOBYTE(v53) = 2;
      CWnd::GetWindowTextW(vftable + 0x130, &name);
      if ( *(name - 0xC) == 4 )
      {
        count_1 = 0;
        while ( get_argv2_char(&name, count_1) >= 'a' && get_argv2_char(&name, count_1) <= 'z' )
        {
          if ( ++count_1 >= 4 )
          {
    LABEL_7:
            count_2 = 0;
            while ( 1 )
            {
              if ( count_3 != count_2 )
              {
                v5 = get_argv2_char(&name, count_2);
                if ( get_argv2_char(&name, count_3) == v5 )// all char should be diff
                  goto LABEL_2;
              }
              if ( ++count_2 >= 4 )
              {
                if ( ++count_3 < 4 )
                  goto LABEL_7;
                CWnd::GetWindowTextW(vftable + 0x1A4, &serial);
                if ( *(serial - 12) == 11 && get_argv2_char(&serial, 5) == '-' )
                {
                  name_0 = get_argv2_char(&name, 0);
                  v40 = (name_0 & 1) + 5;
                  v48 = ((name_0 >> 4) & 1) + 5;
                  v42 = ((name_0 >> 1) & 1) + 5;
                  v44 = ((name_0 >> 2) & 1) + 5;
                  v46 = ((name_0 >> 3) & 1) + 5;    // name_0 condition
                  name_1 = get_argv2_char(&name, 1);
                  v32 = (name_1 & 1) + 1;
                  v38 = ((name_1 >> 4) & 1) + 1;
                  v34 = ((name_1 >> 1) & 1) + 1;
                  v8 = ((name_1 >> 2) & 1) + 1;
                  v36 = ((name_1 >> 3) & 1) + 1;    // name_1 condition
                  buf_get = GetBuffer(buf);         // 루틴
                  itow_s(v40 + v8, buf_get, 0xAu, 10);
                  serial_7 = get_argv2_char(buf, 0);
                  if ( get_argv2_char(&serial, 0) == serial_7 )// 1. buf를 만들고,
                                                    // 2. 숫자 두개를 더해서 십진수로 바꾼다
                                                    // 3. 그값이 시리얼값이랑 같은 지 확
                  {
                    ReleaseBuffer(buf, -1);
                    v11 = GetBuffer(buf);
                    itow_s(v46 + v36, v11, 0xAu, 10);
                    serial_6 = get_argv2_char(&serial, 1);
                    if ( serial_6 == get_argv2_char(buf, 0) )
                    {
                      ReleaseBuffer(buf, -1);
                      v13 = GetBuffer(buf);
                      itow_s(v42 + v38, v13, 0xAu, 10);
                      v14 = get_argv2_char(&serial, 2);
                      if ( v14 == get_argv2_char(buf, 0) )
                      {
                        ReleaseBuffer(buf, -1);
                        v15 = GetBuffer(buf);
                        itow_s(v44 + v32, v15, 0xAu, 10);
                        v16 = get_argv2_char(&serial, 3);
                        if ( v16 == get_argv2_char(buf, 0) )
                        {
                          ReleaseBuffer(buf, -1);
                          v17 = GetBuffer(buf);
                          itow_s(v48 + v34, v17, 0xAu, 10);
                          v18 = get_argv2_char(&serial, 4);
                          if ( v18 == get_argv2_char(buf, 0) )
                          {
                            ReleaseBuffer(buf, -1);
                            v19 = get_argv2_char(&name, 2);
                            v41 = (v19 & 1) + 5;
                            v49 = ((v19 >> 4) & 1) + 5;
                            v43 = ((v19 >> 1) & 1) + 5;
                            v45 = ((v19 >> 2) & 1) + 5;
                            v47 = ((v19 >> 3) & 1) + 5;
                            v20 = get_argv2_char(&name, 3);
                            v33 = (v20 & 1) + 1;
                            v39 = ((v20 >> 4) & 1) + 1;
                            v35 = ((v20 >> 1) & 1) + 1;
                            v21 = ((v20 >> 2) & 1) + 1;
                            v37 = ((v20 >> 3) & 1) + 1;
                            v22 = GetBuffer(buf);
                            itow_s(v41 + v21, v22, 0xAu, 10);
                            v23 = get_argv2_char(&serial, 6);
                            if ( v23 == get_argv2_char(buf, 0) )
                            {
                              ReleaseBuffer(buf, -1);
                              v24 = GetBuffer(buf);
                              itow_s(v47 + v37, v24, 0xAu, 10);
                              v25 = get_argv2_char(&serial, 7);
                              if ( v25 == get_argv2_char(buf, 0) )
                              {
                                ReleaseBuffer(buf, -1);
                                v26 = GetBuffer(buf);
                                itow_s(v43 + v39, v26, 0xAu, 10);
                                v27 = get_argv2_char(&serial, 8);
                                if ( v27 == get_argv2_char(buf, 0) )
                                {
                                  ReleaseBuffer(buf, -1);
                                  v28 = GetBuffer(buf);
                                  itow_s(v45 + v33, v28, 0xAu, 10);
                                  v29 = get_argv2_char(&serial, 9);
                                  if ( v29 == get_argv2_char(buf, 0) )
                                  {
                                    ReleaseBuffer(buf, -1);
                                    v30 = GetBuffer(buf);
                                    itow_s(v49 + v35, v30, 0xAu, 10);
                                    v31 = get_argv2_char(&serial, 10);
                                    if ( v31 == get_argv2_char(buf, 0) )
                                    {
                                      ReleaseBuffer(buf, -1);
                                      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(buf);
                                      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&serial);
                                      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&name);
                                      return 1;
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                goto LABEL_2;
              }
            }
          }
        }
      }
    LABEL_2:
      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(buf);
      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&serial);
      ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&name);
      return 0;
    }

    함수를 여~~~~얼씨미 보시면 함수가 무슨역할을 하는 지 알 수 있을 겁니다. ^^.. 제가 명명도 해놨고, 주석도 넣어놨기 때문에 이해하기 쉬울거 같습니다.

     

    이름만 봐서 잘 모르겠는 함수 하나는 다음 사이트를 보고 가시죠.

     

    _itoa_s, _itow_s functions

    _itoa_s, _ltoa_s, _ultoa_s, _i64toa_s, _ui64toa_s, _itow_s, _ltow_s, _ultow_s, _i64tow_s, _ui64tow_s In this article --> Converts an integer to a string. These are versions of the _itoa, _itow functions with security enhancements as described in Security F

    docs.microsoft.com

     

    z3모듈을 사용해야 할 거 같네요.

     

    Python z3 모듈

    Python z3 Module 더 추가할 예정! z3에 대해 공부할겸 올려봅니다.. ㅎ 틀린부분이나 팁?그런거 있으면 알려주세요 모듈 링크 : https://github.com/Z3Prover/z3 유용한 외국 문서 : https://ericpony.github.io/..

    realsung.tistory.com

    from z3 import*
    
    n = [BitVec('n{}'.format(i),8) for i in range(4)]
    serial = [7,6,8,7,6,7,7,7,7,6]
    
    s = Solver()
    s.insert( serial[0] == ( ((n[0]     ) & 1) + 5) + (((n[1] >> 2) & 1) +1 ) )
    s.insert( serial[1] == ( ((n[0] >> 3) & 1) + 5) + (((n[1] >> 3) & 1) +1 ) )
    s.insert( serial[2] == ( ((n[0] >> 1) & 1) + 5) + (((n[1] >> 4) & 1) +1 ) )
    s.insert( serial[3] == ( ((n[0] >> 2) & 1) + 5) + (((n[1]     ) & 1) +1 ) )
    s.insert( serial[4] == ( ((n[0] >> 4) & 1) + 5) + (((n[1] >> 1) & 1) +1 ) )
    
    s.insert( serial[5] == ( ((n[2]     ) & 1) + 5) + (((n[3] >> 2) & 1) +1 ) )
    s.insert( serial[6] == ( ((n[2] >> 3) & 1) + 5) + (((n[3] >> 3) & 1) +1 ) )
    s.insert( serial[7] == ( ((n[2] >> 1) & 1) + 5) + (((n[3] >> 4) & 1) +1 ) )
    s.insert( serial[8] == ( ((n[2] >> 2) & 1) + 5) + (((n[3]     ) & 1) +1 ) )
    s.insert( serial[9] == ( ((n[2] >> 4) & 1) + 5) + (((n[3] >> 1) & 1) +1 ) )
    
    s.insert( 0x60 < n[0], n[0] < 0x7b)
    s.insert( 0x60 < n[1], n[1] < 0x7b)
    s.insert( 0x60 < n[2], n[2] < 0x7b)
    
    s.insert( n[3] == ord("p"))
    
    s.check()
    a = s.model()
    
    print(''.join([chr(a[x].as_long()) for x in n]))

    실행시키면 플래그가 나옵니다~!

    'Writeup > Wargame_Writeup' 카테고리의 다른 글

    [ Reversing.kr ] AutoHotkey1 Writeup  (0) 2020.02.12
    [Reversing.kr] Ransomware  (0) 2020.02.07
    [Reversing.kr] Direct3D_FPS  (0) 2020.02.07
    [Flare-on 2019] Write up  (0) 2020.02.05
    [Flare-on 2019] Wopr  (0) 2020.02.05

    댓글