CTF BUUOJ [ACTF新生赛2020]crypto-rsa0 Writeup
一、题目描述
题目来源:ACTF新生赛2020
题目分类:Crypto
题目给了一个压缩包和一个提示文件 hint.txt。
hint.txt 内容:
怎么办呢,出题人也太坏了,竟然把压缩包给伪加密了!
output 文件内容:
9018588066434206377240277162476739271386240173088676526295315163990968347022922841299128274551482926490908399237153883494964743436193853978459947060210411
7547005673877738257835729760037765213340036696350766324229143613179932145122130685778504062410137043635958208805698698169847293520149572605026492751740223
50996206925961019415256003394743594106061473865032792073035954925875056079762626648452348856255575840166640519334862690063949316515750256545937498213476286637455803452890781264446030732369871044870359838568618176586206041055000297981733272816089806014400846392307742065559331874972274844992047849472203390350
二、解题思路
1. 伪加密压缩包处理
题目提示“压缩包给伪加密了”,这是一个非常经典的 Misc/Crypto 混合考点。
所谓的 ZIP 伪加密,是指压缩包实际上并没有加密,但是文件头中的加密标志位被修改成了“加密”状态(通常是将全局方式位标记修改为 09 00),导致解压软件误以为需要密码。
解决方法:
使用十六进制编辑器(如 010 Editor、WinHex)打开压缩包,搜索十六进制数据 50 4B 03 04(这是 ZIP 文件头的标志),在其后的数据中找到 09 00,将其修改为 00 00。
修改保存后,再次打开压缩包即可无密码解压,得到 rsa.py 源码文件和 output 文件。
2. 代码分析
解压后得到的 rsa.py 核心逻辑通常如下:
from Cryptodome.Util.number import *
import random
FLAG = #hidden, please solve it
flag = int.from_bytes(FLAG, byteorder='big')
p = getPrime(512)
q = getPrime(512)
print(p)
print(q)
n = p * q
e = 65537
enc = pow(flag, e, n)
print(enc)
结合 output 文件的内容,我们可以确定:
- 第一行 是素数 p
- 第二行 是素数 q
- 第三行 是密文 c
- 公钥指数 e = 65537(RSA 标准默认值)
3. RSA 解密原理
这是一道标准的 RSA 解密题。已知 p,q,c,ep, q, c, ep,q,c,e,求明文 mmm。
计算步骤如下:
三、解题脚本
根据上述原理,编写 Python 脚本如下:
from Crypto.Util.number import long_to_bytes
import gmpy2
# 从 output 文件中提取的数据
p = 9018588066434206377240277162476739271386240173088676526295315163990968347022922841299128274551482926490908399237153883494964743436193853978459947060210411
q = 7547005673877738257835729760037765213340036696350766324229143613179932145122130685778504062410137043635958208805698698169847293520149572605026492751740223
c = 50996206925961019415256003394743594106061473865032792073035954925875056079762626648452348856255575840166640519334862690063949316515750256545937498213476286637455803452890781264446030732369871044870359838568618176586206041055000297981733272816089806014400846392307742065559331874972274844992047849472203390350
# 公钥指数
e = 65537
# RSA 计算过程
n = p * q
phi = (p – 1) * (q – 1)
# 求模逆计算私钥 d
d = gmpy2.invert(e, phi)
# 解密得到明文大整数
m = pow(c, int(d), n)
# 转换为字节串并打印
flag = long_to_bytes(m)
print(flag.decode())
运行结果:
actf{n0w_y0u_see_RSA}
四、总结
这道题虽然归类为 Crypto,但其实考察了两个知识点:
最终 Flag:
flag{n0w_y0u_see_RSA}
网硕互联帮助中心



评论前必须登录!
注册