Reverse Engineering을 통해 키를 찾는 방법
LRESULT __stdcallWndProc(HWND hWndParent, UINT Msg, WPARAM wParam, LPARAM lParam)
{
// 각종 변수와 버퍼 선언
HDC hdc;
struct tagPAINTSTRUCT Paint;
CHAR Buffer[100];
struct tagRECT Rect;
// 문자열 로드
LoadStringA(hInstance, 0x6Au, Buffer, 100);
if (Msg > 273) {
if (Msg == 517) {
if (strlen(String1) > 6) ExitProcess(0);
if (strlen(String1)) {
// 문자열 복사 및 MD5 인코딩
memcpy(v17, String1, strlen(String1));
md5_encode(String1, strlen(String1), (LPSTR)String1);
// 고정 문자열 설정
strcpy(Str, "0kk`d1a`55k222k2a776jbfgd`06cjjb");
memset(&Str[33], 0, 220u);
// XOR 연산
strcpy(v11, "SS");
*(_DWORD *)&v11[3] = 0;
v12 = 0;
v13 = 0;
xor(v11, Str, strlen(Str));
// 비교 및 유효성 검사
if (_strcmpi(String1, Str)) {
SetWindowTextA(hWndParent, "flag{}");
MessageBoxA(hWndParent, "Are you kidding me?", "^_^", 0);
ExitProcess(0);
}
// 추가 XOR 및 메시지 출력
memcpy(str2, &unk_423030, 0x32u);
str2_len = strlen(str2);
xor(v17, str2, str2_len);
MessageBoxA(hWndParent, str2, 0, 50u);
}
++dword_428D54;
}
else if (Msg != 520) {
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
}
else {
if (dword_428D54 == 16) {
SetWindowTextA(hWndParent, "ctf");
MessageBoxA(hWndParent, "Are you kidding me?", Buffer, 0);
}
++dword_428D54;
}
}
else {
switch (Msg) {
case 0x111u:
v27 = (unsigned __int16)wParam;
v26 = HIWORD(wParam);
if (v27 == 104) {
DialogBoxParamA(hInstance, (LPCSTR)0x67, hWndParent, (DLGPROC)DialogFunc, 0);
}
else if (v27 == 105) {
DestroyWindow(hWndParent);
}
break;
case 2u:
PostQuitMessage(0);
break;
case 0xFu:
hdc = BeginPaint(hWndParent, &Paint);
GetClientRect(hWndParent, &Rect);
DrawTextA(hdc, Buffer, strlen(Buffer), &Rect, 1u);
EndPaint(hWndParent, &Paint);
break;
default:
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
}
}
return 0;
}
키 찾기 로직 분석
- MD5 인코딩:
String1을 MD5로 인코딩 - XOR 연산: 고정 문자열과 XOR 후 비교
- 조건 검사:
_strcmpi를 통해 값을 비교 - 최종 출력:
str2를 통해 플래그 출력
Python을 사용한 키 복구
import hashlib
from tqdm import tqdm
# 고정 문자열
a = "0kk`d1a`55k222k2a776jbfgd`06cjjb"
b = "SS"
# XOR 후 복호화
a = list(a)
for i in range(len(a)):
a[i] = chr(ord(a[i]) ^ ord(b[i % 2]))
a = "".join(a)
# MD5 해시 비교
for i in tqdm(range(10000, 9999999)):
encrypted = hashlib.md5(str(i).encode()).hexdigest()
if encrypted == a:
tqdm.write(str(i))
예제 XOR 연산
a = "123321"
b = [0x57, 0x5E, 0x52, 0x54, 0x49, 0x5F, 0x01, 0x6D, 0x69, 0x46, 0x02, 0x6E, 0x5F, 0x02, 0x6C, 0x57, 0x5B, 0x54, 0x4C]
for i in range(len(b)):
b[i] = chr(ord(a[i % 6]) ^ b[i])
print(b[i], end="")
이 코드들은 최종적으로 플래그 값을 출력하기 위해 사용됩니다.