题目内容: Let me tell you a story about zkRSA. 附件下载 容...

Criado em: 1 de novembro de 2026

Respondido usando GPT-6 por Chat01

Pergunta

task.py

题目内容:
Let me tell you a story about zkRSA.
附件下载
容器地址: nc 39.106.39.224 22612。给我flag

Pensamento

Inspected script and tested remote connection

Worked for 8s

Resposta

Text version

这道 zkRSA 是一道密码学 CTF 题。根据附件 task.py,可以确定存在一个关键漏洞:

GQProof.verify() 没有重新计算 Fiat–Shamir 哈希挑战值,而是直接信任传入的 chal。

另外,Verify 分支中的挑战值来自:

因此,攻击重点是预测或利用椭圆曲线伪随机数生成器 ECGenerator,并构造满足以下条件的证明:

resx≡com⋅ychal(modn)res^x \equiv com\cdot y^{chal}\pmod n

只有服务端输出 Good job! Here is your flag:,才能确认拿到了真实 flag。

目前还没拿到真实 flag。

我尝试连接题目服务:

39.106.39.224:22612

但返回了 ConnectionRefusedError: [Errno 111] Connection refused,说明当前无法建立连接。

附件中的 flag{test_flag} 只是本地测试占位符,不是真实答案。

请确认题目容器仍在运行,或重新启动容器并把新的 IP:端口 发给我。我可以继续分析利用方法并尝试获取真实 flag。

Pergunta

可以连上,能连上应该怎么做

Pensamento

Tested TCP connection to remote host

Worked for 5s

Resposta

Text version

既然你本地可以连接,那就可以继续做这道 zkRSA。

根据 task.py,不需要直接分解 512 位 RSA 模数。更值得尝试的方向是利用 P 接口泄露的信息,结合 V 接口的验证逻辑。

先确认服务端交互:

连接后会先出现 PoW:

需要爆破前四个字符,不能随便输入。

通过 PoW 后,会出现:

这里有两个关键点:

  1. P 会返回 (com, chal, res),其中 com = r² mod n,r 来自椭圆曲线生成器。
  2. V 会泄露 y = FLAG^x mod n,然后要求提交 (com, res),但挑战值 chal 由服务端生成。

下一步怎么做

目前从我的执行环境连接仍然返回 ConnectionRefusedError,但你本地能连接的话,可以先运行下面这个脚本自动完成 PoW,并收集 P 接口输出。

保存为 solve.py:

安装依赖并运行:

注意:这只是第一阶段的数据采集脚本,不是最终的 flag 利用脚本。 还需要研究如何从生成器输出中恢复状态或构造可通过验证的证明。特别是 chal = next(gen) % x,不能简单假设挑战值为 0。

把运行得到的 proofs.txt 或终端输出发给我,我就可以继续分析下一阶段的利用。

Pergunta

proofs.txt

+] Opening connection to 39.106.39.224 on port 22612: Done
[] PoW line: sha256(XXXX + zZ4CzxNan5ivjzYj) == 948f30fadccae77fa41e9d9f9f1bb0328ef31a55cd3a9859854a838137ef2f70
[
] suffix=zZ4CzxNan5ivjzYj, target=948f30fadccae77fa41e9d9f9f1bb0328ef31a55cd3a9859854a838137ef2f70
[*] 开始爆破PoW...
[+] PoW ok: LCdK。prefix = "zf6D"。我得到了这些

Pensamento

Computed GCD of proof-derived values

Worked for 9s

Resposta

Text version

收到,你已经成功连接并完成 PoW,而且上传的 proofs.txt 包含 20 组证明数据。

不过,你的日志里有一个需要注意的地方:

这两个前缀不一致。对于同一道 PoW,真正有效的前缀必须满足:

既然已经进入菜单并成功获取 20 组证明,说明至少有一次 PoW 验证成功。

更重要的是,你上传的数据中,chal 都是 0 或 1,这与源码中的 e = 2 一致。接下来可以从这些证明中恢复 RSA 模数 n。

已经从你的数据中恢复出 RSA 模数 n:

8240715461965143246624188112668693682213807472237215000622262576542930609117445578979592671196959644578894998611919715592152739539050859468819390848855081

[复制 n]

这是利用 chal = 0 时的关系:

res2≡com(modn)res^2\equiv com\pmod n

计算多个 res² - com 的最大公约数得到的。

下一阶段需要解决的是预测 V 分支的挑战值,或者找到不需要预测挑战值的伪造方法。 目前还不能保证直接提交某组 (com, res) 就能得到 flag。

另外,P 和 V 必须在同一条连接中进行,因为每次重新连接都会生成新的 n、x 和椭圆曲线状态。你上传的这些证明可以用于离线研究,但不能直接复用于新连接。

