콘텐츠로 건너뛰기

basic_CrackMe

문제 정보

매우 쉬운 전형적인 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~}

태그:

답글 남기기