BCA CTF 2024

Encryptor Shop [50 pts]

After realizing how insecure the systems of many companies are (they’re always getting hacked), I decided to start offering Encryption as a Service (EaaS). With such a strong guarantee of security, I’ll even give you the source code AND my encrypted super secret flag.

nc challs.bcactf.com 31704

server.py


Here’s the source code:

from Crypto.Util.number import *

p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1024)
n = p * q
phi = (p - 1) * (q - 1)
e = 65537
d = pow(e, -1, phi)

print("Welcome to the enc-shop!")
print("What can I encrypt for you today?")


for _ in range(3):
    message = input("Enter text to encrypt: ")
    m = bytes_to_long(message.encode())
    c = pow(m, e, n)
    print(f"Here is your encrypted message: {c}")
    print(f"c = {c}")
    print("Here is the public key for your reference:")
    print(f"n = {n}")
    print(f"e = {e}")
    
print("Thank you for encrypting with us!")
print("In order to guarantee the security of your data, we will now let you view the encrypted flag.")
x=input("Would you like to view it? (yes or no) ")

if x.lower() == "yes":
    with open("flag.txt", "r") as f:
        flag = f.read().strip()
    m = bytes_to_long(flag.encode())
    n = p*r
    c = pow(m, e, n)
    print(f"Here is the encrypted flag: {c}")
    print("Here is the public key for your reference:")
    print(f"n = {n}")

Basically, the server encrypts a user-provided message and the flag with 2 different n values, pq and pr. Since both of these n values are a multiple of p, we can just take the GCD of these two n-values to get p, and then from there it’s just standard RSA decryption.

from Crypto.Util.number import *

n1 = 13970653822676695327002402243981944247885108995678743776010435738907602751027817738172717043999833150844440514292977770367198662505442504241332985082164832583286603474646662190125707343794515753475283386531954309654914941644614292350958865752196399022150954078361225020259102293531041541384554456795544087869421487456214694965285646409646343742249973970445071619383620872935754605340171243850362839321510518630163745804543885935371743993072288993123244093944646303201262240788076907198808730880671795324971762688638896923042230371036646595252867245372177304546879936912808357923311786285717833577324192718336438861519
n2 = 19171949171434405109958482067194016927581311204521413348936810461297547973004061462421845287053538198580034695701223335186715735906882351856231720229969322557567855883283194668136227331495445059409170929004659235745445100174429812980108354430877239494455973190769093681021849056062620181842397131030722192967708031392607242999530209157148452220303480714342845204339925035517690957330927941334981912813001778696536926303999131183910907840246389638661325069315527535854751339078043404209358946102393572791820966663581095121331491623600262429503327580605346779827317444424901232467229568667269141302538477195983466162961
p = GCD(n1, n2)
q = n2//p
phi = (p - 1)*(q - 1)
d = inverse(65537, phi)
ct = 11996706664409063853913346298961923812947203506412200056980105310849189613620971631028714980629747733118910390171530339020274007208529948012393274941291895612463323374222391210969128327204481580397485025036082905312008060965786587802226641921964440913927156184015808098800712903170663144087395493109201189975728925910508013638236865217298519790748761346137207669970744572880544490604157943567035430044260113253879598665938822569538113649620027382994452426105323240365256797007901918106233243236909459210829940963981488713485638373513726583895017505252865090315697217767887986285840459779407064660323956282048616596473
print(long_to_bytes(pow(ct, d, n2)))
bcactf{w0w_@lg3br@_d3in48uth934r}