It gives out rsa public key, from which we can get N and e
Gives out rsa encryption of flag + input
Seems like a nice application of Franklin reiter Related message attack, which is
If we have two linearly related messages, and their corresponding ciphertexts and a small exponent e, we can figure out the messages by factoring the polynomial
Plan of actions go as follows:-
Get public key, parse out N and e
Get the encryption of flag + ""
Get the encryption of flag + "a" a small message
So we have two messages, int(flag) and 256*int(flag)+ord('a')
frompwnimportremotefromCrypto.PublicKeyimportRSAfrombase64importb64decodeimportreHOST,PORT="crypto.zh3r0.ml",9841REM=remote(HOST,PORT)data=REM.recvuntil(b'0.Exit')print(data.decode())REM.sendline(b'1')pub_key=REM.recvuntil(b'-----END PUBLIC KEY-----\n').strip()rsa=RSA.importKey(b64decode(pub_key.split(b'\n-----END PUBLIC KEY-----\n')[0].split(b'-----BEGIN PUBLIC KEY-----')[1]))print(pub_key.decode())N=rsa.nE=rsa.eREM.sendline(b'2')REM.sendline()REM.sendline(b'2')REM.sendline(b'a')REM.sendline(b'0')data=REM.recvuntil(b'BYE')print(data.decode())C1,C2=map(int,re.findall(b'(\d+)\n',data))
This part of the calculation I did it in sage
Plain text
1
2
3
4
5
6
7
8
9
10
11
diff = ord('a')
R.<X> = Zmod(n)[]
f1 = X^3 - C1
f2 = (256*X + r)^3 - C2
def my_gcd(a, b):
return a.monic() if b == 0 else my_gcd(b, a % b)
mint=-my_gcd(f1, f2).coefficients()[0]
print(bytes.fromhex(hex(mint)[2:]).decode())
# mint = 84490476860330212673060501801652621134953572462322324101674679636525065183282486185148354532461487912067725608302199264119177290786545985493246692410205660189434658580866030237305212940461964070200849268673142227118980326807902129431038850502565588905103675210898161818686994591193583661769377667810413989357162402550803291023005993338743213389843385122094
# "RSA is secure and all but the only thing I want to say is zh3r0{Hey_y0u_Sh0u1dn't_S3nd_r3l4ted_m3ssag3s_0r_h4v3_shot_p4ddings_wh3n_e_1s_sm411!!!!!}.