[BJDCTF2020]BJD hamburger competition 打开是一个游戏
6
自己没有写出来,看的wp
由于unity是用C#开发,所以用dnspy
https://github.com/dnSpy/dnSpy
在相同文件夹中找到Assembly-CSharp.dll
然后用dnspy打开
在这个类里面找到了关键代码
将字符串找个在线网站解密之后就是1001
所以flag就是 BJDCTF{MD5(1001)}
取前二十位
flag{B8C37E33DEFDE51CF91E}
[ACTF新生赛2020]Oruga IDA打开
找到主函数
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 __int64 __fastcall main(int a1, char **a2, char **a3) { __int64 result; // rax int i; // [rsp+0h] [rbp-40h] char s1[6]; // [rsp+4h] [rbp-3Ch] BYREF char s2[6]; // [rsp+Ah] [rbp-36h] BYREF char s[40]; // [rsp+10h] [rbp-30h] BYREF unsigned __int64 v8; // [rsp+38h] [rbp-8h] v8 = __readfsqword(0x28u); memset(s, 0, 0x19uLL); printf("Tell me the flag:"); scanf("%s", s); strcpy(s2, "actf{"); for ( i = 0; i <= 4; ++i ) s1[i] = s[i]; s1[5] = 0; if ( !strcmp(s1, s2) ) { if ( sub_78A((__int64)s) ) printf("That's True Flag!"); else printf("don't stop trying..."); result = 0LL; } else { printf("Format false!"); result = 0LL; } return result; }
第一眼甚至觉得flag是4位的
最终判断里有个函数
点进去
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 _BOOL8 __fastcall sub_78A(__int64 a1) { int v2; // [rsp+Ch] [rbp-Ch] int v3; // [rsp+10h] [rbp-8h] int v4; // [rsp+14h] [rbp-4h] v2 = 0; v3 = 5; v4 = 0; while ( byte_201020[v2] != 33 ) { v2 -= v4; if ( *(_BYTE *)(v3 + a1) != 'W' || v4 == -16 ) { if ( *(_BYTE *)(v3 + a1) != 'E' || v4 == 1 ) { if ( *(_BYTE *)(v3 + a1) != 'M' || v4 == 16 ) { if ( *(_BYTE *)(v3 + a1) != 'J' || v4 == -1 ) return 0LL; v4 = -1; } else { v4 = 16; } } else { v4 = 1; } } else { v4 = -16; } ++v3; while ( !byte_201020[v2] ) { if ( v4 == -1 && (v2 & 0xF) == 0 ) return 0LL; if ( v4 == 1 && v2 % 16 == 15 ) return 0LL; if ( v4 == 16 && (unsigned int)(v2 - 240) <= 0xF ) return 0LL; if ( v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E ) return 0LL; v2 += v4; } } return *(_BYTE *)(v3 + a1) == 125; }
其中的字符数组
是一个迷宫题目
WEMJ分别代表上右下左
16X16
不能触碰边缘
只有0可以走,其他的相当于墙
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ☆ □ □ □ ■ □ □ □ □ □ □ □ ■ ■ ■ ■ □ □ □ ■ ■ □ □ □ ■ ■ □ □ □ □ □ □ □ □ □ □ □ □ □ □ ■ ■ □ ■ ■ □ □ □ □ □ □ ■ □ ■ ■ □ ■ ■ □ ■ ■ □ □ □ □ □ □ ■ □ ■ ■ □ ■ ■ □ ■ □ □ □ □ □ □ ■ ■ □ ■ ■ □ □ □ □ ■ □ □ □ □ □ □ □ □ □ ■ ■ □ □ □ □ ■ □ □ □ □ ■ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ ■ □ □ □ □ □ □ □ □ □ ■ ■ ■ □ □ □ ■ □ □ □ □ □ □ □ □ □ □ ■ ■ ■ □ □ □ □ ■ ■ □ □ □ ■ □ ■ □ ■ □ ■ □ □ □ □ ■ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ ■ ■ ■ ■ ■ ■ □ ■ □ ■ □ ■ □ □ □ □ ■ □ □ ■ □ ■ □ ■ □ ■ □ ■ □ □ □ □ ■ □ □ ■ □ ■ □ ■ □ ■ □ ■ ★ □ □ □ ■ ■
flag{MEWEMEWJMEWJM}
[Zer0pts2020]easy strcmp 主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 __int64 __fastcall main(int a1, char **a2, char **a3) { if ( a1 > 1 ) { if ( !strcmp(a2[1], "zer0pts{********CENSORED********}") ) puts("Correct!"); else puts("Wrong!"); } else { printf("Usage: %s <FLAG>\n", *a2); } return 0LL; }
看起来很简单,其实不然
主函数里找不到任何加密
在其他函数中找到了同时a2的参数
1 2 3 4 5 6 7 8 9 10 11 12 _int64 __fastcall sub_6EA(__int64 a1, __int64 a2) { int i; // [rsp+18h] [rbp-8h] int v4; // [rsp+18h] [rbp-8h] int j; // [rsp+1Ch] [rbp-4h] for ( i = 0; *(_BYTE *)(i + a1); ++i ) ; v4 = (i >> 3) + 1; for ( j = 0; j < v4; ++j ) *(_QWORD *)(8 * j + a1) -= qword_201060[j]; return qwor
注意:内存中存储为小端存储,所以我们需要在将字符串转换成ascii后需要逆序一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 enc = "********CENSORED********" m = [0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B] import binascii flag = b"" # 由于是字节操作,需要在前面加上b for i in range(3): p = enc[i * 8:(i + 1) * 8] # 将enc字符串8位一组分开 print(p) a = binascii.b2a_hex(p.encode('ascii')[::-1]) # 将分开后的字符串转每一位转换成ascii,然后逆序 print(a) b = binascii.a2b_hex(hex(int(a, 16) + m[i])[2:])[::-1] # (enc[i]的ascii+m[i])的结果是16进制,[2::]是舍弃开头的0x,然后[::-1]逆序 print(b) print('\n') flag += b # 拼凑每组还原后的结果 print(flag)
flag{l3ts_m4k3_4_DETOUR_t0d4y}
[ACTF新生赛2020]Universe_final_answer IDA64位打开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 __int64 __fastcall main(int a1, char **a2, char **a3) { char v4[32]; // [rsp+0h] [rbp-A8h] BYREF char v5[104]; // [rsp+20h] [rbp-88h] BYREF unsigned __int64 v6; // [rsp+88h] [rbp-20h] v6 = __readfsqword(0x28u); __printf_chk(1LL, (__int64)"Please give me the key string:", (__int64)a3); scanf("%s", v5); if ( sub_560948800860(v5) ) { sub_560948800C50(v5, v4); __printf_chk(1LL, (__int64)"Judgement pass! flag is actf{%s_%s}\n", (__int64)v5); } else { puts("False key!"); } return 0LL; }
点开关键函数
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 bool __fastcall sub_560948800860(char *a1) { int v1; // ecx int v2; // esi int v3; // edx int v4; // er9 int v5; // er11 int v6; // ebp int v7; // ebx int v8; // er8 int v9; // er10 bool result; // al int v11; // [rsp+0h] [rbp-38h] v1 = a1[1]; v2 = *a1; v3 = a1[2]; v4 = a1[3]; v5 = a1[4]; v6 = a1[6]; v7 = a1[5]; v8 = a1[7]; v9 = a1[8]; result = 0; if ( -85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 ) { v11 = a1[9]; if ( 30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400 && -103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 << 6) - 120 * v9 == -10283 && 71 * v6 + (v7 << 7) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855 && 5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944 && -54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222 && -83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258 && 81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559 && 101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308 ) { result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697; } } return result; }
很明显是一组方程式
需要用到z3库
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 from z3 import * #s = Solver() v1 = Int('v1') v2 = Int('v2') v3 = Int('v3') v4 = Int('v4') v5 = Int('v5') v6 = Int('v6') v7 = Int('v7') v8 = Int('v8') v9 = Int('v9') v11 = Int('v11') s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613) s.add( 30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400) s.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - ( v6 * 64) - 120 * v9 == -10283) s.add(71 * v6 + (v7 * 128) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855) s.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944) s.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222) s.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258) s.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559) s.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308) s.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697) if s.check() == sat: result = s.model() print(result) #flag{F0uRTy_7w@_42}
特殊的 BASE64 针灸师换标
一枪秒了 有什么好说的
1 2 3 4 5 6 7 8 9 10 11 12 import base64 import string str1 = 'mTyqm7wjODkrNLcWl0eqO8K8gc1BPk1GNLgUpI==' # 更改后的密码表 string1 = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+" # 原表 string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" print(base64.b64decode(str1.translate(str.maketrans(string1, string2)))) #flag{Special_Base64_By_Lich}
[WUSTCTF2020]level4 主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int __cdecl main(int argc, const char **argv, const char **envp) { puts("Practice my Data Structure code....."); puts("Typing....Struct.....char....*left....*right............emmmmm...OK!"); init("Typing....Struct.....char....*left....*right............emmmmm...OK!", argv); puts("Traversal!"); printf("Traversal type 1:"); type1((char *)&unk_601290); printf("\nTraversal type 2:"); type2((char *)&unk_601290); printf("\nTraversal type 3:"); puts(" //type3(&x[22]); No way!"); puts(&byte_400A37); return 0; }
有两个函数type1 type2
点击去看一下
1 2 3 4 5 6 7 8 9 10 11 12 __int64 __fastcall type1(char *a1) { __int64 result; // rax if ( a1 ) { type1(*((_QWORD *)a1 + 1)); putchar(*a1); result = type1(*((_QWORD *)a1 + 2)); } return result; }
1 2 3 4 5 6 7 8 9 10 11 12 int __fastcall type2(char *a1) { int result; // eax if ( a1 ) { type2(*((_QWORD *)a1 + 1)); type2(*((_QWORD *)a1 + 2)); result = putchar(*a1); } return result; }
涉及到数据结构知识点
https://blog.csdn.net/chinesekobe/article/details/110874773?ops_request_misc=%7B%22request%5Fid%22%3A%22165959738916781790739379%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=165959738916781790739379&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2 top_positive~default-1-110874773-null-null.142%5Ev39%5Epc_rank_v37&utm_term=%E4%BA%8C%E5%8F%89%E6%A0%91&spm=1018.2226.3001.4187
https://www.bilibili.com/video/BV1Qx411m7Lb?spm_id_from=333.999.0.0
找了一些视频文章学习了一下
二叉树的中序和后序
通过中序后序求出前序
https://blog.csdn.net/drdairen/article/details/71338066
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> using namespace std; char post[] = "20f0Th{2tsIS_icArE}e7__w"; // 后序遍历结果 char mid[] = "2f0t02T{hcsiI_SwA__r7Ee}"; // 中序遍历结果 void pre(int root, int start, int end) { if (start > end) return; int i = start; while (i < end && mid[i] != post[root]) i++; //定位根在中序的位置 cout << mid[i]; //访问当前处理的树的根 pre(root - 1 - (end - i), start, i - 1); //递归处理左子树 pre(root - 1, i + 1, end); //递归处理右子树 } int main() { pre(24, 0, 24); return 0; } # wctf2020{This_IS_A_7reE}