RSA_Quartic_Quandary解题步骤:
rsa解密,需要p和q,我们可以设 p, q 为未知数,列方程组 p, q = symbols(‘p q’, integer=True) eq1 = Eq(p * q, n) eq2 = Eq(p4 + q4, s)来求解
解题脚本:
from Crypto.Util.number import long_to_bytes
from sympy import symbols, Eq, solve
# 直接赋值参数
n = 125997816345753096048865891139073286898143461169514858050232837657906289840897974068391106608902082960171083817785532702158298589600947834699494234633846206712414663927142998976208173208829799860130354978308649020815886262453865196867390105038666506017720712272359417586671917060323891124382072599746305448903
e = 65537
c = 16076213508704830809521504161524867240789661063230251272973700316524961511842110066547743812160813341691286895800830395413052502516451815705610447484880112548934311914559776633140762863945819054432492392315491109745915225117227073045171062365772401296382778452901831550773993089344837645958797206220200272941
s = 35935569267272146368441512592153486419244649035623643902985220815940198358146024590300394059909370115858091217597774010493938674472746828352595432824315405933241792789402041405932624651226442192749572918686958461029988244396875361295785103356745756304497466567342796329331150560777052588294638069488836419744297241409127729615544668547101580333420563318486256358906310909703237944327684178950282413703357020770127158209107658407007489563388980582632159120621869165333921661377997970334407786581024278698231418756106787058054355713472306409772260619117725561889350862414726861327985706773512963177174611689685575805282
# 设 p, q 为未知数,列方程组
p, q = symbols('p q', integer=True)
eq1 = Eq(p * q, n)
eq2 = Eq(p**4 + q**4, s)
# 求解 p, q
sol = solve((eq1, eq2), (p, q))
for _p, _q in sol:
if _p > 1 and _q > 1:
p, q = int(_p), int(_q)
break
# 计算私钥 d
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
# 解密
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)
PositionalXOR解题步骤:
密文是 cipher = "qcoq~Vh{e~bccocH^@Lgt{gt|g"
Flag格式是 palu{},说明解密后的字符串里应该包含这个特征。
加密是基于“位置”的异或,也就是说:密文字符 = 明文字符 XOR 某个和字符位置相关的数
题目说“基于位置的异或”,所以密钥 K 是字符所在索引 i 的函数。
位置相关的key不一定简单线性,可能有偏移或倍数。写脚本穷举
解题脚本:
cipher = "qcoq~Vh{e~bccocH^@Lgt{gt|g"
def try_decrypt(cipher, key_func):
n = len(cipher)
plain_chars = []
for i, c in enumerate(cipher):
key = key_func(i, n)
plain_c = chr(ord(c) ^ key)
plain_chars.append(plain_c)
return "".join(plain_chars)
def main():
cipher = "qcoq~Vh{e~bccocH^@Lgt{gt|g"
n = len(cipher)
for start_i in [0, 1]:
for offset in range(31): # 0 ~ 30
for factor in range(1, 11): # 1 ~ 10
plain = try_decrypt(cipher, lambda i, n: ((i + offset) * factor) % 256 if start_i == 0 else ((i + start_i + offset) * factor) % 256)
if "palu{" in plain:
print(f"[+] Found flag! start_i={start_i}, offset={offset}, factor={factor}")
print(plain)
return
print("[-] No flag found in tested key ranges.")
if __name__ == "__main__":
main()
时间折叠(TimeFold Paradox)解题步骤:
观察题目的值,可以发现一个模式:
- 每组高位值是
0x0 ~ 0x38,每次+0x10,像是一个线性递增的“时间”。 - 每组低位保持在 8位(2字节)范围内,
- 所以我们可以假设,这个“timestamp”其实是一个结构体编码:php-template
<index (高位)> <byte (低位)>
我们从每个 timestamp 中提取低位两个 hex 数字,构造成一个字节流:
fe ef e2 fb f5 da e6 e7 fd d1 e7 fd d1 cf d1 dd ef e3 fe e2 eb d1 c8 e2 ef e9 d1 cd e6 ef e0 e9 eb d1 c3 eb af af f3
推测是某种简单加密或者编码:
比如XOR 解密
解题脚本:
data = bytes.fromhex("feefe2fbf5dae6e7fdd1e7fdd1cfd1ddefe3fee2ebd1c8e2efe9d1cde6efe0e9ebd1c3ebafaff3")
# 单字节 XOR 爆破
for k in range(256):
decoded = bytes([b ^ k for b in data])
if all(32 <= c <= 126 for c in decoded): # 可打印 ASCII
print(f"Key: {k:02x} -> {decoded.decode()}")
然后在输出中找到Key: 8e -> palu{This_is_A_Sample_Flag_Change_Me!!}
TopSecret解题步骤:
看文件像base64加密,而palu的base64加密为cGFs,所以直接在文件中查找cGFs
找到疑似有重叠的密文 cGFsdXtZb3VfcmVfYV9yZWFsXzUwd30= cwPIy0wF54q32yv+WXlWo7yCCuyR4M7GeTEp1=JNLNUqPeYBNKHSOuLA0lV
base64解码得到palu{You_re_a_real_50w}
循环锁链解题步骤:
把文件放到010editor里面,提取出16进制,11 0D 19 0E 12 2A 74 42 31 2B 25 00 07 0C 16 39 27 21 03 00 28 0D 27 20 26 2C 19 00 0C 3B 04 39 22 19 52 44 0D
如果我们把题目“锁在了一个无尽的循环中”理解为:
每个明文字符是由密文当前字符与前一个明文字符 XOR 得到的
就像是:
vbnet复制编辑plaintext[0] = ciphertext[0] ^ key[0]
plaintext[i] = ciphertext[i] ^ plaintext[i - 1]
我们知道:
- plaintext 以
palu{开头 - 我们可以爆破密文的起点(旋转)
- 遍历所有偏移(rotate)
- 假设第一个明文字符是
p,根据密文推回 key 或前态 - 用链式 XOR 递推解出整个明文
- 找到符合
palu{开头和}结尾的内容
解题脚本:
ciphertext = [
0x11, 0x0D, 0x19, 0x0E, 0x12, 0x2A, 0x74, 0x42, 0x31, 0x2B, 0x25, 0x00,
0x07, 0x0C, 0x16, 0x39, 0x27, 0x21, 0x03, 0x00, 0x28, 0x0D, 0x27, 0x20,
0x26, 0x2C, 0x19, 0x00, 0x0C, 0x3B, 0x04, 0x39, 0x22, 0x19, 0x52, 0x44,
0x0D
]
known_prefix = "palu{"
known_ascii = [ord(c) for c in known_prefix]
n = len(ciphertext)
def is_printable(s):
return all(32 <= ord(c) <= 126 for c in s)
for offset in range(n):
rotated = ciphertext[offset:] + ciphertext[:offset]
first_plain = ord('p')
key = rotated[0] ^ first_plain
plaintext = [first_plain]
try:
for i in range(1, n):
next_char = rotated[i] ^ plaintext[i - 1]
if not (0x20 <= next_char <= 0x7E):
raise ValueError("non-printable")
plaintext.append(next_char)
decoded = ''.join(chr(c) for c in plaintext)
if decoded.startswith(known_prefix) and "}" in decoded:
flag = decoded[:decoded.index("}") + 1]
print(f"Found flag at offset {offset}, key = {key:#x}")
print(f"Flag: {flag}")
break
except:
continue
轮回密码解题步骤:
题目附件实现了一个名为 samsara_encrypt 的加密函数,该函数使用了三步加密过程:
- 循环移位加密 :根据 key_word 的长度计算出一个循环步长 cycle_step ,然后对输入的 text 进行循环移位加密。具体来说,每个字节的高位和低位进行循环移位。
- Base85编码 :将第一步得到的字节序列进行Base85编码。这是一种将二进制数据编码为可打印字符的方式。
- 再次循环移位加密 :对Base85编码后的结果再次进行循环移位加密。
- 异或加密 :最后一步是将第三步的结果与 key_word 进行异或操作,得到最终的加密结果。
题目给了提示
密文:zQL0AmL5D2NvD2NuAQR6ZwZk
key;Bore
解题脚本:
import base64
def rotate_left(byte, steps):
return ((byte << steps) & 0xFF) | (byte >> (8 - steps))
def samsara_decrypt(cipher, key_word):
cycle_step = len(key_word) % 6 + 1
# 异或密钥得到phase3
phase3 = bytes([c ^ key_word[i % len(key_word)] for i, c in enumerate(cipher)])
# phase3循环左移cycle_step位得到phase2
phase2 = bytes([rotate_left(c, cycle_step) for c in phase3])
# Base85解码得到phase1
phase1 = base64.b85decode(phase2)
# phase1循环左移cycle_step位得到明文
plain = bytes([rotate_left(c, cycle_step) for c in phase1])
return plain
cipher_str = "y¦•_•6•>X¬y•!,!n¡mS•aÜñüë•••9¼•6•"
cipher = cipher_str.encode('latin-1')
key = b"Bore"
# 解密
flag = samsara_decrypt(cipher, key)
print("解密结果:", flag.decode())
欧几里得解题步骤:
题目逻辑梳理
m1 = bytes_to_long(flag)
m2 = bytes_to_long(os.urandom(2) * 35)
c1 = Paillier_encode(m1, g, n)
c2 = Paillier_encode(m2, g, n)
print(Paillier_decode(c1 * c2, p, q, g, n))
这个语句 Paillier_decode(c1 * c2) 正好利用了 Paillier 的加法同态性:
Paillier 有性质:
$$
E(m_1) \cdot E(m_2) \mod n^2 = E(m_1 + m_2 \mod n)
$$
所以:
Paillier_decode(c1 * c2) == m1 + m2 (mod n)
可以遍历所有可能的 x = os.urandom(2) 值,然后构造 m2_candidate = bytes_to_long(x * 35),接着:
m1_candidate = c - m2_candidate
尝试将 m1_candidate 转回 bytes,看是否是 flag 格式
解题脚本:
from Crypto.Util.number import long_to_bytes, bytes_to_long
c = 1426774899479339414711783875769670405758108494041927642533743607154735397076811133205075799614352194241060726689487117802867974494099614371033282640015883625484033889861
for i in range(0, 1 << 16): # 遍历所有 2 字节的可能
x = i.to_bytes(2, 'big')
m2 = bytes_to_long(x * 35)
m1 = c - m2
try:
flag = long_to_bytes(m1)
if b'palu' in flag:
print("Found!", flag)
break
except:
continue
应急响应1 -1解题步骤:
查找日志
/var/log/nginx/access.log
access.log没数据,找access.log.1
遍历数据,找到可疑ip 192.168.31.240,因为它试图访问 /shell.php
所以得到flag:palu{192.168.31.240}
应急响应2-1解题步骤:
直接打开堡垒机,在留存日志处找到flag
palu{2025_qiandao_flag}







It’s fascinating how easily accessible online gaming has become, but responsible play is key. Platforms like arion play app casino emphasize security, which is a good sign-important for both enjoyment & protection. Setting limits is smart!