[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;
}

其中的字符数组

是一个迷宫题目

  1. WEMJ分别代表上右下左
  2. 16X16
  3. 不能触碰边缘
  4. 只有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-2top_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}