-
-
[原创]2019看雪CTF 第四题:达芬奇密码
-
2019-6-27 00:50 7592
-
运行程序,随便输入一串字符,弹出提示框:
将程序拖入IDA,打开Strings窗口搜索 Wrong
emmmm,居然没有搜索到,这表示程序会在运行过程中,动态解密所需字符串。
动态调试,果然在程序内存中发现有Wrong字符串,计算出Wrong字符串偏移是0x1FDE
IDA打开程序,按住Ctrl+S,找出基址为0x400000,Wrong字符串在程序中偏移地址为0x400000+0x1FDE=0x401FDE
按G,输入0x401FDE,跳转到对应位置,按F5反编译成伪代码:
int __thiscall sub_401EA0(CWnd *this) { CWnd *v1; // esi int v2; // eax WCHAR String; // [esp+Ch] [ebp-310h] char v5; // [esp+Eh] [ebp-30Eh] char v6; // [esp+20Ch] [ebp-110h] char v7; // [esp+20Dh] [ebp-10Fh] DWORD v8; // [esp+30Ch] [ebp-10h] CWnd *v9; // [esp+310h] [ebp-Ch] unsigned int v10; // [esp+314h] [ebp-8h] DWORD flOldProtect; // [esp+318h] [ebp-4h] v1 = this; v9 = this; String = 0; memset(&v5, 0, 0x1FEu); v6 = 0; memset(&v7, 0, 0xFFu); CWnd::GetDlgItemTextW(v1, 0x3E8, &String, 0x14); if ( wcslen(&String) == 0x10 ) { v2 = 0; while ( !(*(&String + v2) & 0xFF00) ) { *(&v6 + v2) = *((_BYTE *)&String + 2 * v2); if ( ++v2 >= 0x10 ) { v8 = 0x40; flOldProtect = 0; VirtualProtect(sub_4010E0, 0xD17u, 0x40u, &flOldProtect); if ( GetLastError() ) return CWnd::MessageBoxW(v1, L"Wrong!", 0, 0); qmemcpy(sub_4010E0, &byte_5647B8, 0x330u); VirtualProtect(sub_4010E0, 0xD17u, flOldProtect, &v8); if ( !GetLastError() ) { v10 = 0; v10 = sub_4010E0(); if ( v10 == 1 ) return CWnd::MessageBoxW(v9, L"Congratulations! You are right!", 0, 0); } v1 = v9; return CWnd::MessageBoxW(v1, L"Wrong!", 0, 0); } } } return CWnd::MessageBoxW(v1, L"Wrong!", 0, 0); }
if ( wcslen(&String) == 0x10 ) //只能输入长度为16的字符
while ( !(*(&String + v2) & 0xFF00) ) // 字符范围是从0001到00FF,即ASCII码
动态解密函数sub_4010E0
VirtualProtect(sub_4010E0, 0xD17u, 0x40u, &flOldProtect); if ( GetLastError() ) return CWnd::MessageBoxW(v1, L"Wrong!", 0, 0); qmemcpy(sub_4010E0, &byte_5647B8, 0x330u); VirtualProtect(sub_4010E0, 0xD17u, flOldProtect, &v8);
qmemcpy引起我的兴趣,其作用为将一段长度为0x330的字符复制到sub_4010E0里面。右击byte_5647B8,查找引用。发现sub_401D80()做了一些操作,它异或了0xAB
只要函数sub_4010E0返回值为1,我们就达到目的
上面已经分析过了,函数sub_4010E0是动态解密的。动态调试程序,等它解密完成(即qmemcpy()运行后),再分析sub_4010E0函数。
因为代码太长了,我就不贴了,万一被认为水字数就不好了。⁄(⁄⁄•⁄ω⁄•⁄⁄)
仔细分析了一下代码,emmmmm,居然是解二元二次方程!!!⁄想起高考前被数学支配的恐惧 ヽ(。>д<)p
解完方程还要异或一下,后面有说明。
方程为x*x-7y*y=8,且1<<56 <= x < 1<<60、1<<56 <= y < 1<<60
手动运算是不可能的,编程也不会,只能靠好心的大佬们的程序才能维持得了生活的样子,咕咕咕。
这里使用wolframalpha算出x = 385044246406735194, y = 145533045678356702
wolframalpha网址:https://www.wolframalpha.com/
//分析sub_4010E0函数得到的 XorTable = [0x16, 0x96, 0x8c, 0xe3, 0x81, 0x98, 0x6e, 0x64, 0x84, 0x08, 0xdc, 0x81, 0xbe, 0x4d, 0x48, 0x4f]
将x,y转换为十六进制,和XorTable异或一下,颠倒顺序,拼接,转换成字符串,得到密码:L3mZ2k9aZ0a36DMM
忙到半夜,困死了,补觉
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
最后于 2019-6-27 15:28
被xmhwws编辑
,原因:
赞赏
看原图