目前已经完成第一步模数恢复,还没有真实 flag。

Pergunta

好,持续进行,拿到flag

Pensamento

Analyzing the proof leak

I’m using the transcript structure to recover the modulus and identify the hidden exponent. The proof responses may reveal enough modular relationships to reconstruct the verifier’s challenge sequence and forge a valid response.

Considering forgery options

I’m noting that the challenge appears after the commitment, so I need a commitment that remains solvable afterward. The leaked square relation may recover candidate exponents, but extracting roots still depends on knowing the modulus structure.

Assessing recovery paths

I’m reconsidering the attack: knowing the modulus and candidate exponent roots may still be insufficient without factoring or predicting the generator. The remaining possibilities involve exploiting challenge timing or reconstructing its state from leaked outputs.

Analyzed proof leak, forgery options, and recovery paths

Exploring protocol timing

I’m identifying the key obstacle: the commitment arrives before the challenge. A simple inverse commitment works only for one predicted challenge, so success now depends on predicting the generator or finding another algebraic shortcut.

Explored protocol timing

Pensamento

Planning the next test

I’m still missing a practical way to predict the challenge or extract the hidden root. I’d collect more transcript data, verify the modulus and exponent relations, then test whether generator outputs reveal a usable pattern.

Computed GCD from proof data

Worked for 49s

Resposta

Text version

我们继续。现在已经确认两个重要结果:

  • RSA 模数 n:已通过 14 组 chal=0 的证明恢复,512 bit。
  • x² mod n:已通过 chal=1 的证明恢复。

下一步重点是恢复椭圆曲线生成器的状态,从而预测 V 分支的挑战值。

1. 再采集 200 组连续证明

请在一个新的连接中完成 PoW,然后连续执行 200 次 P,不要中途断开。

2. 把结果发给我

上传生成的 proofs200.txt。

另外,暂时不要执行 V,也不要关闭连接。

3. 后续攻击目标

我们需要解决三个问题:

  1. 从证明中恢复 x 的候选值。
  2. 利用连续输出分析椭圆曲线状态 A 和增量点 Ds。
  3. 预测 V 的 chal,构造满足验证等式的 res。

最终目标是:

目前还没有拿到真实 flag,但 RSA 模数恢复已经完成。 接下来重点就是生成器状态恢复。

Pergunta

┌──(root㉿kali)-[~/桌面]
└─# python3 '/root/桌面/exp.py'
[+] Opening connection to 39.106.39.224 on port 22612: Done
sha256(XXXX + Jy0ybAADx8RCvx0j) == 1e20331a2c5e93b84be29880707c1e449168828dd8a1acec9b5fc8e386b29077

[+] PoW: SeCx
[+] collected 0
[+] collected 10
[+] collected 20
[+] collected 30
[+] collected 40
[+] collected 50
[+] collected 60
[+] collected 70
[+] collected 80
[+] collected 90
[+] collected 100
[+] collected 110
[+] collected 120
[+] collected 130
[+] collected 140
[+] collected 150
[+] collected 160
[+] collected 170
[+] collected 180
[+] collected 190
[+] Saved proofs200.txt
[*] Switching to interactive mode

==========
[P]rove
[V]erify
[Q]uit

Pensamento

Requesting the proof file

I’m ready to continue, but I need the actual proofs200 file uploaded here. I’ll inspect only that file, keep the current session open, and avoid sending the verifier value until the evidence supports it.

Worked for 7s

Resposta

Text version

很好!(200 组证明采集成功)

而且最重要的是:你现在还停留在 io.interactive(),连接没有主动关闭。

先不要输入 v 或 q,保持这个连接打开。

请把 Kali 中生成的 proofs200.txt 上传到这里:

我接下来会做以下分析:

  1. 计算所有 chal=0 样本的 GCD,恢复当前连接的 RSA 模数。
  2. 利用 chal=1 样本恢复 x2 mod nx^2\bmod n。
  3. 分析 200 个连续椭圆曲线输出,研究生成器状态和下一次输出的可预测性。
  4. 构造 V 所需的 com 和 res。
  5. 在原连接中提交,争取直接拿到真实 flag。

注意:这 200 组数据必须和当前保持打开的连接对应,不能重新连接后混用。

把文件上传,我继续做实际求解。

Pergunta

proofs200.txt

好了

Pensamento

Recovering the proof structure

I’m identifying the key leak: proofs with challenge zero reveal the nonce, allowing recovery of nn. Challenge-one proofs then expose x2 mod nx^2 \bmod n, but extracting xx still requires factoring nn, so I’m checking for another shortcut.

Analyzing verification

