ctf密码,尝试解出flag
创建于:2025年10月11日
使用 GPT-5 Thinking 回答 Chat01
创建于:2025年10月11日
使用 GPT-5 Thinking 回答 Chat01
python# Let's open the uploaded files to see sizes and content lengths path = "/mnt/data/output.txt" with open(path, 'r') as f: text = f.read() text[:300] 'n = 7494062703769887703668081866565274579333132167014632821313548612356114287792191446305040778987677683423969025588609780586722302041792065732461222120206217\nx = 17658940797450972866082725708833718328064551094153369275643785130728271552854366965912050347453351071891894940628064693694462929689934292'
pythonlen(text) 37570
python# Extract n, x, enc import re, ast m = re.search(r"n = (\d+)", text) n_str = m.group(1) x_str = re.search(r"x = (\d+)", text).group(1) enc_list_str = re.search(r"enc = $$(.*)$$", text, re.S).group(1) # Split by commas safely enc_nums = [int(s.strip()) for s in enc_list_str.split(",")] len(enc_nums), enc_nums[0], enc_nums[-1] (239, 1719131405161789300725716547614879725769113740628924228040533454917595622840903436228598969968521441543327057141589401318966713711269892553169244263117465, 6834470718220476619599192939877802960626266906218601397992141268348842750307258845978436373245888045814447365868690654204442632005537885428710943936919252)
pythonimport sympy as sp, time n = int(n_str) start=time.time() factors = sp.factorint(n, limit=2**20) # limit bounds tries for small primes? time.time()-start, factors (28.139240980148315, {7494062703769887703668081866565274579333132167014632821313548612356114287792191446305040778987677683423969025588609780586722302041792065732461222120206217: 1})
pythonimport importlib, sys, pkgutil, math, time [x.name for x in pkgutil.iter_modules()][:20] ['__future__', '__hello__', '__phello__', '_aix_support', '_bootsubprocess', '_collections_abc', '_compat_pickle', '_compression', '_markupbase', '_osx_support', '_py_abc', '_pydecimal', '_pyio', '_sitebuiltins', '_strptime', '_sysconfigdata__linux_x86_64-linux-gnu', '_threading_local', '_weakrefset', 'abc', 'aifc']
pythonimport math n = int(n_str); x = int(x_str) enc = enc_nums vals=[] nontrivial=[] for i in range(len(enc)-1): a=enc[i]; b=enc[i+1] for comb in [(b-a)%n, (b - a*x)%n, (b*x - a)%n]: g=math.gcd(comb, n) if g!=1 and g!=n: nontrivial.append((i, g)) len(nontrivial), nontrivial[:5] (0, [])
pythonimport math from math import gcd # compute inverse of x mod n def invmod(a, m): return pow(a, -1, m) invx = invmod(x, n) nontrivial=[] for i in range(len(enc)-1): a=enc[i]; b=enc[i+1] combos = [ (b - a)%n, (b - a*x)%n, (b*x - a)%n, (b*invx - a)%n, (b - a*invx)%n, (a - b)%n, (a - b*x)%n, (a*x - b)%n, ] for comb in combos: g=gcd(comb, n) if g!=1 and g!=n: nontrivial.append((i, comb, g)) len(nontrivial) 0
下面是我“解题 + 还原 flag”的完整思路与脚本(已尽力直接破解;结论是需要分解 n,见下文)。
给定的脚本实现的就是 Goldwasser–Micali (GM) 位加密:
enc
。)(output.txt)GM 的解密方法非常简单——只要知道 p 或 q:
因为 且 。因此只要分解出 (或得到其中一个素数),逐位取勒让德符号就能还原出明文位,再按 LSB→MSB 顺序重组为字节即可。(Random.py)
你给的
enc
长度是 239 位 ≈ 30 字节,和常见的flag{...}
很贴合。(output.txt)
结论:这份构造没有明显实现漏洞;想要解出 flag 的“正道”就是分解 。
把下面脚本保存为 solve.py
,把你给的 output.txt
放同一目录,如果你已经用工具分解出了 ,填进去即可立刻还原 flag。
python# solve.py — 还原 GM 密文位并输出 flag import re from math import prod # ---- 1) 读入 n, x, enc ---- with open("output.txt","r") as f: t = f.read() n = int(re.search(r"n\s*=\s*(\d+)", t).group(1)) x = int(re.search(r"x\s*=\s*(\d+)", t).group(1)) enc = list(map(int, re.search(r"enc\s*=\s*$$(.*)$$", t, re.S).group(1).split(","))) # ---- 2) 若你已经分解出 p,q,就填在这里 ---- # TODO: 把下面两行换成你的素数(知道 p 或 q 之一也行) p = None q = None def legendre(a, p): # 勒让德符号 (a|p) with Euler's criterion return pow(a % p, (p-1)//2, p) if a%p else 0 if p is None or q is None: raise SystemExit("请先分解 n= p*q,填入 p,q 再运行。") # ---- 3) 逐位解密:b=0 -> (c|p)=+1; b=1 -> (c|p)=-1 ---- bits = [] for c in enc: s = legendre(c, p) if s == 1: bits.append(0) elif s == p-1: # -1 mod p bits.append(1) else: raise RuntimeError("遇到异常勒让德符号 (可能 p 填错)") # enc 是 LSB->MSB,重组成整数 m = 0 for i, b in enumerate(bits): if b: m |= (1<<i) # 输出字节串 out = m.to_bytes((len(bits)+7)//8, "little").rstrip(b"\x00") print(out) try: print("decoded (utf-8):", out.decode()) except: pass
factor(<n>)
,它会自动调用 ECM + SIQS。flag
。若你愿意把 或 (或已分解结果)贴给我,我会立刻用上面的流程把 flag 还原出来并给出最终字符串。
(数据与代码出处:你的 Random.py
中的加密实现与勒让德选择条件,及 output.txt
中给出的 n, x, enc
。(Random.py) (output.txt))