-
-
[原创]2019看雪CTF 团队赛 第六题 RepwnWP
-
发表于: 2019-3-21 15:24 3317
-
用PEID扫描程序,使用了des算法
我们先看看sub_4013B0做了什么
用PEID扫描程序,使用了des算法
第二部分的flag会用到,这里先不看。
int __thiscall sub_4014C0(void *this) { unsigned int v1; // ebx char *Str; // [esp+0h] [ebp-68h] char v4[4]; // [esp+10h] [ebp-58h] int v5; // [esp+20h] [ebp-48h] int v6; // [esp+24h] [ebp-44h] int v7; // [esp+28h] [ebp-40h] int v8; // [esp+2Ch] [ebp-3Ch] int v9; // [esp+30h] [ebp-38h] int v10; // [esp+34h] [ebp-34h] int v11; // [esp+38h] [ebp-30h] int v12; // [esp+3Ch] [ebp-2Ch] char v13; // [esp+40h] [ebp-28h] sub_404970(0x10u, (int)this, (int)Str); sub_4044F0(); v1 = 0; v5 = 'yt^'; v6 = '+pLc'; v7 = 'a+SG'; v8 = 'G-QG'; v9 = 'Gl(V'; v10 = ')y}J'; v11 = 'SGA)'; v12 = 'ea+'; strcpy(v4, "Ansome_Is_Wrong"); while ( v1 < strlen((const char *)&v5) ) *((_BYTE *)&v5 + v1++) ^= 0x18u; puts("Please Input Your Key_ Now!"); scanf("%s", &v13); if ( sub_4012F0((int)&v13) ) { sub_401460(&v13); system("pause"); } else { puts(v4); } return 0; }
分析下sub_4012F0,sub_401460
int __thiscall sub_4014C0(void *this) { unsigned int v1; // ebx char *Str; // [esp+0h] [ebp-68h] char v4[4]; // [esp+10h] [ebp-58h] int v5; // [esp+20h] [ebp-48h] int v6; // [esp+24h] [ebp-44h] int v7; // [esp+28h] [ebp-40h] int v8; // [esp+2Ch] [ebp-3Ch] int v9; // [esp+30h] [ebp-38h] int v10; // [esp+34h] [ebp-34h] int v11; // [esp+38h] [ebp-30h] int v12; // [esp+3Ch] [ebp-2Ch] char v13; // [esp+40h] [ebp-28h] sub_404970(0x10u, (int)this, (int)Str); sub_4044F0(); v1 = 0; v5 = 'yt^'; v6 = '+pLc'; v7 = 'a+SG'; v8 = 'G-QG'; v9 = 'Gl(V'; v10 = ')y}J'; v11 = 'SGA)'; v12 = 'ea+'; strcpy(v4, "Ansome_Is_Wrong"); while ( v1 < strlen((const char *)&v5) ) *((_BYTE *)&v5 + v1++) ^= 0x18u; puts("Please Input Your Key_ Now!"); scanf("%s", &v13); if ( sub_4012F0((int)&v13) ) { sub_401460(&v13); system("pause"); } else { puts(v4); } return 0; }
分析下sub_4012F0,sub_401460
signed int __cdecl sub_4012F0(int a1) { signed int v1; // ecx signed int v2; // edx int v4; // [esp+0h] [ebp-38h] int v5; // [esp+10h] [ebp-28h] v1 = 8; v2 = 0; strcpy((char *)&v5, "Your_Input_Is_Wrong"); strcpy((char *)&v4, "X1Y0uN3tG00d"); while ( *((_BYTE *)&v4 + v2) == *(_BYTE *)(v1 + a1) ) { ++v2; ++v1; if ( v2 > 11 ) return 1; } return 0; }
sub_4012F0的代码比较简单,判断输入的key的8-12位是否为"X1Y0uN3tG00d"。
signed int __cdecl sub_4012F0(int a1) { signed int v1; // ecx signed int v2; // edx int v4; // [esp+0h] [ebp-38h] int v5; // [esp+10h] [ebp-28h] v1 = 8; v2 = 0; strcpy((char *)&v5, "Your_Input_Is_Wrong"); strcpy((char *)&v4, "X1Y0uN3tG00d"); while ( *((_BYTE *)&v4 + v2) == *(_BYTE *)(v1 + a1) ) { ++v2; ++v1; if ( v2 > 11 ) return 1; } return 0; }
sub_4012F0的代码比较简单,判断输入的key的8-12位是否为"X1Y0uN3tG00d"。
int __cdecl sub_401460(char *Str) { char Dest; // [esp+8h] [ebp-10h] if ( strlen(Str) == 24 ) { if ( sub_4013B0((int)Str) ) { Str[20] -= 0x58; Str[21] -= 0x46; Str[22] -= 3; Str[23] -= 0x6B; strcpy(&Dest, Str); } } else { printf("String Length is Wrong"); } return 0; }
sub_401460先判断key是否为24位,那我们可以知道key应该是这种形式:xxxxxxxxX1Y0uN3tG00dxxxx。
int __cdecl sub_401460(char *Str) { char Dest; // [esp+8h] [ebp-10h] if ( strlen(Str) == 24 ) { if ( sub_4013B0((int)Str) ) { Str[20] -= 0x58; Str[21] -= 0x46; Str[22] -= 3; Str[23] -= 0x6B; strcpy(&Dest, Str); } } else { printf("String Length is Wrong"); } return 0; }
sub_401460先判断key是否为24位,那我们可以知道key应该是这种形式:xxxxxxxxX1Y0uN3tG00dxxxx。
之后在sub_4013B0继续处理flag,处理完以后将key后4位的值分别减去不同的值,用strcpy覆盖掉堆栈里的返回地址。
我们先看看sub_4013B0做了什么
int __cdecl sub_4013B0(int a1) { int v1; // ebx int v2; // ecx int v3; // esi int result; // eax sub_401380(a1); // 只能输入十进制整数 v1 = key4 + 1000 * key1 + 100 * key2 + 10 * key3; v2 = key6 + 10 * key5; v3 = key8 + 10 * key7; result = 2 * (v1 + v2); if ( result == 4040 ) { result = 3 * v2 / 2; if ( result + 100 * v3 == 115 ) { result = 1; if ( v1 - 110 * v3 != 1900 ) result = printf("Key_Is_Wrong,Please_Input_Again!"); } } return result; }
int __cdecl sub_4013B0(int a1) { int v1; // ebx int v2; // ecx int v3; // esi int result; // eax sub_401380(a1); // 只能输入十进制整数 v1 = key4 + 1000 * key1 + 100 * key2 + 10 * key3; v2 = key6 + 10 * key5; v3 = key8 + 10 * key7; result = 2 * (v1 + v2); if ( result == 4040 ) { result = 3 * v2 / 2; if ( result + 100 * v3 == 115 ) { result = 1; if ( v1 - 110 * v3 != 1900 ) result = printf("Key_Is_Wrong,Please_Input_Again!"); } } return result; }
sub_401380是将前8位key都减去0x30,然后添加到全局变量地址里面,这里我把地址重新命名了。
要算出key,我们可以先列出关于v1,v2,v3的方程组
2 v1 + 2 v2 = 4040
2 v1 + 2 v2 = 4040
1.5 v2 + 100 v3 = 115
v1 - 110 v3 = 1900
可解得v1=2010,v2=10,v3=1
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: