Writeup by brf-f for Rien à signaler

intro crypto

April 22, 2024

Understanding the challenge

This challenge gives us 2 files: output.txt (JSON text data) and a Python script rien-a-signaler.py.

We need to decipher the flag that was encrypted with RSA using the python script provided to us

The output.txt file contains 3 variables: e, n, and c

Solution

I opened the Python script to get an idea of how the data was encrypted

I create a copy of the script so I can make my own modifications / solution cp rien-a-signaler.py my_sol.py

After running pip to install a few missing libraries I print the results of sk, pk = keygen() which gives integers in the format:

(d, n), (e, n)

e is constant, n and d change every run

After a quick confusion due to sk, pk switching when returned -> sk becomes pk + vice versa

According to the script, using the values we got we can see that

(65537, n) (d, n)

--------
p = getPrime(1024)
q = getPrime(1024)

e = 65537

n = p*q

d = (1/65537) % ((p - 1) * (q - 1))

getPrime(n) generates a prime number of n bits

We look at output.txt again, which gives us 3 values: e , n, and c. Looking at the script, we know that

d = [e]
n = [n]

Therefore we know

p = getPrime(1024)
q = getPrime(1024)

e = 65537

n = 15796942747309728499758004731551695370913663306666035509299434642801916886496898004446545897149657535285268305926374338100837909963511256277964036962044387829939281166102731090331978991280163210213940391251452338553405036351243486418991475381065523778778374159216111211039724992140348798301914302441933569705494577465736752087544176074475722982600742085989140379907623574747713824460161103249270448563714176784913386788071348191510218812659925461534747629228752452045853041012162619056264262054391967199115369336548943331022933845667724296738334370747384492830658154258526863726939357154899976616849634493499797766299

d = 14939086586092777407540803168471412724086958884607893995687327163153290580760558837291728666456222816453459253012875608081140912518401828609726644228963594136502689596910372270878975142615041204855876795840250744447608791110019817832312337476046798491861483950133453478764973611286365531244274907864964200118887980416350639882907479248120503190137345205402154450552803826178574159801186219948543406588724442253188994068292704744044422267282898105644719291000793491804938648328829611223993162601906075018324472156338267348355427156047595434154590931416765750047893661286247274247632521858558403416012123883148428323057

We can now decrypt the flag using the private keys sk:

m = pow(c, sk[0], sk[1])

Writing a quick python script to give the flag:

e = 65537
c = 8974868290281688737233990325600894780715849339628541493919631966007477856153771121147897587192029426714635875587384109624607194486211852465796766441066196469272988076202321557112300294463883797708163984188107199926745938577562219282934551167072277621808474131345695591468145868455419473050498493285402336637848596791275101533878984692539165395918338275186762268105380646876795842765910627488934075701761752437069042340873474933889573307306539126206460702731582652544213958040586038088129224761895431978602343177304095553828090049657631935349611981192723124744317395844933142968117051307548448128268941861109853064071
n = 15796942747309728499758004731551695370913663306666035509299434642801916886496898004446545897149657535285268305926374338100837909963511256277964036962044387829939281166102731090331978991280163210213940391251452338553405036351243486418991475381065523778778374159216111211039724992140348798301914302441933569705494577465736752087544176074475722982600742085989140379907623574747713824460161103249270448563714176784913386788071348191510218812659925461534747629228752452045853041012162619056264262054391967199115369336548943331022933845667724296738334370747384492830658154258526863726939357154899976616849634493499797766299
d = 14939086586092777407540803168471412724086958884607893995687327163153290580760558837291728666456222816453459253012875608081140912518401828609726644228963594136502689596910372270878975142615041204855876795840250744447608791110019817832312337476046798491861483950133453478764973611286365531244274907864964200118887980416350639882907479248120503190137345205402154450552803826178574159801186219948543406588724442253188994068292704744044422267282898105644719291000793491804938648328829611223993162601906075018324472156338267348355427156047595434154590931416765750047893661286247274247632521858558403416012123883148428323057

# get m
m = pow(c, e, n)

# Convert flag binary int to string
from Crypto.Util.number import long_to_bytes

original_bytes = long_to_bytes(m)
flag = original_bytes.decode()

print(flag)

Running this script gives the flag: FCSC{7264bd2db7fae77e0c4e2445e45ed89fbe98f7c1bc8e7796111e32654f1ad1f0}