简单题目我直接跳过了~
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}