Misc
量子迷宫
Challenge
未来量子实验室的AI将机密数据加密成了量子迷宫,每一行代表一个量子比特操作。只有通过逆向坍缩观测,才能还原出被量子噪声掩盖的密钥。实验室遗留的日志文件似乎隐藏着关键线索(flag格式:palu{32位md5})
Solution

提取出QUBIT|后面的字符(索引为6)并连接->二进制转字符(字节长度为8)
data = """QUBIT|0⟩ → X GateQUBIT|1⟩ → Y Gate PHOTON: 2492°QUBIT|1⟩ → X Gate...""" bits = ''.join([line[6] for line in data.splitlines() if len(line) > 6])for i in range(0, len(bits), 8): chunk = bits[i:i+8] char = chr(int(chunk, 2)) print(char,end="")palu{aea437c12b149750383fe56727ec5344}时间折叠
Challenge
某服务器系统日志中发现异常的时间戳记录,所有时间均显示为”1970-01-01 08:00:00”。技术员发现日志中存在与时间无关的二进制干扰信号,你能从被折叠的时空中找到隐藏的flag吗?
Solution
data = """[1970-01-01 08:00:00] System boot sequence initiated[1970-01-01 08:00:00] SYSTEM ALERT: Time anomaly detected at 00000000fe ns[1970-01-01 08:00:00] SYSTEM ALERT: Time anomaly detected at 10000000ef ns...[1970-01-01 08:00:00] SYSTEM ALERT: Time anomaly detected at 380000000f3 ns[1970-01-01 08:00:00] System entering chronostasis mode""" result = ' '.join([line[-5:-3] for line in data.splitlines() if len(line) > 60]) # 将十六进制字符串转换为字节数组byte_data = bytes.fromhex(result) # 尝试 XOR 解密def xor_decrypt(data, key): return bytes([b ^ key for b in data]) # 假设密钥是一个单字节值(0x00 到 0xFF)for key in range(256): decrypted_data = xor_decrypt(byte_data, key) try: decrypted_string = decrypted_data.decode('utf-8') if decrypted_string.startswith("palu"): print(f"找到匹配的密钥: {key}") print("还原的目标字符串:", decrypted_string) break except UnicodeDecodeError: continueelse: print("未找到以 'palu' 开头的字符串")XOR解密,爆破得到密钥为142
palu{This_is_A_Sample_Flag_Change_Me!!}TopSecret
Challenge
你从某机密设施偷取了一份文件,但你被发现了,最后只收到一份乱码,你能从中提取到有用的信息吗?
Solution
看着就像base64,直接搜cGFsd

cGFsdXtZb3VfcmVfYV9yZWFsXzUwd30=复制下来拿去解码

palu{You_re_a_real_50w}screenshot
Challenge
有个笨比截图flag的时候不小心发到群里了,细心和反回撤的群友已经偷偷记录下来了
Solution
苹果手机的无效打码还挺有名的,改一下曝光亮度那些就能出
不过因为我懒得调参数所以就用StegSolve了

palu{why_you_spy_me}几何闪烁的秘密
Challenge
我们找到了一张神秘的GIF图片,里面似乎隐藏着重要信息。仔细观察,你会发现四个几何体在不同时刻闪现出一些奇怪的字符。你能从中提取出完整的Flag吗?
Solution
在蓝色圆圈发现flag头经过base64编码后的结果cGFsd
分别提取图片里的字母
圆形:cGFsXttcFsdXtcGFdXtt
方形:YXN0XJfYN0ZXfYXNZXJf
三角形:b2Zf2VvbZfZ2vb2ZZ2Vv
五边形:bWV0nl9bV0cn9bWVcnl9
这里拿圆形举例
cGFsXttcFsdXtcGFdXtt ->
cGFsXtt cFsdXt cGFdXtt ->
求同存异得到 cGFsdXtt
同理得到其他几个图形对应的字符串,拼接得到cGFsdXttYXN0ZXJfb2ZfZ2VvbWV0cnl9
解码得到flag
palu{master_of_geometry}dorodoro
Challenge
Solution


import requests url = "http://challenge.qsnctf.com:31868/check" data_template = { "part1": "", "part2": "", "part3": "", "part4": ""} def orange(part): for n in range(1, 100): # "哦润吉"重复n次 data_template[f"part{part}"] = "哦润吉" * n response = requests.post(url, json=data_template) result = response.json() if result.get("feedback", {}).get(f"part{part}") == True: print(f"[*] 找到了正确的 part{part} 值!") print(data_template[f'part{part}']) return result # print(orange(1))# print(orange(2))# print(orange(3))print(orange(4))时间循环的信使
Challenge
某神秘组织通过时间循环传递加密信息,我们在捕获的流量日志中发现异常时间戳。日志文件显示:“在错误的时间做正确的事,在正确的时间解开谜题”,flag格式为palu{xxx}
Solution
先把附件丢给AI让它帮忙按时间从小到大排序,然后手动清理数据,只留下循环的
然后把循环的数字拼起来(这里的操作是取每行的最后一个字符)
data = """1745396077|777777771745396138|000000001745396199|666666661745396260|111111111745396321|666666661745396382|cccccccc1745396443|777777771745396504|555555551745396565|777777771745396626|bbbbbbbb1745396687|555555551745396748|444444441745396809|666666661745396870|999999991745396931|666666661745396992|dddddddd1745397053|666666661745397114|555555551745397175|555555551745397236|ffffffff1745397297|333333331745397358|111111111745397419|777777771745397480|333333331745397541|555555551745397602|ffffffff1745397663|666666661745397724|333333331745397785|777777771745397846|999999991745397907|666666661745397968|333333331745398029|666666661745398090|cccccccc1745398151|333333331745398212|111111111745398273|666666661745398334|333333331745398395|444444441745398456|000000001745398517|666666661745398578|cccccccc1745398639|555555551745398700|ffffffff1745398761|333333331745398822|000000001745398883|777777771745398944|888888881745399005|777777771745399066|dddddddd""" last_chars = [line[-1] for line in data.splitlines() if line]print(''.join(last_chars))拼起来得到70616c757b54696d655f31735f6379636c3163406c5f30787d,拿去CyberChef十六进制转字符串

