又是一题pwn结合crypto,记录一下。听说是鹤城杯2021 babyrsa类似题目。
源码challenge.sage:
for _ in range(3):
p = random_prime(2^1024)
q = random_prime(2^1024)
n = p*q
p1=p>>724
ct=n * inverse_mod(q % (2 ** 265), 2^265) % 2^265
print('p1=',p1)
print('ct=',ct)
print("n=",n)
e = 65537
alarm(80)
m = randint(2,n-1)
c=pow(m,e,n)
print('c=', c)
print('---------------------------------------------')
m1 = int(input("m="))
print('---------------------------------------------')
print()
if m1!=m:
print("Nope")
exit()
print(open("flag.txt","r").read())
分析一下逻辑,一共三轮RSA加密,p,q
是1024bit随机素数, e=65537
,给出 p1
是 p
的高300bit值,给出 n=p*q
,给出 c t = n × q − 1 m o d 2 265 ct=n \times q^{-1} \mod 2^{265} ct=n×q−1mod2265
另外还给出明文 m
经过RSA加密后的密文 c
需要解出明文后进入下一轮。
推导一下;
实际上 c t = n × q − 1 m o d 2 265 = p m o d 2 265 ct=n \times q^{-1} \mod 2^{265}=p \mod 2^{265} ct=n×q−1mod2265=pmod2265也就是p的低265bit;已知p的高位和低位套coppersmith攻击脚本求解。
最终exp:
#sage
from pwn import *
context.log_level = "DEBUG"
conn = remote("223.112.5.156", 54864)
def solveit(p1,ct,n,c):
mod=pow(2,265)
pbar=(p1<<724)+ct
PR.<x> = PolynomialRing(Zmod(n))
for i in range(32):
f=pbar+x*mod*32
f=f.monic()
pp=f.small_roots(X=2^454,beta=0.4)
if(pp):
break
pbar+=mod
assert pp
p=pbar+pp[0]*32*mod
q=n//Integer(p)
e=65537
phi=(p-1)*(q-1)
d = inverse_mod(e, phi)
m = pow(c, d, n)
return m
for _ in range(3):
conn.recvuntil(b'p1=')
params = conn.recvuntil(b'm=')
params=params.split(b'\n')
p1=int(params[0][1:])
ct=int(params[1][4:])
n=int(params[2][3:])
c=int(params[3][3:])
#print(p1,ct,n,c)
m=solveit(p1,ct,n,c)
print(m)
conn.sendline(str(m))
conn.recvall()