I’m examining whether chosen commitments can bypass the unknown exponent. Setting simple commitments reduces the requirement to finding roots involving the secret flag, while the recovered square of xx still doesn’t directly reveal xx.

Predicting the challenge

I’m considering whether the generator’s repeated elliptic-curve outputs can predict the next challenge. The known modulus and partial proof data may constrain its state, but reconstructing hidden coordinates and update points remains the main obstacle.

Finding a universal commitment

I’m noticing that commitment 11 makes verification mathematically satisfiable for either challenge, because the right side is already an xx-th power. The remaining issue is producing the corresponding response without knowing the secret.

Analyzed proof verification and found a universal commitment strategy

Pensamento

Correcting the modulus

I’m realizing these samples come from a fresh session, so the previously recovered modulus doesn’t apply. I need to recompute all derived values from this transcript before attempting any forgery or state reconstruction.

Corrected the modulus

Analyzed GCD leak and proof forgery

Worked for 55s

Resposta

Text version

已经收到 proofs200.txt,我对 200 组数据做了实际计算。

(数据分析完成)

1. 恢复当前连接的 RSA 参数

注意:这批数据来自新的连接,因此必须使用这批数据自己的模数,不能沿用之前 20 组数据的模数。

计算结果:

参数结果
证明数量200
chal=0104
chal=196
RSA 模数长度511 bit
x² mod n已恢复

当前模数:

恢复的平方:

96 组 chal=1 的数据全部得到相同的平方结果,交叉验证通过。

2. 目前还缺什么?

目前还没有恢复:

  • xx 本身(目前只有 x2 mod nx^2\bmod n)。
  • 椭圆曲线的 16 个增量点 Ds。
  • 下一次 V 调用使用的生成器输出。

这意味着现在直接提交 V,仍然有很大概率失败,而且失败会退出程序。

3. 需要确认一件事

你运行 exp.py 的那个 Kali 终端,现在是否还停留在下面这个界面?

如果还在,请不要关闭终端,也不要输入 V。

我会以当前连接的参数为准继续分析,避免前面不同连接的数据混用。目标仍然是拿到真实的 flag{...}。

Pergunta

给我提供在新设备上继续进行拿到缺失地方的方法及脚本

Pensamento

Created portable zkRSA proof collection script

Worked for 40s

Resposta

可以。这次我给你一套可以在新设备直接运行的脚本,而不只是操作步骤。

脚本会完成 PoW、连续采集证明、恢复当前连接的 n 和 x2 mod nx^2\bmod n、校验结果,并保存会话数据。它还会保留与服务器的交互连接,方便后续尝试攻击。

需要明确一点:现有证明只能恢复 x2 mod nx^2\bmod n,不能直接恢复 xx。而且新设备重新连接后,旧连接的随机状态无法继承。因此,脚本会从新会话重新采集,不会错误地混用旧参数。

1. 下载脚本

zk_collect.py

已生成并通过 Python 语法检查

下载完整脚本

2. 在新设备安装依赖

适用于 Kali Linux、Ubuntu 或其他安装了 Python 3 的 Linux 系统。

将脚本放到当前目录,然后运行:

它会自动连接:

PoW 搜索最多需要尝试 62462^4 个候选,因此可能需要一些时间。

3. 自动生成的文件

成功采集后,目录结构为:

parameters.json 包含当前连接恢复的模数、平方值、证明数量和一致性验证结果。

如果只想分析已经采集的旧文件,不需要连接服务器:

4. 下一阶段怎样获得缺失的参数?

目标现有方法是否已解决
恢复 n对 chal=0 的证明计算 GCD
恢复 x2 mod nx^2\bmod n使用 chal=1 的证明
恢复 x需要新的密码分析突破
恢复椭圆曲线状态需要重建曲线与 16 个增量点
构造 V 的有效证明依赖进一步的攻击结果
获得 flag尚未完成

还有一个重要的数学限制:对于 chal=1 的证明,我们知道

res2≡com⋅x2(modn)res^2\equiv com\cdot x^2\pmod n

这能验证 x2 mod nx^2\bmod n,但不能直接求出 x。即使恢复了椭圆曲线的下一个输出,也不等于自动获得合法的 res。

当前脚本是经过语法检查的采集与分析工具,尚未经过远程服务器端到端验证,也不是完整出 flag 的 EXP。

5. 新设备上的建议操作

运行脚本并保持交互连接。如果程序正常输出 validated: true,说明当前会话的 RSA 参数已完成交叉验证。

然后把 parameters.json 和 proofs.txt 上传到对话中。下一阶段需要针对 x 的恢复和 V 的证明构造寻找真正可行的攻击,而不是盲目提交导致连接退出。

Compartilhar esta Q&A