-
-
[分享]CTF2019第一题writeup
-
发表于:
2019-3-11 15:51
3441
-
进入两个函数,F5,查看c代码
下面就写个反向程序,通过KanXueCTF2019JustForhappy
算出key
int __thiscall sub_401890(CWnd *this)
{
struct CString *v1; // ST08_4@1
CWnd *v2; // eax@1
int v3; // eax@1
int result; // eax@2
int v5[26]; // [sp+4Ch] [bp-74h]@7
int i; // [sp+B4h] [bp-Ch]@3
char *Str; // [sp+B8h] [bp-8h]@1
CWnd *v8; // [sp+BCh] [bp-4h]@1
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) )
{
for ( i = 0; Str[i]; ++i )
{
if ( Str[i] > 57 || Str[i] < 48 ) // 非数字
{
if ( Str[i] > 122 || Str[i] < 97 ) // 非小写字母
{
if ( Str[i] > 90 || Str[i] < 65 ) // 非大写字母
sub_4017B0();
else
v5[i] = Str[i] - 29; // 大写字母减29
}
else
{
v5[i] = Str[i] - 87; // 小写字母减87
}
}
else
{
v5[i] = Str[i] - 48; // 数字减48
}
}
result = sub_4017F0((int)v5);
}
else
{
result = CWnd::MessageBoxA(v8, "请输入pass!", 0, 0);
}
return result;
}
int __cdecl sub_4017F0(int a1)
{
int result; // eax@6
char Str1[28]; // [sp+D8h] [bp-24h]@4
int v3; // [sp+F4h] [bp-8h]@1
int v4; // [sp+F8h] [bp-4h]@1
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;
}
public static void main(String[] args) {
String source = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ";
String dst = "KanXueCTF2019JustForhappy";
char[] sA = source.toCharArray();
char[] dA = dst.toCharArray();
for (char c : dA) {
for (int i = 0; i < sA.length; i++) {
if (c == sA[i]) {
if (i + 48 <= 57 && i + 48 >= 48) {
System.out.print((char)(i + 48));
} else if (i + 87 >= 97 && i + 87 <= 122) {
System.out.print((char)(i + 87));
} else if (i + 29 >= 65 && i + 29 <= 90) {
System.out.print((char)(i + 29));
} else {
System.out.print("error" + " ");
}
}
}
}
}
- 先运行程序,随便输入提交,弹出加油提示框
- 用ida打开exe,查看string,发现KanXueCTF2019JustForhappy、abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ等字符串
- 猜测可能是对比字符串,在function中看到有strcmp,查看graph,发现上面有两个函数调用,分别是sub_401890 -> sub_4017F0 -> strcmp
-
进入两个函数,F5,查看c代码
int __thiscall sub_401890(CWnd *this)
{
struct CString *v1; // ST08_4@1
CWnd *v2; // eax@1
int v3; // eax@1
int result; // eax@2
int v5[26]; // [sp+4Ch] [bp-74h]@7
int i; // [sp+B4h] [bp-Ch]@3
char *Str; // [sp+B8h] [bp-8h]@1
CWnd *v8; // [sp+BCh] [bp-4h]@1
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) )
{
for ( i = 0; Str[i]; ++i )
{
if ( Str[i] > 57 || Str[i] < 48 ) // 非数字
{
if ( Str[i] > 122 || Str[i] < 97 ) // 非小写字母
{
if ( Str[i] > 90 || Str[i] < 65 ) // 非大写字母
sub_4017B0();
else
v5[i] = Str[i] - 29; // 大写字母减29
}
else
{
v5[i] = Str[i] - 87; // 小写字母减87
}
}
else
{
v5[i] = Str[i] - 48; // 数字减48
}
}
result = sub_4017F0((int)v5);
}
else
{
result = CWnd::MessageBoxA(v8, "请输入pass!", 0, 0);
}
return result;
}
int __cdecl sub_4017F0(int a1)
{
int result; // eax@6
char Str1[28]; // [sp+D8h] [bp-24h]@4
int v3; // [sp+F4h] [bp-8h]@1
int v4; // [sp+F8h] [bp-4h]@1
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;
}
- 分别下断点,通过ida调试,验证猜想,分析之后,流程是先对输入的串进行转换,然后再从
abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ
中按数组取值,最后与KanXueCTF2019JustForhappy
比较
-
下面就写个反向程序,通过KanXueCTF2019JustForhappy
算出key
public static void main(String[] args) {
String source = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ";
String dst = "KanXueCTF2019JustForhappy";
char[] sA = source.toCharArray();
char[] dA = dst.toCharArray();
for (char c : dA) {
for (int i = 0; i < sA.length; i++) {
if (c == sA[i]) {
if (i + 48 <= 57 && i + 48 >= 48) {
System.out.print((char)(i + 48));
} else if (i + 87 >= 97 && i + 87 <= 122) {
System.out.print((char)(i + 87));
} else if (i + 29 >= 65 && i + 29 <= 90) {
System.out.print((char)(i + 29));
} else {
System.out.print("error" + " ");
}
}
}
}
}
- 最后结果为:
j0rXI4bTeustBiIGHeCF70DDM
--- END ---
先运行程序,随便输入提交,弹出加油提示框
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-3-12 08:31
被小呱呱编辑
,原因: