刚好在学逆向,突然想着可以看一下还在比赛的看雪ctf
流浪者
win32 gui 输入注册码,错误会有提示
od 打开,搜索字符串,找到判断结果的函数位置;
ida 打开,找到od确定的函数位置,根据ida的交叉引用,找到了判断的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| sub_401770 proc near ; CODE XREF: sub_4017F0+83↓p
BOOL __cdecl sub_4017F0(int a1) { BOOL result; // eax char Str1[28]; // [esp+D8h] [ebp-24h] int v3; // [esp+F4h] [ebp-8h] int v4; // [esp+F8h] [ebp-4h]
v4 = 0; v3 = 0; while ( *(_DWORD *)(a1 + 4 * v4) < 62 && *(_DWORD *)(a1 + 4 * v4) >= 0 ) { Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)]; ++v4; } Str1[v4] = 0; if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") ) result = sub_401770(); else result = sub_4017B0(); return result; }
aAbcdefghiabcde db 'abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ',0
|
可以看到就是字符串对应,直接写脚本
中间卡了一下就是得到的是数字位置,如19,42什么的,但是输入没法这样,出去溜了个弯,回去在od strcmp之前下了个断点,查看对输入字符串的处理,之后突然意识到可能是 0-9 a-z A-Z 对应,尝试了一下,bingo
脚本:
1 2 3 4 5 6 7 8 9 10 11 12
| a = 'abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'
b = 'KanXueCTF2019JustForhappy' array = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
c = ''
for i in range(len(b)): for j in range(len(a)): if b[i]== a[j]: c += array[j] print c
|
Repwn
中间卡住了。。好在后面还是把解出来了哈哈哈哈,先说下目前的思路
还是先拖进od然后搜索出现的字符串,不记得是用ida还是od找到了判断入口,下断点,同时在ida中找到函数位置,反汇编,可以看到层层嵌套的判断
第一次 判断了13位,也可以因此确定其中的13位:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| v1 = 8; v2 = 0; v8 = 'ruoY'; v9 = 'pnI_'; v10 = 'I_tu'; v11 = 'rW_s'; v12 = 'gno'; v4 = '0Y1X'; v5 = 't3Nu'; v6 = 'd00G'; v7 = 0; while ( *((_BYTE *)&v4 + v2) == *(_BYTE *)(v1 + key) ) { ++v2; ++v1; if ( v2 > 11 ) { result = 1; if ( *(_BYTE *)(key + 20) == 'H' ) return result; return 0; } } return 0;
|
第二次,确定了序列长度,同时在检查第三步回来之后还会对最后四位处理,最后会将其覆盖到返回地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| if ( strlen(Str) == 24 ) { if ( check3((int)Str) ) { Str[20] -= 88; Str[21] -= 70; Str[22] -= 3; Str[23] -= 107; strcpy(&Dest, Str); } } else { printf("String Length is Wrong"); }
|
第三次,也就是最后一次,,deal_8对前八位全部减0x30, 第三次通过计算可以确定第五到八位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| deal_8(a1); v1 = no_4 + 1000 * fl[0] + 100 * no_2 + 10 * no_3; v2 = no_6 + 10 * no_5; v3 = no_8 + 10 * no_7;
if ( 2 * (v1 + v2) != 4040 || 3 * v2 / 2 + 100 * v3 != 115 )// v1+v2 = 0x7e4 goto LABEL_2; result = 1;
if ( v1 - 110 * v3 != 1900 ) { printf("Key_Is_Wrong,Please_Input_Again!"); LABEL_2: result = 0; }
|
经过不断的尝试+猜测,终于试出了flag
1
| 20101001X1Y0uN3tG00dHaCk
|