palu{Time_1s_cycl1c@l_0x}时间交织的密语
Challenge
我们在暗网服务器中发现了一个神秘文件,据说是某个黑客组织的「时空密钥」,文件内容似乎由大量时间戳构成。情报显示,只有将时间维度与二进制低语结合才能解开秘密。线索隐藏在时空的起点与终点之间。
Solution
“文件内容似乎由大量时间戳构成”提示了要把十六进制转为十进制得到时间戳
“将时间维度与二进制低语结合”提示了要取时间戳的最后两位
“线索隐藏在时空的起点与终点之间”提示了最终解出来的结果要把第一个和最后一个字符去除,保留中间的部分
import struct with open("timestream.bin", 'rb') as f: data = f.read() hex_result = '' for i in range(0, len(data), 4): chunk = data[i:i+4] # 使用大端模式解包为无符号整数(UNIX 时间戳) timestamp, = struct.unpack('>I', chunk) # 取模后转为十六进制,去掉前缀 '0x' hex_digit = format(timestamp % 100, 'x') # 取最后两位 hex_result += hex_digit flag = bytes.fromhex(hex_result[1:-1]).decode('utf-8') # 保留中间部分print(flag)palu{Time_1s_B1nary_Whisper}最弱帕鲁
Challenge
刚学习网络安全的帕鲁下班回来天塌了,自己珍藏的文件居然忘记了密码!不对…知道密码也没用啊!
Solution
jsteg隐写,工具下载lukechampine/jsteg
jsteg.exe reveal 弱帕鲁.jpg
SuperPassw0rdNeverGuess
得到解压密码SuperPassw0rdNeverGuess
{% note warning %}
等WP复现ing
{% endnote %}
Web
CatBank
Challenge
🐱 欢迎光临猫猫银行!
一家由 喵星人 运营的银行!你励志要 赚一百万,但……
这家银行的代码是猫爪写的 🐾💻,好像有漏洞?
猫猫银行最近有网络波动 在被未知势力攻击!!!
Solution
先注册两个号,就分别叫1和2吧
登录账号2给1转账0.01元

抓包找到这条记录,修改金额后重新发送(金额要大于等于一百万)

然后登录账号1,此时给任意一个用户转账一百万就会显示flag

palu{4e730efb2ca3433e806f150c53f4bfa2}Reverse
PosltionalXOR
Chall
qcoqVh{ebccocH^@Lgt{gt|g
Solution
根据加密算法分析,每个字符的加密密钥为其在字符串中的位置索引加1。因此,解密时需将每个密文字符与其位置索引加1后的值进行异或运算。
ciphertext = "qcoq~Vh{e~bccocH^@Lgt{gt|g"transformed = []for idx, char in enumerate(ciphertext): position = idx + 1 original_ascii = ord(char) new_ascii = original_ascii ^ position transformed_char = chr(new_ascii) transformed.append(transformed_char)print(''.join(transformed))palu{PosltionalXOR_sample}PaluFlat
Challenge
帕鲁不是死肥宅,帕鲁不胖!帕鲁头晕目眩绝对不是炫多了!
Solution
用010editor打开附件发现是7z压缩包,改后缀解压后用IDA分析。
我们通过静态分析发现,函数的大致流程如下:
对于每个字符 a1[i]:
-
使用
"flat"或"palu"中的一个字符串循环异或:cchar key = flat_or_palu[i % len];char tmp = a1[i] ^ key; -
对异或后的
tmp做一些变换:- 可能是 nibble swap(交换高低 4 位)
- 可能减去 85
- 可能按位取反
这些操作根据 n12345 的比特位动态选择。
不过,由于 n12345 = 12345 是固定的,因此每一步的操作是固定的。
既然整个过程是确定性的,我们可以直接暴力枚举所有可能的 ASCII 字符,找到经过 sub_401550() 后等于 v5[i] 的字符即可。
def encrypt_char(c, index): # 模拟 sub_401550 的单个字符处理逻辑 # 根据 index 决定使用哪个 key 字符串 key_str = "flat" if (index & 1) else "palu" key = key_str[index % len(key_str)] tmp = c ^ ord(key) tmp = ((tmp << 4) & 0xF0) | ((tmp >> 4) & 0x0F) # Nibble swap tmp -= 85 tmp = ~tmp & 0xFF # 取反并保持在 byte 范围 return tmp # v5 数组v5 = [ 84, -124, 84, 68, -92, -78, -124, 84, 98, 50, -113, 84, 98, -78, 84, 3, 20, -128, 67, 19] # 转换为无符号字节v5_bytes = [b & 0xFF for b in v5] flag = ''for i in range(len(v5_bytes)): target = v5_bytes[i] found = False for c in range(32, 127): # 可打印 ASCII 范围 if encrypt_char(c, i) == target: flag += chr(c) found = True break if not found: flag += '?' print(flag)palu{Fat_N0t_Flat!}