BUUCTF-findKey
查壳,莫得,32位
载入 IDA,搜索字符串
跟进
发现左边地址是红色的,往上看到有花指令,两个一样的指令删掉一处就可以
然后选中这一块区域按 P 将汇编代码转换为函数,F5 反编译
LRESULT __stdcall sub_401640(HWND hWndParent, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int v5; // eax
size_t v6; // eax
DWORD v7; // eax
int v8; // eax
int v9; // eax
int v10; // [esp+4Ch] [ebp-400h]
UINT v11; // [esp+50h] [ebp-3FCh]
CHAR v12[256]; // [esp+54h] [ebp-3F8h] BYREF
char v13[7]; // [esp+154h] [ebp-2F8h] BYREF
__int16 v14; // [esp+15Bh] [ebp-2F1h]
char v15; // [esp+15Dh] [ebp-2EFh]
char Str[253]; // [esp+160h] [ebp-2ECh] BYREF
__int16 v17; // [esp+25Dh] [ebp-1EFh]
char v18; // [esp+25Fh] [ebp-1EDh]
CHAR v19[256]; // [esp+260h] [ebp-1ECh] BYREF
CHAR String[4]; // [esp+360h] [ebp-ECh] BYREF
int v21; // [esp+364h] [ebp-E8h]
__int16 v22; // [esp+368h] [ebp-E4h]
CHAR Text[32]; // [esp+36Ch] [ebp-E0h] BYREF
struct tagRECT Rect; // [esp+38Ch] [ebp-C0h] BYREF
CHAR Buffer[100]; // [esp+39Ch] [ebp-B0h] BYREF
HDC hdc; // [esp+400h] [ebp-4Ch]
struct tagPAINTSTRUCT Paint; // [esp+404h] [ebp-48h] BYREF
int v28; // [esp+444h] [ebp-8h]
int v29; // [esp+448h] [ebp-4h]
LoadStringA(hInstance, 0x6Au, Buffer, 100);
v11 = Msg;
if ( Msg > 0x111 )
{
if ( v11 == 517 )
{
if ( strlen((const char *)String1) > 6 )
ExitProcess(0);
if ( strlen((const char *)String1) )
{
memset(v19, 0, sizeof(v19));
v6 = strlen((const char *)String1);
memcpy(v19, String1, v6);
v7 = strlen((const char *)String1);
sub_40101E(String1, v7, (LPSTR)String1);
strcpy(Str, "0kk`d1a`55k222k2a776jbfgd`06cjjb");
memset(&Str[33], 0, 0xDCu);
v17 = 0;
v18 = 0;
strcpy(v13, "SS");
*(_DWORD *)&v13[3] = 0;
v14 = 0;
v15 = 0;
v8 = strlen(Str);
sub_401005(v13, (int)Str, v8);
if ( _strcmpi((const char *)String1, Str) )
{
SetWindowTextA(hWndParent, "flag{}");
MessageBoxA(hWndParent, "Are you kidding me?", "^_^", 0);
ExitProcess(0);
}
memcpy(v12, &unk_423030, 0x32u);
v9 = strlen(v12);
sub_401005(v19, (int)v12, v9);
MessageBoxA(hWndParent, v12, 0, 0x32u);
}
++dword_428D54;
}
else
{
if ( v11 != 520 )
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
if ( dword_428D54 == 16 )
{
strcpy(String, "ctf");
v21 = 0;
v22 = 0;
SetWindowTextA(hWndParent, String);
strcpy(Text, "Are you kidding me?");
MessageBoxA(hWndParent, Text, Buffer, 0);
}
++dword_428D54;
}
}
else
{
switch ( v11 )
{
case 0x111u:
v29 = (unsigned __int16)wParam;
v28 = HIWORD(wParam);
v10 = (unsigned __int16)wParam;
if ( (unsigned __int16)wParam == 104 )
{
DialogBoxParamA(hInstance, (LPCSTR)0x67, hWndParent, (DLGPROC)DialogFunc, 0);
}
else
{
if ( v10 != 105 )
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
DestroyWindow(hWndParent);
}
break;
case 2u:
PostQuitMessage(0);
break;
case 0xFu:
hdc = BeginPaint(hWndParent, &Paint);
GetClientRect(hWndParent, &Rect);
v5 = strlen(Buffer);
DrawTextA(hdc, Buffer, v5, &Rect, 1u);
EndPaint(hWndParent, &Paint);
break;
default:
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
}
}
return 0;
}
看到关键部分
关键函数为 sub_401005,传入 Str 与 v13,查看一下,就是一个简单的异或操作
异或后的字符串与 String1 比较,String1 是通过 sub_40101E 变换了的,如果比较结果一致,则将未变换过的 String1 与 unk_423030 进行异或得到 flag
看一下 sub_40101E 可以发现是 MD5 加密,所以总的解题流程如下:
按照 sub_40101E 的逻辑将 Str 与 v13 异或,异或的结果进行 MD5 解密,再将结果传入 sub_40101E 与 unk_423030 进行异或得到 flag
脚本如下:
#include <bits/stdc++.h>
using namespace std;
string str = "0kk`d1a`55k222k2a776jbfgd`06cjjb";
unsigned char ida_chars[] = {
0x57, 0x5E, 0x52, 0x54, 0x49, 0x5F, 0x01, 0x6D, 0x69, 0x46,
0x02, 0x6E, 0x5F, 0x02, 0x6C, 0x57, 0x5B, 0x54, 0x4C
};
string s = "SS";
inline void sub_401005_1() {
int len = str.length();
for (int i = 0; i < len; i++) {
int num1 = str[i];
int num2 = s[i % 2];
str[i] = (char)(num1 ^ num2);
}
cout << str << endl;
}
inline void sub_401005_2() {
int len = 19;
for (int i = 0; i < len; i++) {
int num1 = ida_chars[i];
int num2 = s[i % 6];
ida_chars[i] = (char)(num1 ^ num2);
}
cout << ida_chars << endl;
}
int main() {
sub_401005_1();
s = "123321";
sub_401005_2();
system("pause");
return 0;
}
flag{n0_Zu0_n0_die}