一般来说会尊重每一道题,给每一道题一篇文章,不过工控的比赛有些无聊..也没啥新知识点,就写一块了。
freestyle
打开主程序会发现两个fun1
fun1
直接手算也行,直接写个程序也可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| __int64 fun1() { char input1[24]; unsigned __int64 v2;
v2 = __readfsqword(0x28u); puts("Welcome to Alaska!!!"); puts("please input key: "); fgets(input1, 20, stdin); if ( 4 * (3 * atoi(input1) / 9 - 9) != 4400 ) exit(0); puts("ok,level_1 over!\n\n"); return 1LL; }
|
fun2
第二个是要找等式最小的数值,直接相同语句爆破就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| __int64 fun2() { char input[24]; unsigned __int64 v2;
v2 = __readfsqword(0x28u); puts("Welcome to Paradise Lost!!!"); puts("The code value is the smallest divisible"); puts("please input key: "); fgets(input, 20, stdin); if ( 2 * (atoi(input) % 56) != 98 ) exit(0); puts("ok,level_2 over!"); return 1LL; }
|
GetFlag
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h>
int main(void) { int i; printf("%d\n", 1109 * 9 / 3); for ( i = 56; i < 200; i++ ) if ( i % 56 == 49 ) printf("%d ", i); return 0; }
|
拿到数据程序跑一下试一下即可,两个拼接起来MD5加密提交即可
Re_function
压缩包密码
接收到压缩包发现有个密码,然后还在压缩包旁边还看到一堆信息,看文件前缀 89 50 4E可得知这是PNG文件
直接拿出来查看即可得知压缩包密码:3CF8
解压出来两个文件,分别分析一下
re_easy_func1
进到主程序可以发现IDA解析异常,原因是401019处有花,程序执行根本不会执行到
因为xor eax, eax会把标志位ZF设置为1,于是JZ必定跳转
于是我们把401019变成nop即可,再在401000处按u转成未定义,按c转成代码,按p形成结构块,即可恢复再F5即可查看反汇编
逻辑较为简单,就是偶数位异或
EXP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <stdio.h> #include <string.h>
int main(void) { unsigned char encData[] = { 100, 113, 84, 84, 100, 120, 116, 120, 100, 65, 64, 72, 112, 109, 24, 74, 0x41, 0x78, 0x66, 0x72, 0x41, 0x78, 0x5E, 0x4E, 0x5D, 0x52, 0x0E, 0x3D }; int i; for ( i = 0; i < strlen(encData); i += 2 ) printf("%c%c", encData[i] ^ 0x37, encData[i + 1]); return 0; }
|
获得输入
1
| SqcTSxCxSAwHGm/JvxQrvxiNjR9=+
|
re_easy_func2
明显还要个文件,还没完
进去就一个函数,很明显的base64加密,不过换了码表
直接拿Cyber解密即可,填入码表,再输入我们从re_easy_func1获得的输入,即可flag
定时启动
- 在被这程序加密一次后得知(就是当前目标的所有文件后缀被加了.WNCRY),还会有个ReadMe文件生成
- 再运行此squid.WNCRY,就会有个提示,就是要在指定时间运行这个文件
- 修改系统时间,再把ReadMe删掉即可出flag
ez_algorithm
分析主函数可得知就这一个加密函数,并可以从xyp1()获取密文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int __cdecl main(int argc, const char **argv, const char **envp) { const char *encFlag; char v5[1000]; char *encInput;
_main(argc, argv, envp); printf(Format); scanf("%s", v5); encInput = (char *)encryption(v5); encFlag = (const char *)xyp1(); if ( !strcmp(encInput, encFlag) ) puts("Gj!You Win!!!"); else puts("Sry!You Lost!!!"); system("pause"); return 0; }
|
encryption
简单分析一下可得知不同字符对应的不同加密,但其实都是单字符替换,唯一注意的是大写字母和小写字母会根据下标进行不同操作
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| char *__fastcall encryption(char *input) { int v1; char v2; char v3; __int64 v4; char v5; char v6; int v7; char v8; char v9; char v10; char v11; char v12; size_t index; char v15[1012]; int v16; __int64 v17; __int64 v18; int v19; char *t; char *v21;
v18 = xyp2(); v17 = xyp3(); v21 = v15; t = input; v19 = 0; v16 = 1; while ( 1 ) { index = v19; if ( index >= strlen(input) ) return v15; if ( *t <= 64 || *t > 90 ) { if ( *t <= 96 || *t > 122 ) { if ( *t == '_' ) { switch ( v16 + rand() % 7 ) { case 0: *v21 = 58; break; case 1: *v21 = 38; break; case 2: *v21 = 43; break; case 3: *v21 = 42; break; case 4: *v21 = 92; break; case 5: *v21 = 63; break; case 6: *v21 = 36; break; case 7: *v21 = 35; break; default: break; } } else if ( *t <= 47 || *t > 57 ) { *v21 = *t; } else { v12 = encryption2(*t); *v21 = v12; } } else { v7 = v19 % 4; if ( v19 % 4 == 1 ) { v9 = encryption2(*(_BYTE *)((*t - 97) * (v19 % 4) + v18)); *v21 = v9; } else if ( v7 > 1 ) { if ( v7 == 2 ) { v10 = encryption2(*(_BYTE *)(((*t - 97) ^ (v19 % 4)) + v18)); *v21 = v10; } else if ( v7 == 3 ) { v11 = encryption2(*(_BYTE *)(*t - 97 + v19 % 4 + v18)); *v21 = v11; } } else if ( !v7 ) { v8 = encryption2(*(_BYTE *)(*t - 97 - v19 % 4 + v18)); *v21 = v8; } } } else { v1 = v19 % 4; if ( v19 % 4 == 1 ) { v3 = encryption2(*(_BYTE *)(*t - 65 + v19 % 4 + v17)); *v21 = v3; } else if ( v1 > 1 ) { if ( v1 == 2 ) { v4 = v19 * (*t - 65); v5 = encryption2(*(_BYTE *)((((HIDWORD(v4) >> 30) + (unsigned __int8)v19 * (*t - 65)) & 3) - (HIDWORD(v4) >> 30) + v17)); *v21 = v5; } else if ( v1 == 3 ) { v6 = encryption2(*(_BYTE *)(((*t - 65) ^ (v19 % 4)) + v17)); *v21 = v6; } } else if ( !v1 ) { v2 = encryption2(*(_BYTE *)(*t - 65 - v19 % 4 + v17)); *v21 = v2; } } ++v19; ++t; ++v21; } }
|
GetFlag
于是现在加密算法有,数据有,我们直接爆破每个字符即可
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
| #include <stdio.h> #include <stdint.h> #include <string.h> #include <stdlib.h>
char encFlag[] = "BRUF{E6oU9Ci#J9+6nWAhwMR9n:}"; char data1[] = "ckagevdxizblqnwtmsrpufyhoj"; char data2[] = "TMQZWKGOIAGLBYHPCRJSUXEVND";
__int64 encryption3(char a1) { unsigned __int8 v2;
v2 = a1; if ( a1 > 64 && a1 <= 70 || a1 > 96 && a1 <= 102 ) return (unsigned __int8)(a1 + 20); if ( a1 > 84 && a1 <= 90 || a1 > 116 && a1 <= 122 ) return (unsigned __int8)(a1 - 20); if ( a1 > 71 && a1 <= 77 || a1 > 103 && a1 <= 109 ) return (unsigned __int8)(a1 + 6); if ( a1 > 77 && a1 <= 83 || a1 > 109 && a1 <= 115 ) return (unsigned __int8)(a1 - 6); if ( a1 == 71 || a1 == 103 ) return (unsigned __int8)(a1 + 13); if ( a1 == 84 || a1 == 116 ) return (unsigned __int8)(a1 - 13); if ( a1 > 47 && a1 <= 57 ) v2 = 105 - a1; return v2; }
__int64 encryption2(char a1) { unsigned __int8 v2;
v2 = a1; if ( a1 > 64 && a1 <= 90 ) return (unsigned __int8)encryption3(a1 + 32); if ( a1 > 96 && a1 <= 122 ) return (unsigned __int8)encryption3(a1 - 32); if ( a1 > 47 && a1 <= 57 ) v2 = encryption3(a1); return v2; }
int encryption(char input, int index) { int v1; char v2; char v3; __int64 v4; char v5; char v6; int v7; char v8; char v9; char v10; char v11; char v12; size_t count; char v15[10]; int v16; int len; char t; char encBuff;
t = input; len = 0; v16 = 1; while ( 1 ) { len = index; if ( t <= 64 || t > 90 ) { if ( t <= 96 || t > 122 ) { if ( t == '_' ) { switch ( v16 + rand() % 7 ) { case 0: encBuff = ':'; break; case 1: encBuff = '&'; break; case 2: encBuff = '+'; break; case 3: encBuff = '*'; break; case 4: encBuff = '\\'; break; case 5: encBuff = '?'; break; case 6: encBuff = '$'; break; case 7: encBuff = '#'; break; default: break; } } else if ( t <= 47 || t > 57 ) { encBuff = t; } else { v12 = encryption2(t); encBuff = v12; } } else { v7 = len % 4; if ( len % 4 == 1 ) { v9 = encryption2(data1[(t - 97) * (len % 4)]); encBuff = v9; } else if ( v7 > 1 ) { if ( v7 == 2 ) { v10 = encryption2(data1[(t - 97) ^ (len % 4)]); encBuff = v10; } else if ( v7 == 3 ) { v11 = encryption2(data1[t - 97 + len % 4]); encBuff = v11; } } else if ( !v7 ) { v8 = encryption2(data1[t - 97 - len % 4]); encBuff = v8; } } } else { v1 = len % 4; if ( len % 4 == 1 ) { v3 = encryption2(data2[t - 65 + len % 4]); encBuff = v3; } else if ( v1 > 1 ) { if ( v1 == 2 ) { v4 = len * (t - 65); v5 = encryption2(data2[(((unsigned __int8)len * (t - 65)) & 3)]); encBuff = v5; } else if ( v1 == 3 ) { v6 = encryption2(data2[(t - 65) ^ (len % 4)]); encBuff = v6; } } else if ( !v1 ) { v2 = encryption2(data2[t - 65 - len % 4]); encBuff = v2; } } return encBuff == encFlag[index]; } }
int main(void) { char input[] = "BRUF{E6oU9Ci_J9_6nWAhwMR9n_}"; int i, j; int count = 0; for ( i = 0; i < strlen(input); i++ ) { for ( j = 32; j <= 127; j++ ) { input[i] = j; if (encryption(j, i)) break; } printf("%c", input[i]); } return 0; }
|
GetFlag!