-
-
[分享]流浪者(kxctf2019cm1)wp
-
2019-3-14 11:59 2364
-
前话
作为逆向的真*萌新,感到吃不消。看雪CTF的题目质量都非常高,能够学习到很多东西。以前都只是默默关注,当我开始尝试后发现,只要尽心尽力了,就算解不出来,也会收获很多。看到这么多大佬蹭蹭蹭往上升,我躲在角落里瑟瑟发抖。
试探程序
先把程序运行起来,随便输入
IDA载入,搜索字符串,发现关键字
跟随字符串来到关键函数,部分函数名自定义了。
int __thiscall sub_401890(CWnd *this) { ... CWnd::GetWindowTextA(v2, v1); // 获取用户输入 v3 = sub_401A30(v8 + 100); Str = CString::GetBuffer((v8 + 100), v3); if ( !strlen(Str) ) return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0); for ( i = 0; Str[i]; ++i ) // 根据输入的数据进行判断 { if ( Str[i] > '9' || Str[i] < '0' ) { if ( Str[i] > 'z' || Str[i] < 'a' ) { if ( Str[i] > 'Z' || Str[i] < 'A' ) // 限定输入的数据只包含数字和大小写字母 sub_4017B0(); else v5[i] = Str[i] - 29; // 根据相应的范围,进行相应的运算 } else { v5[i] = Str[i] - 87; } } else { v5[i] = Str[i] - 48; } } return check(v5); // 关键校验函数 }
check函数:
int __cdecl check(int a1) { int 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 ( *(a1 + 4 * v4) < 62 && *(a1 + 4 * v4) >= 0 ) { Str1[v4] = aAbcdefghiabcde[*(a1 + 4 * v4)]; // a1数组中的元素作为aAbcdefghiabcde数组的索引 ++v4; } Str1[v4] = 0; if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") ) result = sub_401770(); else result = sub_4017B0(); return result; }
程序流程
用户输入的字符中,如果一个字符处于0~9,就让这个字符减去48;如果处于a~z,就减去87;如果处于A~Z,就减去29,从而得到check函数里用到的索引数组。
进入check函数
依次将v5的元素作为aAbcdefghiabcde数组的索引,取出aAbcdefghiabcde的每个元素并赋给Str1形成新的字符串和“KanXueCTF2019JustForhappy”比较,相等就通过。
dump出来aAbcdefghiabcde的数据,枚举一下输入即可。编写脚本
EXP
#include<iostream> #include<string.h> using namespace std; int main(){ char aAbcdefghiabcde[]="abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"; char result[]="KanXueCTF2019JustForhappy"; int v5; for(int i1=0;i1<strlen(result);i1++){ for(int i2=0;i2<strlen(aAbcdefghiabcde);i2++){ if ( aAbcdefghiabcde[i2] >=48 && aAbcdefghiabcde[i2] <= 57 ) v5 = aAbcdefghiabcde[i2] - 48; if ( aAbcdefghiabcde[i2] >=97 && aAbcdefghiabcde[i2] <= 122 ) v5 = aAbcdefghiabcde[i2] - 87; if ( aAbcdefghiabcde[i2] >=65 && aAbcdefghiabcde[i2] <= 90 ) v5 = aAbcdefghiabcde[i2] - 29; if(aAbcdefghiabcde[v5]==result[i1]) { cout<<aAbcdefghiabcde[i2]; break; } } } return 0; } //j0rXI4bTeustBiIGHeCF70DDM
疑惑
python我没有专门去学,我按照C++的写法,转为python脚本如下
tmpl=list("abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ") result=list("KanXueCTF2019JustForhappy") flag='' for r in result: for ch in tmpl: if ord(ch)>=0 and ord(ch)<=9: index=ord(ch)-48 if ord(ch)>=97 and ord(ch)<=122: index = ord(ch) - 87 if ord(ch)>=65 and ord(ch)<=90: index=ord(ch)-29 if tmpl[index]==r: flag+=ch break; print "flag:",flag #jrXIbTeustBiIGHeCFDDM
结果却不一样,显然C++是正确的,不解,拜托各位大神解释一下。
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
赞赏
他的文章
[原创]第二题 南冥神功
4125
Win10Ntfs文件系统的FCB结构体
3032
看原图