리버싱

Position(reversing.kr) write-up

He110 2023. 11. 19. 21:17

정말 빡센 문제입니다...

이렇게 입력을 받는데 체크하는 버튼은 없습니다. 따라서 input값들이 다 맞아 떨어질때 correct를 출력할 것 입니다.

저는 처음에 감을 못잡아서 ollydbg로 전체 브레이크 포인트를 걸어서 디버깅작업을 해봤습니다. (노가다...)

결과적으로 저기 함수(Position)에서 연산이 일어납니다.

하여튼 이 뒤로 개노가다여서 노가다한 내용을 정리해보았습니다.

ABCDEF COUNT = 7 (제가 입력한 값)
총 NAME COUNT = 4 (프로그램에서 원하는 값)
입력 첫 문자 < 0x61 점프됨
입력 첫 문자 >0x61
 '' >0x7A 되면 점프됨 따라서 < 0x7A가 되어야됨 그래서 name 한 글자 당 모두 0x61<inputs<0x7a가 되어야 됨.

다 다른 문자이여만 함
serial count= 11
(char)0x2D = -

여기까지가 ollydbg로 분석한 내용입니다. 더 이상은 힘들어서 ida로 갈아탔습니다.

이 함수를 보면 correct문구를 보실 수 있죠? 그 전에 호출되는 함수(sub_401740)를 더블클릭합니다.

여기 코드가 좀 더럽네요.. 

v6는 name의 첫번째 element값입니다.  그리고 v8는 name의 두번째 element값입니다. 이것들을 이용해서 연산을 해주고 최종적으로v7 + v9 = v10이 되어야 합니다.  이때 v10은 serial의 첫번째 값입니다. 밑에도 마찬가지 입니다.

아 힘드네요... 이러한 정보들을 이용해서 c++로 코드를 짜봤습니다. brute force공격이네요. 코드는 스스로 분석해보세보시는 것을 추천드려요.. 지금 제가 너무 졸려요..

 

#include <iostream>
using namespace std;

int main()
{
    int v1; // edi
    int v3; // esi
    int v4; // esi
    __int16 v5; // bx
    unsigned __int8 v6; // al
    unsigned __int8 v7; // ST2C_1
    unsigned __int8 v8; // al
    unsigned __int8 v9; // bl
    wchar_t* v10; // eax
    __int16 v11; // di
    wchar_t* v12; // eax
    __int16 v13; // di
    wchar_t* v14; // eax
    __int16 v15; // di
    wchar_t* v16; // eax
    __int16 v17; // di
    wchar_t* v18; // eax
    __int16 v19; // di
    unsigned __int8 v20; // al
    unsigned __int8 v21; // ST2C_1
    unsigned __int8 v22; // al
    unsigned __int8 v23; // bl
    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; // di
    wchar_t* v32; // eax
    __int16 v33; // si
    unsigned __int8 v34; // [esp+10h] [ebp-28h]
    unsigned __int8 v35; // [esp+10h] [ebp-28h]
    unsigned __int8 v36; // [esp+11h] [ebp-27h]
    unsigned __int8 v37; // [esp+11h] [ebp-27h]
    unsigned __int8 v38; // [esp+13h] [ebp-25h]
    unsigned __int8 v39; // [esp+13h] [ebp-25h]
    unsigned __int8 v40; // [esp+14h] [ebp-24h]
    unsigned __int8 v41; // [esp+14h] [ebp-24h]
    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 v50; // [esp+20h] [ebp-18h]
    int v51; // [esp+24h] [ebp-14h]
    char v52; // [esp+28h] [ebp-10h]
    int v53; // [esp+34h] [ebp-4h]

	for(int i=0x61;i<=0x7a;i++)
		for (int j = 0x61; j <= 0x7a; j++)
			for (int k = 0x61; k <= 0x7a; k++)
			{
                v7 = (i & 1) + 5;
                v48 = ((i >> 4) & 1) + 5;
                v42 = ((i >> 1) & 1) + 5;
                v44 = ((i >> 2) & 1) + 5;
                v46 = ((i >> 3) & 1) + 5;   
                
                v34 = (j & 1) + 1;
                v40 = ((j >> 4) & 1) + 1;
                v36 = ((j >> 1) & 1) + 1;
                v9 = ((j >> 2) & 1) + 1;
                v38 = ((j >> 3) & 1) + 1;

                if (v7 + v9 == 7&&v46+v38==6&& v42 + v40 == 8&& v44 + v34 == 7 
                    && v48 + v36 == 6)
                {
                    v21 = (k & 1) + 5;
                    v49 = ((k >> 4) & 1) + 5;
                    v43 = ((k >> 1) & 1) + 5;
                    v45 = ((k >> 2) & 1) + 5;
                    v47 = ((k >> 3) & 1) + 5;
                    
                    v22 = (int)'p';

                    v35 = (v22 & 1) + 1;
                    v41 = ((v22 >> 4) & 1) + 1;
                    v37 = ((v22 >> 1) & 1) + 1;
                    v23 = ((v22 >> 2) & 1) + 1;
                    v39 = ((v22 >> 3) & 1) + 1;
                    if (v21 + v23 == 7 && v47 + v39 == 7 && v43 + v41 == 7 && v45 + v35 == 7
                        && v49 + v37 == 6)
                    {
                        cout << (char)i << (char)j << (char)k << 'p'<<endl;
                    }
                }
			}
}

 

이 코드를 컴파일 하면 다음과 같은 결과를 볼 수 있습니다.

그래서 name은 다음과 같습니다. 문제에서 name이 여러개라고 했는데 진짜네요..

name은 bump, cqmp, ftmp 다 됩니다.

하지만 auth인증되는 값은 bump입니다. 여러분도 해보세요..  

 

끝.. 

추가정보

알고보니 그냥 name입력하고 시리얼 입력한 다음에 enter누른 뒤 올리디버거에서 분석할 수 도 있었음.  엔터가 될 줄 몰랐음...

correct 위에 함수에 브레이크 포인트걸고 연속 두번 f9하면 이벤트 걸림.