ctf-writeup/2023/Srdnlen CTF 2023/RSA
daffainfo e6c48e50f1 feat: grouped the challs 2024-01-09 16:59:32 +07:00
..
README.md feat: grouped the challs 2024-01-09 16:59:32 +07:00

README.md

RSA

Was this the RSA that Rivest, Shamir and Adleman intended?

About the Challenge

We were given 2 files, chall.py and output.txt.

from Crypto.Util.number import getStrongPrime, bytes_to_long

flag = b"srdnlen{?????????????????????????????????????????????}"

nbits = 512
e = 0x10001
r, s, a = [getStrongPrime(nbits, e=e) for _ in range(3)]

rsa = r * s * a
r_s_a = r + s + a
rs_ra_sa = r * s + r * a + s * a

flag_enc = pow(bytes_to_long(flag), e, rsa)

print(f"{flag_enc = }")
print(f"{rsa = }")
print(f"{r_s_a = }")
print(f"{rs_ra_sa = }")

And here is the content of output.txt

flag_enc = 305937389913644124353521541203896228228100287771861952787632778203429862580034717045066213644670515924479613687491939585830621428606122810529254111370561855825281351383357838797183961382377911872273999422767788459585486508291858004728424594963981121345786835801425225173392185659177549728175043848142863492498517163562979790708452839236670186147527086692854011149422111289175223857001786765717200535670927989091747867031255628205430286900180120411568566496158971
rsa = 1119331088426445652049073632117678292260141007738261628482440105143508952011573006283470657320593796414881427458009128790416915606096677817107740886320364054596186677319992672873286602387978243613748908293131886639783664921319212446265594496808690114453810308016153697587841315391448735148763753254685350707203658119669859336306387287389740797917206580085557660754531433662772769500638270585975839989101964379252278187400491260154753705688029268027175812419696619
r_s_a = 31196151692240769482413434933384534303517111654835402273777788758876797999084042595072311282209063135918012172776936704542482749883925277357875720477370629
rs_ra_sa = 323898748110304540012077200920876791739827672187962956210824080913877019158151191999812688624496191774476169968522325251822258958226152196451875769781319538093983441577632922600197853360682904318047081576168252854038158315592880232574502453976052364135250887912532391068132536589210795343836920404808340626031

In order to decrypt the flag, we need to find the value of r, s, and a

How to Solve?

I made a Python script that uses z3 to find the value of r, s, and a. Here is the full script

from z3 import *
from Crypto.Util.number import long_to_bytes

flag_enc = 305937389913644124353521541203896228228100287771861952787632778203429862580034717045066213644670515924479613687491939585830621428606122810529254111370561855825281351383357838797183961382377911872273999422767788459585486508291858004728424594963981121345786835801425225173392185659177549728175043848142863492498517163562979790708452839236670186147527086692854011149422111289175223857001786765717200535670927989091747867031255628205430286900180120411568566496158971
rsa = 1119331088426445652049073632117678292260141007738261628482440105143508952011573006283470657320593796414881427458009128790416915606096677817107740886320364054596186677319992672873286602387978243613748908293131886639783664921319212446265594496808690114453810308016153697587841315391448735148763753254685350707203658119669859336306387287389740797917206580085557660754531433662772769500638270585975839989101964379252278187400491260154753705688029268027175812419696619
r_s_a = 31196151692240769482413434933384534303517111654835402273777788758876797999084042595072311282209063135918012172776936704542482749883925277357875720477370629
rs_ra_sa = 323898748110304540012077200920876791739827672187962956210824080913877019158151191999812688624496191774476169968522325251822258958226152196451875769781319538093983441577632922600197853360682904318047081576168252854038158315592880232574502453976052364135250887912532391068132536589210795343836920404808340626031

e = 0x10001

r = Int('r')
s = Int('s')
a = Int('a')

eq1 = r * s * a == rsa
eq2 = r + s + a == r_s_a
eq3 = r * s + r * a + s * a == rs_ra_sa

solver = Solver()

solver.add(eq1)
solver.add(eq2)
solver.add(eq3)

if solver.check() == sat:
    # Get the solution
    model = solver.model()

    # Get the values of r, s, and a
    r_value = model[r].as_long()
    s_value = model[s].as_long()
    a_value = model[a].as_long()

    phi_rsa = (r_value - 1) * (s_value - 1) * (a_value - 1)

    d = pow(e, -1, phi_rsa)
    flag_dec = pow(flag_enc, d, r_value * s_value * a_value)
    flag_bytes = long_to_bytes(flag_dec)
    print(flag_bytes)

else:
    print("Nah")

Run the program and you will obtain the flag

srdnlen{W3lc0m3_t0_srdnlen_ctf_2023_crypt0_ch4ll3ng3s}