发现自己似乎很久没有写过东西了,最近认识了很多大佬们,意识到差距真tm巨大,要补的东西还有很多,其实不写博客学习还是要继续的,不过为了潜意识里联系上某位大佬,还是写点东西了吧。 这是2017年的WIFI万能钥匙逆向题的一道,没有花没有反调试,(最近做题老喜欢爆破,所以就选这道题了)先看题目:
对的,没错,error了,也是一个很基础的调用messagebox的程序,找到输入内容的GetDlgItemTextA,设置断点
然后遇到一些跳转,提前看一下跳转地址,然后一路修改标志位(f表示不能跳转),调试下去,即爆破成功。
0040120B . FF15 A8704000 call dword ptr ds:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
00401211 . 68 F4010000 push 0x1F4 ; /Timeout = 500. ms
00401216 . FF15 00704000 call dword ptr ds:[<&KERNEL32.Sleep>] ; \Sleep
0040121C . 8D45 E4 lea eax,dword ptr ss:[ebp-0x1C]
0040121F . 50 push eax
00401220 . E8 DB000000 call WannaLOL.00401300
00401225 . 83F8 04 cmp eax,0x4
00401228 . 59 pop ecx ; WannaLOL.004012E7
00401229 . 0F85 A0000000 jnz WannaLOL.004012CF ; F
0040122F . 6A 30 push 0x30
00401231 . 59 pop ecx ; WannaLOL.004012E7
00401232 . 384D E4 cmp byte ptr ss:[ebp-0x1C],cl
00401235 . 0F84 94000000 je WannaLOL.004012CF ; f
0040123B . 384D E5 cmp byte ptr ss:[ebp-0x1B],cl
0040123E . 0F84 8B000000 je WannaLOL.004012CF ; f
00401244 . 384D E6 cmp byte ptr ss:[ebp-0x1A],cl
00401247 . 0F84 82000000 je WannaLOL.004012CF ; f
0040124D . 384D E7 cmp byte ptr ss:[ebp-0x19],cl
00401250 . 74 7D je short WannaLOL.004012CF ; f
00401252 . 807D E4 31 cmp byte ptr ss:[ebp-0x1C],0x31
00401256 . 75 77 jnz short WannaLOL.004012CF ; f
00401258 . 807D E5 35 cmp byte ptr ss:[ebp-0x1B],0x35
0040125C . 75 71 jnz short WannaLOL.004012CF ; f
0040125E . 74 03 je short WannaLOL.00401263
00401260 . 75 01 jnz short WannaLOL.00401263
00401262 E8 db E8
00401263 > 66:B8 0800 mov ax,0x8
00401267 . 66:35 0700 xor ax,0x7
0040126B . 0FBE45 E6 movsx eax,byte ptr ss:[ebp-0x1A]
0040126F . 2BC1 sub eax,ecx
00401271 . 8945 FC mov dword ptr ss:[ebp-0x4],eax
00401274 . 0FBE45 E4 movsx eax,byte ptr ss:[ebp-0x1C]
00401278 . DB45 FC fild dword ptr ss:[ebp-0x4]
0040127B . 2BC1 sub eax,ecx
0040127D . 8945 FC mov dword ptr ss:[ebp-0x4],eax
00401280 . 0FBE45 E5 movsx eax,byte ptr ss:[ebp-0x1B]
00401284 . DB45 FC fild dword ptr ss:[ebp-0x4]
00401287 . 2BC1 sub eax,ecx
00401289 . 8945 FC mov dword ptr ss:[ebp-0x4],eax
0040128C . DA75 FC fidiv dword ptr ss:[ebp-0x4]
0040128F . 0FBE45 E7 movsx eax,byte ptr ss:[ebp-0x19]
00401293 . 2BC1 sub eax,ecx
00401295 . 8945 FC mov dword ptr ss:[ebp-0x4],eax
00401298 . DEE9 fsubp st(1),st
0040129A . DA4D FC fimul dword ptr ss:[ebp-0x4]
0040129D . D80D 1C714000 fmul dword ptr ds:[0x40711C]
004012A3 . D95D FC fstp dword ptr ss:[ebp-0x4]
004012A6 . 74 03 je short WannaLOL.004012AB
004012A8 . 75 01 jnz short WannaLOL.004012AB
004012AA E8 db E8
004012AB > 66:B8 0800 mov ax,0x8
004012AF . 66:35 0700 xor ax,0x7
004012B3 . D945 FC fld dword ptr ss:[ebp-0x4]
004012B6 . D81D 18714000 fcomp dword ptr ds:[0x407118]
004012BC . 6A 00 push 0x0
004012BE . 68 78804000 push WannaLOL.00408078 ; ASCII "CrackMe 2017 CTF"
004012C3 . DFE0 fstsw ax
004012C5 . 9E sahf
004012C6 . 75 0E jnz short WannaLOL.004012D6 ; f
004012C8 . 68 5C804000 push WannaLOL.0040805C ; ASCII "Registration successful !"
004012CD . EB 0C jmp short WannaLOL.004012DB
004012CF > 6A 00 push 0x0
004012D1 . 68 48804000 push WannaLOL.00408048 ; ASCII "CrackMe 2017 CTF v2"
004012D6 > 68 40804000 push WannaLOL.00408040 ; ASCII "error !"
004012DB > FF35 34AA4000 push dword ptr ds:[0x40AA34] ; |hOwner = 008C034E ('PEDIY CTF 2017',class='myWindowClass')
004012E1 . FF15 AC704000 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
004012E7 . C9 leave
004012E8 . C3 retn
爆破确实是不难,做下来也就十几分钟,但是where is the flag????所以接下来,追码吧
打开IDA载入程序,跟到MessageBoxA然后看看哪里调用这个函数
奈斯!
找到函数头F5,反编译代码,让我们看看他在干嘛:
不奈斯,再自己定义成函数吧。然后就再看一下汇编吧(做题我一般还是不会仔细看汇编代码的),斯国一,来我们看看
这里有两个IDA找不到头尾的函数,反编译出来也是有,但是不影响什么,等待师傅们的解答。
int sub_4011F4()
{int v0; // ecx@8double v1; // st7@8double v2; // st6@8double v3; // st6@8const CHAR *v5; // [sp-Ch] [bp-28h]@9const CHAR *v6; // [sp-8h] [bp-24h]@8CHAR String; // [sp+0h] [bp-1Ch]@1 /key的第一位/char v8; // [sp+1h] [bp-1Bh]@3 /key的第二位/char v9; // [sp+2h] [bp-1Ah]@4 /key的第三位/char v10; // [sp+3h] [bp-19h]@5 /key的第四位/int v11; // [sp+18h] [bp-4h]@8GetDlgItemTextA(hDlg, 1001, &String, 21);Sleep(0x1F4u);if ( strlen(&String) != 4 || String == 48 || v8 == 48 || v9 == 48 || v10 == 48 || String != 49 || v8 != 53 ){v6 = Caption;goto LABEL_11; //这里就GG了/}JUMPOUT(v8 == 53, (char *)&loc_401262 + 1);JUMPOUT(0, (char *)&loc_401262 + 1);v48CACD();v11 = v9 - v0;v1 = (double)v11;v11 = String - v0;v2 = (double)v11;v11 = v8 - v0;v3 = v2 / (double)v11;v11 = v10 - v0;*(float *)&v11 = (v1 - v3) * (double)v11 * 16.0;JUMPOUT(v10, v0, (char *)&loc_4012AA + 1);JUMPOUT(v10 != v0, (char *)&loc_4012AA + 1);v48CB15();v6 = aCrackme2017Ctf;if ( *(float *)&v11 != 384.0 ){
LABEL_11:v5 = Text;return MessageBoxA(hWnd, v5, v6, 0);}v5 = aRegistrationSu;return MessageBoxA(hWnd, v5, v6, 0);
}
硬着头皮看完吧。。除此之外没有别的方法。大致分析一下:输入的字符串长度必须等于4,且不能有0,第一位和第二位分别是1和5,第三位和第四位靠算法算出:
///v0为临时变量/v11 = v9 - v0; // 第三位 -v0 v1 = (double)v11; v1==key[2]v11 = String - v0; //第一位-v0v2 = (double)v11; v2==key[0]v11 = v8 - v0; //第二位-v0v3 = v2 / (double)v11; v3==key[1]v11 = v10 - v0; v4==key[3]*(float *)&v11 = (v1 - v3) * (double)v11 * 16.0;
列方程: (v1-0.2)* v11 * 16.0=384
py脚本走起
所以解出flag:1555
链接:https://pan.baidu.com/s/1LnI1F19Cfm97P_cmVHM3Tw 密码:kjj5