BUUCTF--SimpleRev
Posted mayfly-nymph
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BUUCTF--SimpleRev相关的知识,希望对你有一定的参考价值。
1.准备
获取信息
- 64位文件
2.IDA打开
将main函数反编译为C代码
1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) 2 3 int v3; // eax 4 char v4; // [rsp+Fh] [rbp-1h] 5 6 while ( 1 ) 7 8 while ( 1 ) 9 10 printf("Welcome to CTF game!\\nPlease input d/D to start or input q/Q to quit this program: ", argv, envp); 11 v4 = getchar(); 12 if ( v4 != ‘d‘ && v4 != ‘D‘ ) 13 break; 14 Decry(); 15 16 if ( v4 == ‘q‘ || v4 == ‘Q‘ ) 17 Exit(); 18 puts("Input fault format!"); 19 v3 = getchar(); 20 putchar(v3); 21 22
3.代码分析
很明显,这道题的关键在于Decry()
1 unsigned __int64 Decry() 2 3 char v1; // [rsp+Fh] [rbp-51h] 4 int v2; // [rsp+10h] [rbp-50h] 5 int v3; // [rsp+14h] [rbp-4Ch] 6 int i; // [rsp+18h] [rbp-48h] 7 int v5; // [rsp+1Ch] [rbp-44h] 8 char src[8]; // [rsp+20h] [rbp-40h] 9 __int64 v7; // [rsp+28h] [rbp-38h] 10 int v8; // [rsp+30h] [rbp-30h] 11 __int64 v9; // [rsp+40h] [rbp-20h] 12 __int64 v10; // [rsp+48h] [rbp-18h] 13 int v11; // [rsp+50h] [rbp-10h] 14 unsigned __int64 v12; // [rsp+58h] [rbp-8h] 15 16 v12 = __readfsqword(0x28u); 17 *(_QWORD *)src = ‘SLCDN‘; 18 v7 = 0LL; 19 v8 = 0; 20 v9 = ‘wodah‘; 21 v10 = 0LL; 22 v11 = 0; 23 text = join(key3, (const char *)&v9); // text = ‘killshadow‘ 24 strcpy(key, key1); 25 strcat(key, src); // key = ‘ADSFKNDCLS‘ 26 v2 = 0; 27 v3 = 0; 28 getchar(); 29 v5 = strlen(key); // v5 = 10 30 for ( i = 0; i < v5; ++i ) 31 32 if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )// key = ‘adsfkndcls‘ 33 key[i] = key[v3 % v5] + 32; 34 ++v3; 35 36 printf("Please input your flag:", src); 37 while ( 1 ) 38 39 v1 = getchar(); 40 if ( v1 == 10 ) 41 break; 42 if ( v1 == 32 ) 43 44 ++v2; 45 46 else 47 48 if ( v1 <= 96 || v1 > 122 ) 49 50 if ( v1 > 64 && v1 <= 90 ) // 大写字母 51 str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; 52 53 else // 小写字母 54 55 str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; 56 57 if ( !(v3 % v5) ) 58 putchar(‘ ‘); 59 ++v2; 60 61 62 if ( !strcmp(text, str2) ) 63 puts("Congratulation!\\n"); 64 else 65 puts("Try again!\\n"); 66 return __readfsqword(0x28u) ^ v12; 67
转换成可以运行的C代码是
1 #include <bits/stdc++.h> 2 3 #pragma warning(disable:4996) 4 5 int main(void) 6 7 int i, j, n = 0, v5 = 10, v3 = 0, v2 = 0; 8 char v1; 9 char flag[11] = 0 ; 10 char str2[104] = 0 ; 11 char key[] = "ADSFKNDCLS"; 12 char text[] = "killshadow"; 13 14 15 for (i = 0; i < v5; ++i) 16 17 if (key[v3 % v5] > 64 && key[v3 % v5] <= 90) 18 key[i] = key[v3 % v5] + 32; 19 ++v3; 20 21 printf("Please input your flag:"); 22 while (1) 23 24 v1 = getchar(); 25 printf("v1:%c\\nv2:%d\\n\\n", v1, v2); 26 if (v1 == 10) 27 printf("进入1\\n"); 28 break; 29 30 if (v1 == 32) 31 32 printf("进入2\\n"); 33 ++v2; 34 35 else 36 37 if (v1 <= 96 || v1 > 122) 38 39 if (v1 > 64 && v1 <= 90) 40 str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; 41 printf("计算1\\n"); 42 43 44 else 45 46 str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; 47 printf("计算1\\n"); 48 49 if (!(v3 % v5)) 50 putchar(‘ ‘); 51 ++v2; 52 53 54 if (!strcmp(text, str2)) 55 puts("Congratulation!\\n"); 56 else 57 printf("str2:%s\\n", str2); 58 puts("Try again!\\n"); 59 60 61 system("PAUSE"); 62 return 0; 63
第30~35行代码的实际作用是将大写字母转换为小写。
第37~61行代码实际上就是遍历输入的字符(flag),进行str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;运算,最后与text比较。
因此我们只要反向就能求出输入的v1
4.程序获取flag
#include <bits/stdc++.h> #pragma warning(disable:4996) int main(void) int i, j, n = 0, v5 = 10, v3 = 0, v2 = 0; char v1; char flag[11] = 0 ; char str2[104] = 0 ; char key[] = "ADSFKNDCLS"; char text[] = "killshadow"; for (i = 0; i < v5; ++i) if (key[v3 % v5] > 64 && key[v3 % v5] <= 90) key[i] = key[v3 % v5] + 32; ++v3; for (j = 0; j < 10; ++j) for (v2 = 0; v2 < 10; ++v2) v1 = text[v2] - 97 + 26 * j - 97 + key[v3++ % v5] + 39; if ((v1 >= 65 && v1 <= 90) || (v1 >= 97 && v1 <= 122)) flag[v2] = v1; if (++n == 10) printf("%s\\n", flag); system("PAUSE"); return 0; system("PAUSE"); return 0;
5.get flag!
flagKLDQCUDFZO
以上是关于BUUCTF--SimpleRev的主要内容,如果未能解决你的问题,请参考以下文章