Write up for UTCTF 2024 - Crypto/bits and pieces

Challenge

I really really like RSA, so implemented it myself <3.

n1: 16895844090302140592659203092326754397916615877156418083775983326567262857434286784352755691231372524046947817027609871339779052340298851455825343914565349651333283551138205456284824077873043013595313773956794816682958706482754685120090750397747015038669047713101397337825418638859770626618854997324831793483659910322937454178396049671348919161991562332828398316094938835561259917841140366936226953293604869404280861112141284704018480497443189808649594222983536682286615023646284397886256209485789545675225329069539408667982428192470430204799653602931007107335558965120815430420898506688511671241705574335613090682013
e1: 65537
c1: 7818321254750334008379589501292325137682074322887683915464861106561934924365660251934320703022566522347141167914364318838415147127470950035180892461318743733126352087505518644388733527228841614726465965063829798897019439281915857574681062185664885100301873341937972872093168047018772766147350521571412432577721606426701002748739547026207569446359265024200993747841661884692928926039185964274224841237045619928248330951699007619244530879692563852129885323775823816451787955743942968401187507702618237082254283484203161006940664144806744142758756632646039371103714891470816121641325719797534020540250766889785919814382

n2: 22160567763948492895090996477047180485455524932702696697570991168736807463988465318899280678030104758714228331712868417831523511943197686617200545714707332594532611440360591874484774459472586464202240208125663048882939144024375040954148333792401257005790372881106262295967972148685076689432551379850079201234407868804450612865472429316169948404048708078383285810578598637431494164050174843806035033795105585543061957794162099125273596995686952118842090801867908842775373362066408634559153339824637727686109642585264413233583449179272399592842009933883647300090091041520319428330663770540635256486617825262149407200317
e2: 65537
c2: 19690520754051173647211685164072637555800784045910293368304706863370317909953687036313142136905145035923461684882237012444470624603324950525342723531350867347220681870482876998144413576696234307889695564386378507641438147676387327512816972488162619290220067572175960616418052216207456516160477378246666363877325851823689429475469383672825775159901117234555363911938490115559955086071530659273866145507400856136591391884526718884267990093630051614232280554396776513566245029154917966361698708629039129727327128483243363394841238956869151344974086425362274696045998136718784402364220587942046822063205137520791363319144

n3: 30411521910612406343993844830038303042143033746292579505901870953143975096282414718336718528037226099433670922614061664943892535514165683437199134278311973454116349060301041910849566746140890727885805721657086881479617492719586633881232556353366139554061188176830768575643015098049227964483233358203790768451798571704097416317067159175992894745746804122229684121275771877235870287805477152050742436672871552080666302532175003523693101768152753770024596485981429603734379784791055870925138803002395176578318147445903935688821423158926063921552282638439035914577171715576836189246536239295484699682522744627111615899081
e3: 65537
c3: 17407076170882273876432597038388758264230617761068651657734759714156681119134231664293550430901872572856333330745780794113236587515588367725879684954488698153571665447141528395185542787913364717776209909588729447283115651585815847333568874548696816813748100515388820080812467785181990042664564706242879424162602753729028187519433639583471983065246575409341038859576101783940398158000236250734758549527625716150775997198493235465480875148169558815498752869321570202908633179473348243670372581519248414555681834596365572626822309814663046580083035403339576751500705695598043247593357230327746709126221695232509039271637

Explain

I was able to factorize n from this site. Additionally I can also use SageMath in n2 and n3 because gcd of n2 and n3 is not 1.

Solve

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

variables = {}
with open("vals.txt", 'r') as f:
    for line in f:
        data = line.strip().split(": ")

        if len(data) == 2:
            name = data[0].strip()
            value = int(data[1].strip())
            variables[name] = value

n1 = variables.get("n1")
c1 = variables.get("c1")

n2 = variables.get("n2")
c2 = variables.get("c2")

n3 = variables.get("n3")
c3 = variables.get("c3")

e = 0x10001

flag = ""

phin1 = 16895844090302140592659203092326754397916615877156418083775983326567262857434286784352755691231372524046947817027609871339779052340298851455825343914565349651333283551138205456284824077873043013595313773956794816682958706482754685120090750397747015038669047713101397337825418638859770626618854997324831793483399942293439193445876565410462258408145424095373114625714666823463436027356285160751905081284239154181810844068696092653066139150228436068974242451870955518122731978988326774464530494978234244780781600510074655669895400291104256598040165674190576927181493419185550767267658104298029188019054228428445668087068
phin2 = 22160567763948492895090996477047180485455524932702696697570991168736807463988465318899280678030104758714228331712868417831523511943197686617200545714707332594532611440360591874484774459472586464202240208125663048882939144024375040954148333792401257005790372881106262295967972148685076689432551379850079201234106199216017825788678673051683319144361501367849768037929407472475858393869758337436253583130888148222917281355451236923124042483469746729375035625789504990395476050410221619041286807165303634504502778271258054063069179412686396702135882138414149543954702873109572172178520692209029826007647072129531505642300
phin3 = 30411521910612406343993844830038303042143033746292579505901870953143975096282414718336718528037226099433670922614061664943892535514165683437199134278311973454116349060301041910849566746140890727885805721657086881479617492719586633881232556353366139554061188176830768575643015098049227964483233358203790768451449790522713779237593764477520129960023709960651676644776532149666922026760766290289294881616083643821928260250243127299942302927356733497361741780435643187835604145764846151111646548824888169366336552055439368102169006201494713671464782430289036196952789164492448636114382601137360148190387559997534400669572

d1 = pow(e, -1, phin1)
d2 = pow(e, -1, phin2)
d3 = pow(e, -1, phin3)
m1 = pow(c1, d1, n1)
m2 = pow(c2, d2, n2)
m3 = pow(c3, d3, n3)

flag += str(long_to_bytes(m1), "utf-8")
flag += str(long_to_bytes(m2), "utf-8")
flag += str(long_to_bytes(m3), "utf-8")

print(flag)
❯ python3 utctf_bits-and-pieces.py
utflag{oh_no_it_didnt_work_</3_i_guess_i_can_just_use_standard_libraries_in_the_future}