简单题目我直接跳过了~

https://blog.csdn.net/Jsy050906/article/details/137167432?ops_request_misc=&request_id=&biz_id=102&utm_term=rc4%E5%8A%A0%E5%AF%86&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-137167432.142^v102^pc_search_result_base5

https://blog.csdn.net/vanarrow/article/details/105605253?ops_request_misc=%257B%2522request%255Fid%2522%253A%25220422b28ef2b976a155dd2c0f3ff56e0e%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=0422b28ef2b976a155dd2c0f3ff56e0e&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-105605253-null-null.142^v102^pc_search_result_base5&utm_term=ctf%20Forensics

https://blog.csdn.net/m0_68012373/article/details/129520318

crypto

1.偷渡者前传

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
flag = "flag{???}"
assert len(flag) == 36

new_flag = ''.join(str(ord(c)) for c in flag)

t = []
for i in new_flag:
s = ord(i)
sh = s>>4
sl = s%16
t.append(sh^sl)

b64_table = 'SPCctfabdeghijklmnopqrsuvwxyzABDEFGHIJKLMNOQRTUVWXYZ0123456789+/='

enc = []
for i in range(len(t)//6):
a1 = (t[i*6]<<2) + (t[i*6+1]>>2)
a2 = ((t[i*6+1]%4)<<4) + t[i*6+2]
a3 = (t[i*6+3]<<2) + (t[i*6+4]>>2)
a4 = ((t[i*6+4]%4)<<4) + t[i*6+5]
enc.append(b64_table[a1])
enc.append(b64_table[a2])
enc.append(b64_table[a3])
enc.append(b64_table[a4])

print("".join(enc))

# enc = 'dXd7NCiCtfmGzFdGtGqGgKd2dKNGgYiGeYtOvHgIdKdoNGeodOvFdGdGoKd3NCjY'

详细解释

1. 把 flag 字符串变成 ASCII 数字串

new_flag = ''.join(str(ord(c)) for c in flag)

你有一个字符串 flag,比如 “flag{…}”,每个字符都是字母或者符号。

ord(c) 返回字符 c 的 ASCII 码数字,例如 ‘f’ 是 102。

把所有字符转成对应的数字,并拼接成一个长字符串。例如:

flag{a} -> 'f','l','a','g','{','a','}' -> ASCII: 102 108 97 103 123 97 125

拼接成字符串: “1021089710312397125

这一步把可读的字符串转成纯数字字符串。

2. 对数字字符串的每个字符做处理

1
2
3
4
5
for i in new_flag:
s = ord(i) # i是字符 '0'~'9',ASCII码是48~57
sh = s >> 4 # s的高4位,等于 s // 16
sl = s % 16 # s的低4位
t.append(sh ^ sl) # 高4位和低4位做异或

i 是数字字符,比如 ‘1’,ord(‘1’)=49

对 s 做两步操作:

高4位(sh):比如 49 的二进制是 00110001,右移4位得到 0011(十进制3)

低4位(sl):低4位是 0001(十进制1)

异或 sh ^ sl,如 3 ^ 1 = 2

将每个字符都转换成一个 0-15 范围的数加入列表 t

这样做相当于给原始数字字符做了一种轻度混淆,产生一个新的小数字列表

3. 定义自定义 Base64 字符表

b64_table = 'SPCctfabdeghijklmnopqrsuvwxyzABDEFGHIJKLMNOQRTUVWXYZ0123456789+/='

标准 Base64 表通常是 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

这里用的是自己定义的映射表 b64_table

这个表用于后续把数字索引映射成对应的字符,做最终加密字符

4. 将列表 t 每6个元素一组,编码成4个字符

1
2
3
4
5
6
7
8
9
for i in range(len(t)//6):
a1 = (t[i*6]<<2) + (t[i*6+1]>>2)
a2 = ((t[i*6+1]%4)<<4) + t[i*6+2]
a3 = (t[i*6+3]<<2) + (t[i*6+4]>>2)
a4 = ((t[i*6+4]%4)<<4) + t[i*6+5]
enc.append(b64_table[a1])
enc.append(b64_table[a2])
enc.append(b64_table[a3])
enc.append(b64_table[a4])

这部分代码把每6个 t 中的数,重新组合成4个索引 a1, a2, a3, a4

位操作说明:

t[i*6]<<2 左移2位

t[i*6+1]>>2 右移2位

%4 相当于取2位低位

目的是将 6 个 4bit 小数重新拼成 4 个 6bit 数字,这跟 Base64 编码把 3 字节变成 4 个6bit片段的原理类似

然后用自定义的 b64_table 把每个数字转成字符

最终得到加密字符串 enc

总结

这段代码的核心是将字符串先转成ASCII数字串,再对数字字符串的每个数字字符用特殊位运算做轻度混淆,生成一个数字列表 t

然后将 t 按照 Base64 编码的思想,把每6个4bit数字拼成4个6bit数字

用自定义 Base64 字符表将这4个6bit数字映射成字符,得到加密后的字符串

整体是一个自定义变体的 Base64 加密过程,带了一个基于字符 ASCII 位运算的“预处理”层,增加复杂度防止直接Base64解码

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
enc = 'dXd7NCiCtfmGzFdGtGqGgKd2dKNGgYiGeYtOvHgIdKdoNGeodOvFdGdGoKd3NCjY'
b64_table = 'SPCctfabdeghijklmnopqrsuvwxyzABDEFGHIJKLMNOQRTUVWXYZ0123456789+/='

b64_dict = {c: i for i, c in enumerate(b64_table)}

t = []

for i in range(0, len(enc), 4):
a1 = b64_dict[enc[i]]
a2 = b64_dict[enc[i+1]]
a3 = b64_dict[enc[i+2]]
a4 = b64_dict[enc[i+3]]

t0 = a1 >> 2
t1 = ((a1 & 3) << 2) | (a2 >> 4)
t2 = a2 & 15
t3 = a3 >> 2
t4 = ((a3 & 3) << 2) | (a4 >> 4)
t5 = a4 & 15

t.extend([t0, t1, t2, t3, t4, t5])

ascii_chars = []
for val in t:
found = False
for s in range(48, 58):
sh = s >> 4
sl = s & 15
if (sh ^ sl) == val:
ascii_chars.append(chr(s))
found = True
break
if not found:
ascii_chars.append('?')

ascii_str = "".join(ascii_chars)

def decode_ascii_string(s):
res = []
i = 0
while i < len(s):
if i + 3 <= len(s):
num = int(s[i:i+3])
if 32 <= num <= 126:
res.append(chr(num))
i += 3
continue
if i + 2 <= len(s):
num = int(s[i:i+2])
if 32 <= num <= 126:
res.append(chr(num))
i += 2
continue
res.append('?')
i += 1
return "".join(res)

flag = decode_ascii_string(ascii_str)
print("解密得到的flag是:", flag)

Reverse

1.ezMaze(迷宫+花指令)

CTF逆向Reverse 花指令介绍 and NSSCTF靶场入门题目复现_ctf逆向工程基础题-CSDN博客

一下是详细解释(适合初学仔细看)

ezmaze解题思路

跳转到14000185F

然后看到

这里有call而没有ret出现“栈不平衡”,把这里的十六进制码的call(E8)转成90(nop啥也不做)就不会出现“栈不平衡”

修改后就直接看到伪代码了:

迷宫到手,flag:flag{aassddssaasssddwddddsdddd}