1.[NPUCTF2020]共 模 攻 击
给出两个代码。先解hint.py(毕竟解出来的东西是提示)。可以看出这里面含有共模攻击,解出c之后,我们就掌握了密文c,模数p,指数(256),再利用sympy.nthroot_mod(c,256,p)解出明文m。
import sympy,gmpy2
from Crypto.Util.number import *
p = 107316975771284342108362954945096489708900302633734520943905283655283318535709
n = 6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579
e1 = 2303413961
c1 = 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723
e2 = 2622163991
c2 = 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249
gcd = gmpy2.gcdext(e1,e2)
s,t = int(gcd[1]),int(gcd[2])
c = (pow(c1,s,n)*pow(c2,t,n))%n
m = sympy.nthroot_mod(c,256,p)
print(long_to_bytes(m))
解出 m.bit_length() < 400。 再看task.py。不知道e1,e2,连共模攻击都用不了。但是e1, e2 = p, q,c1, c2 = pow(m, e1, n), pow(m, e2, n)。
c1 = me1 mod n =mp mod n = mp mod p c2 = me2 mod n =mq mod n = mq mod q 由费马定理可得 mp = m mod p mq = m mod q 所以c1 = m mod p , c2 = m mod q 。 好像可以用中国剩余定理,但是p,q未知。 根据c1 = m mod p , c2 = m mod q 推出 c1 - m = t1 * p c2 - m = t2 * q 两个等式相乘,得到m2 - (c1 + c2 ) * m + c1 * c2 = t1 * t2 * p * q = k * n 即m2 - (c1 + c2 ) * m + c1 * c2 = 0 mod n
大佬说用Sage来解这个方程。 原来这个Sage是一种语言,我还以为是py里的库:) 在线运行sage脚本:sagemath 解出来的就是m,再进行long_to_bytes(m)即可得出明文 b’verrrrrrry_345yyyyyyy_rsaaaaaaa_righttttttt?’
2.[b01lers2020]safety_in_number
pubkey.pem文件巨大,读取时间真的长。期间为了看一下具体的n,直接卡死了:)(手贱)
with open("pubkey.pem", "r") as f:
ciph = RSA.importKey(f.read())
n = ciph.n
e = ciph.e
print(n)
print(e)
解出的n超大,e=65537。根据c = me mod n可以知道,当n远大于me时,只需对c开e次根即可得到m。
import gmpy2
from Crypto.Util.number import *
e = 65537
with open("flag.enc", "rb") as f:
flag = f.read()
c = int.from_bytes(flag, byteorder = 'little')
m = int(gmpy2.iroot(c,e)[0])
print(long_to_bytes(m))
print(long_to_bytes(m)[::-1])
因为读出来的flag时字节串,需要转成数字再开根号,而在子程序enc中,是进行了小端存储(即低位在前,高位在后,汇编中有介绍) int.from_bytes和int.to_bytes函数介绍
b'}f00Rp_3RutUf!{ftcp'
b'pctf{!fUtuR3_pR00f}'
正如结果所显示的,低位在前,高位在后,正常的解出来是逆过来的,所以要从最后面开始打印。
|