• [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

    댓글