1.思考:
拿到题后我们运行程序后可以看到是一个程序,要求我们输入用户名和密码,,题目附加的txt里面已经告诉了我们用户名,我们就只需要在程序里面找到密码就可以了
2.把程序拖入IDA:
用DIE可以看到程序是一个32位的程序,所以把程序放入32位的IDA里面,使用插件findcrypto查看一下函数用了什么算法:
可以看到是blowfish算法(查了一下是一个对称加密算法,当时的第一反应是动调)
因为找不到main函数,就要找到这个程序里面加密的算法放在哪里的:
先找到winmain函数(winmain函数是windows程序的入口函数,是一个特殊的函数,必须在 Windows GUI 应用程序中使用,在C/C++ 编程中,WinMain 函数取代了标准的 main 函数,这也是我们找不到单独的main函数的原因)
然后又找到DialogFunc函数(因为这个函数在CreateDialogParamA函数里面,CreateDialogParamA函数的作用是创建了一个对话框窗口,并且返回窗口的句柄hWnd,也就是和用户交互的地方)
继续深入,直到这里:
CHAR *__cdecl sub_4577E0(HWND hDlg)
{
CHAR *result; // eax
CHAR *v2; // [esp+10h] [ebp-154h]
void *v3; // [esp+24h] [ebp-140h]
CHAR *v4; // [esp+114h] [ebp-50h]
CHAR *lpString; // [esp+120h] [ebp-44h]
HWND DlgItem; // [esp+12Ch] [ebp-38h]
HWND hWnd; // [esp+138h] [ebp-2Ch]
int v8; // [esp+144h] [ebp-20h]
int WindowTextLengthA; // [esp+150h] [ebp-14h]
__CheckForDebuggerJustMyCode(&unk_52105E);
hWnd = GetDlgItem(hDlg, 1003);
DlgItem = GetDlgItem(hDlg, 1004);
WindowTextLengthA = GetWindowTextLengthA(hWnd);
v8 = GetWindowTextLengthA(DlgItem);
lpString = (CHAR *)j__malloc(__CFADD__(WindowTextLengthA, 16) ? -1 : WindowTextLengthA + 16);
result = (CHAR *)j__malloc(__CFADD__(v8, 16) ? -1 : v8 + 16);
v4 = result;
if ( lpString && result )
{
GetWindowTextA(hWnd, lpString, WindowTextLengthA + 16);
GetWindowTextA(DlgItem, v4, v8 + 16);
v3 = operator new(0x10u);
if ( v3 )
{
sub_451B43(0x10u);
v2 = (CHAR *)sub_450CE3(v3);
}
else
{
v2 = 0;
}
sub_44FC2B(&unk_51D38C, 0x10u); //一些初始化
sub_45126F(lpString, WindowTextLengthA, (int)v4, v8);//算法进入
sub_450199(v2); //数据校验
j__free(lpString);
j__free(v4);
result = v2;
if ( v2 )
return (CHAR *)sub_44F77B(1);
}
return result;
}
然后我们从这一个函数里面进入:
(因为根据代码来看,很可能是处理对话窗口的文本内容的函数,其中:lpString
是一个指向第一个控件文本内容的指针或字符串;WindowTextLengthA
是第一个控件文本内容的长度;(int)v4
是一个指向第二个控件文本内容的指针或字符串;v8
是第二个控件文本内容的长度)
其中
if ( operator new(0x2Cu) )
{
sub_451A4E(0x2Cu);
v8 = (void *)sub_450CBB(Src, a3);
}
else
{
v8 = 0;
}
里面的 v8 = (void *)sub_450CBB(Src, a3);可能就是引用用户名的作用,它的下面应该就分别是引用加密函数和password的作用
3.找出password并解出密码:
下面就得在程序里面找到password了,需要我们把对比的密文拿出来:
这一个函数里面标记的那一个函数应该是执行了某一种检查的功能,下面的if里面的比较应该就是判断用户的密码是否输入正确
如何找到这一个函数的位置呢?
回到之前找到WindowTextLengthA的那个地方,查看下面的那一个函数sub_450199(v2),可以看到这里面就是判断你输入的密码是否正确的地方
这里面v5就是密文,这个时候点进去的话什么也看不到,所以我们需要在这里下断点进行动调:
记住地址,定位到这里进行动调,弹窗就输入题目给出的用户名,密码随便写,然后看运行的结果(因为这里可以看见V5是一个指针,鼠标指向的时候下面写的地址是0x57BB250,而我点进去的时候并不是跳转到我想要的地址,可能ida出bug了,所以得手动跳转看看)
因为直到是地址,多以按d切换成这个样子:
因为是二重指针,所以同上再转变一次进去看到的结果下面就是我们的密文了:
11A51F049550E2508F17E16CF1632B47
因为之前就用插件查到是个blowfish算法加密,在网上找一个在线解密的网站直接解密就能得到flag:D0g3{UzBtZTBuZV9EMGczQHRoZWJsdWVmMXNo
(之所以这么找的原因是因为memcmp是这个程序的比较函数,它的作用是比较两个内存区域的内容是否相等, 而我们在汇编里面可以看到比较的数据是被push压入栈里面了的,所以要在栈里面去找)
Comments | NOTHING