-
-
[原创]2019看雪CTF 团队赛 第六题 RepwnWP
-
发表于: 2019-3-21 15:24 3347
-
用PEID扫描程序,使用了des算法
我们先看看sub_4013B0做了什么
用PEID扫描程序,使用了des算法
第二部分的flag会用到,这里先不看。
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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"。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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"。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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做了什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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
赞赏
他的文章
看原图
赞赏
雪币:
留言: