用PE查壳
用ida打开找到main函数
int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // eax int v4; // eax int v5; // eax int result; // eax char flag; // [rsp+20h] [rbp-60h] char Str1; // [rsp+50h] [rbp-30h] char v9; // [rsp+90h] [rbp+10h] char v10; // [rsp+D0h] [rbp+50h] char Str2[8]; // [rsp+110h] [rbp+90h] int v12; // [rsp+14Ch] [rbp+CCh] _main(); strcpy(Str2, "EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG"); puts("Hello, please input your flag and I will tell you whether it is right or not."); scanf("%38s", &flag); if ( strlen(&flag) == 38 && (v3 = strlen(&flag), (unsigned int)encode_one(&flag, v3, &v10, &v12) == 0) && (v4 = strlen(&v10), (unsigned int)encode_two(&v10, v4, &v9, &v12) == 0) && (v5 = strlen(&v9), (unsigned int)encode_three(&v9, v5, &Str1, &v12) == 0) && !strcmp(&Str1, Str2) ) { puts("you are right!"); result = 0; } else { printf("Something wrong. Keep going."); result = 0; } return result; }
看到有三层加密,动态调试可以找到v10,v12,v9,Str1的初始化值为零,也可以根据调用情况看是否被其他函数调用。
第一层加密:
int64 __fastcall encode_one(const char *flag, int a2, char *a3, int *a4) { int v5; // esi int v6; // esi int v7; // esi int v8; // [rsp+34h] [rbp-1Ch] int v9; // [rsp+38h] [rbp-18h] char *v10; // [rsp+40h] [rbp-10h] int v11; // [rsp+48h] [rbp-8h] int i; // [rsp+4Ch] [rbp-4h] unsigned __int8 *v13; // [rsp+70h] [rbp+20h] int len; // [rsp+78h] [rbp+28h] int *v15; // [rsp+88h] [rbp+38h] v13 = (unsigned __int8 *)flag; len = a2; // v14=strlen(flag) len=38 v15 = a4; if ( !flag || !a2 ) return 0xFFFFFFFFi64; v11 = 0; if ( a2 % 3 ) v11 = 3 - a2 % 3; // v11=1 v9 = a2 + v11; // v9=39 v8 = 8 * (a2 + v11) / 6; // v8=52 v10 = a3; for ( i = 0; i < v9; i += 3 ) { *v10 = alphabet[(char)*v13 >> 2]; if ( len + v11 - 3 == i && v11 ) // 36==i && v11 { if ( v11 == 1 ) { v5 = (char)cmove_bits(*v13, 6, 2); v10[1] = alphabet[v5 + (char)cmove_bits(v13[1], 0, 4)]; v10[2] = alphabet[(char)cmove_bits(v13[1], 4, 2)]; v10[3] = 61; } else if ( v11 == 2 ) { v10[1] = alphabet[(char)cmove_bits(*v13, 6, 2)]; v10[2] = 61; v10[3] = 61; } } else { v6 = (char)cmove_bits(*v13, 6, 2); v10[1] = alphabet[v6 + (char)cmove_bits(v13[1], 0, 4)]; v7 = (char)cmove_bits(v13[1], 4, 2); v10[2] = alphabet[v7 + (char)cmove_bits(v13[2], 0, 6)]; v10[3] = alphabet[v13[2] & 0x3F]; } v10 += 4; v13 += 3; } if ( v15 ) *v15 = v8; return 0i64; }
alphabet的值为:
其实我一开始也没有看到这是base64加密,直到我解出了第二道、第三道的结果我才发现这是base64加密
第二道加密是简单的置换
_int64 __fastcall encode_two(const char *a1, int a2, char *V9, int *a4) { char *Source; // [rsp+40h] [rbp+10h] char *A; // [rsp+50h] [rbp+20h] Source = (char *)a1; A = V9; if ( !a1 || !a2 ) return 0xFFFFFFFFi64; strncpy(V9, a1 + 26, 0xDui64); strncpy(A + 13, Source, 0xDui64); strncpy(A + 26, Source + 39, 0xDui64); strncpy(A + 39, Source + 13, 0xDui64); return 0i64; }
第三是凯撒的加密,但是配合上了数字
_int64 __fastcall encode_three(const char *a1, int len, char *a3, int *a4) { char v5; // [rsp+Fh] [rbp-11h] int i; // [rsp+14h] [rbp-Ch] char *v7; // [rsp+18h] [rbp-8h] const char *v8; // [rsp+30h] [rbp+10h] v8 = a1; if ( !a1 || !len ) return 0xFFFFFFFFi64; v7 = a3; // V7已知反推V8(v5),也就是a1 for ( i = 0; i < len; ++i ) { v5 = *v8; if ( *v8 <= 64 || v5 > 90 ) { if ( v5 <= 96 || v5 > 122 ) { if ( v5 <= 47 || v5 > 57 ) *v7 = v5; else *v7 = (v5 - 48 + 3) % 10 + 48; } else { *v7 = (v5 - 97 + 3) % 26 + 97; } } else { *v7 = (v5 - 65 + 3) % 26 + 65; } ++v7; ++v8; } return 0i64; }
其实就是你过来的解密,密文为EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG
最后的str1就是密文,利用str1在encode_three解出v9,利用v9在encode_two解出v10,然后就是由v10得到flag。
第三道和第二道加密的脚本如下:
#include#include int main() { int i; char A[54]; char a1[54]; int v5[54]; int v7[54]={69,109,66,109,80,53,80,109,110,55,81,99,80,85,52,103,76,89,75,118,53,81,99,77,109, 66,51,80,87,72,99,80,53,89,107,80,113,51,61,99,84,54,81,99,107,107,80,99,107,111,82,71}; //EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG的ascll值 for(i=0;i<54;i++)//凯撒密码解码,加上数字 { for(v5[i]=1;v5[i]<=126;v5[i]++) { if ( v5[i]<= 64 || v5[i] > 90 ) { if ( v5[i] <= 96 || v5[i] > 122 ) { if ( v5[i] <= 47 || v5[i] > 57 ) { if(v5[i] == v7[i]) break; } else if(v7[i] == ((v5[i] - 48 + 3)%10+48)) break; } else { if(v7[i] == (v5[i] - 97 + 3) % 26 + 97) break; } } else { if(v7[i] == (v5[i] - 65 + 3) % 26 + 65) break; } } } for(i=0;i<=53;i++) { printf("%c",v5[i]); A[i]=v5[i]; } printf("n"); strncpy(a1+26,A,13); strncpy(a1,A+13,13); strncpy(a1+39,A+26,13); strncpy(a1+13,A+39,13); for(i=0;i<=53;i++) { printf("%c",a1[i]); } }
得到:
base64解码得到:
flag{672cc4778a38e80cb362987341133ea2}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)