-
-
[原创]流浪者writeup
-
发表于: 2019-3-21 13:01 2989
-
搜索字符串shift+F12
发现可疑字符串KanXueCTF2019JustForhappy
,双击进入
选中字符串,按X找到这个字符串被交叉引用的地址
双击004035c0
进入,F5
查看伪代码
双击sub_4017F0
进入a1的交叉引用地址
可以看到以下伪代码
这个算法比较简单,直接引用原代码编写解密脚本
int __cdecl sub_4017F0(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 ( *(_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; }
int __thiscall sub_401890(CWnd *this) { struct CString *v1; // ST08_4 CWnd *v2; // eax int v3; // eax int v5[26]; // [esp+4Ch] [ebp-74h] int i; // [esp+B4h] [ebp-Ch] char *Str; // [esp+B8h] [ebp-8h] CWnd *v8; // [esp+BCh] [ebp-4h] v8 = this; v1 = (CWnd *)((char *)this + 100); v2 = CWnd::GetDlgItem(this, 1002); CWnd::GetWindowTextA(v2, v1); v3 = sub_401A30((char *)v8 + 100); Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v3); if ( !strlen(Str) ) return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0); for ( i = 0; Str[i]; ++i ) { if ( Str[i] > 57 || Str[i] < 48 ) { if ( Str[i] > 'z' || Str[i] < 'a' ) //h,r变化进制,编码 { 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 sub_4017F0((int)v5); }
content = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ" flag="KanXueCTF2019JustForhappy" position =[] v5=0 for i in flag: for j in range(0,len(content)): if i==content[j]: position.append(j) print(position) for i in range(0,len(content)): num=ord(content[i]) if num>57 or num <97: if num>122 or num <97: pass else: v5=num-29 else: v5=num-48 if v5==48: print(content[i])
-
搜索字符串
shift+F12
-
发现可疑字符串
KanXueCTF2019JustForhappy
,双击进入 -
选中字符串,按X找到这个字符串被交叉引用的地址
-
双击
004035c0
进入,F5
查看伪代码int __cdecl sub_4017F0(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 ( *(_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; }
- 分析可知:我们输入的passwd字符串保存到a1指向的地址,经过转换得到
KanXueCTF2019JustForhappy
- 我们现在需要了解转换方式,然后逆向出解密算法
- 分析可知:我们输入的passwd字符串保存到a1指向的地址,经过转换得到
-
双击
sub_4017F0
进入a1的交叉引用地址 -
可以看到以下伪代码
int __thiscall sub_401890(CWnd *this) { struct CString *v1; // ST08_4 CWnd *v2; // eax int v3; // eax int v5[26]; // [esp+4Ch] [ebp-74h] int i; // [esp+B4h] [ebp-Ch] char *Str; // [esp+B8h] [ebp-8h] CWnd *v8; // [esp+BCh] [ebp-4h] v8 = this; v1 = (CWnd *)((char *)this + 100); v2 = CWnd::GetDlgItem(this, 1002); CWnd::GetWindowTextA(v2, v1); v3 = sub_401A30((char *)v8 + 100); Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v3); if ( !strlen(Str) ) return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0); for ( i = 0; Str[i]; ++i ) { if ( Str[i] > 57 || Str[i] < 48 ) { if ( Str[i] > 'z' || Str[i] < 'a' ) //h,r变化进制,编码 { 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 sub_4017F0((int)v5); }
-
这个算法比较简单,直接引用原代码编写解密脚本
content = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ" flag="KanXueCTF2019JustForhappy" position =[] v5=0 for i in flag: for j in range(0,len(content)): if i==content[j]: position.append(j) print(position) for i in range(0,len(content)): num=ord(content[i]) if num>57 or num <97: if num>122 or num <97: pass else: v5=num-29 else: v5=num-48 if v5==48: print(content[i])
- 解出flag :
j0rXI4bTeustBiIGHeCF70DDM
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-3-26 17:20
被shavchen编辑
,原因:
赞赏
看原图
赞赏
雪币:
留言: