문제 정보

    매우 쉬운 전형적인 reversing문제.

    문제 파일

    basic_CrackMe/
    ├── flag.enc
    ├── prob
    └── prob.exe
    
    0 directories, 3 files

    flag.enc 암호화된 텍스트 파일,
    실행 파일은 flag, flag.exe 각각 리눅스와 윈도우용 둘다 존재한다.


    풀이

    int __cdecl sub_401500(int a1)
    {
      __int64 v1; // rax
      __int64 v2; // rcx
      __int64 v3; // rax
      __int64 v4; // rax
      int i; // [esp+Ch] [ebp-14h]
    
      for ( i = 0; i <= 80; ++i )
      {
        v1 = (Str[i % dword_4054F4] * Str[i % dword_4054F4] + i) ^ *(char *)(i + a1);
        dword_405040[2 * i] = v1;
        dword_405044[2 * i] = HIDWORD(v1);
        LODWORD(v2) = dword_405040[2 * i];
        HIDWORD(v2) = dword_405044[2 * i];
        v3 = v2 - Str[i % dword_4054F4];
        dword_405040[2 * i] = v3;
        dword_405044[2 * i] = HIDWORD(v3);
        LODWORD(v2) = dword_405040[2 * i];
        HIDWORD(v2) = dword_405044[2 * i];
        v4 = v2 + i;
        dword_405040[2 * i] = v4;
        dword_405044[2 * i] = HIDWORD(v4);
      }
      return 0;
    }

    Str = “have a good day! enjoy wargame!”
    dword_4054f4 = Str 문자열 크기,
    a1에는 암호화되지 않은 원문 문자열을 나타내는 포인터 주소를 각각 나타낸다.

    총 81번을 반복하고 카운트 변수는 i이다.
    v1 = (Str[i % 31] * Str[i % 31] + i) ^ a1[i];
    v3 = v1 – Str[i % 31];
    v4 = v3 + i;

    이를 테면,
    a1이 “ABCDEFGHIJKLMNOPQRSTUVWXYZ” 문자열이 있다고 가정하자.
    이 문자열 크기는 총 26바이트인데,
    총 81번 반복하므로 나머지 55바이트(=81-26)는 00 으로 채워진다.

    초기에는
    v1 = (Str[0 % 31] * Str[0 % 31] + 0) ^ a1[0]
    = 0x2A40 ^ 0x41 = 0x2a01

    v3 = v1 – Str[0 % 31]
    = 0x2a01 – 0x68 = 0x2999

    v4 = v3 + 0
    = 0x2999

    두번째 루프문에서는
    v1 = (Str[1 % 31] * Str[1 % 31] + 1) ^ a1[1]
    = 0x24c2 ^ 0x42 = 0x2480

    v3 = v1 – Str[1 % 31]
    = 0x2480 – 0x61 = 0x241f

    v4 = 0x241f + 1
    = 0x2420

    이렇게 암호화된 문자가 하나씩 만들어진다.

    암호화시키는 코드를 파이썬으로 구현하면 다음과 같다.

    #enc.py
    
    def read_file(filename):
        with open(filename, 'rb+') as file:
            data = file.read()
        return data
    
    def save_file(filename, data):
        with open(filename, 'wb+') as file:
            file.write(data)
    
    GDStr = "have a good day! enjoy wargame!"
    GDStrLen = len(GDStr)
    filename = 'flag.txt'
    filecontext = read_file(filename)
    
    if(len(filecontext) < 81):
        filecontext += bytes(81 - len(filecontext))
    
    enc = ''
    
    for i in range(81):
        v1 = (ord(GDStr[i % GDStrLen]) * ord(GDStr[i % GDStrLen]) + i) ^ filecontext[i]
        v3 = v1 - ord(GDStr[i % GDStrLen])
        result = v3 + i
        enc += hex(result).upper()
    
    print(enc)
    save_file('tmp.enc', enc.encode('utf-8'))

    복호화시키는 코드는 역순으로 계산시키면 답이 나온다.

    def read_file(filename):
        with open(filename, 'rb+') as file:
            data = file.read()
        return data
    
    GDStr = "have a good day! enjoy wargame!"
    GDStrLen = len(GDStr)
    
    filename = 'flag.enc'
    filecontext = read_file(filename)
    
    filecontext = filecontext.decode('utf-8')
    filecontext = filecontext.split('0X')[1:]
    filecontext = [int(val, 16) for val in filecontext]
    
    dec = ''
    
    for i in range(81):
        v3 = filecontext[i] - i
        v1 = v3 + ord(GDStr[i % GDStrLen])
        v0 = v1 ^ (ord(GDStr[i % GDStrLen]) * ord(GDStr[i % GDStrLen]) + i)
        print(chr(v0), end='')

    FLAG

    PS C:\Users\Seo Hyun-gyu\Desktop\basic_CrackMe\test> python3 dec.py
    Congratulation!:
    +DH{0h_y0u_6ot_cr4ck_m3_4nd_h4ve_good_d4y~}+
    good luck new year!

    DH{0h_y0u_6ot_cr4ck_m3_4nd_h4ve_good_d4y~}

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다