この大会は2019/8/31 9:00(JST)~2019/9/6 9:00(JST)に開催されました。
今回もチームで参戦。結果は4850点...のはずです。
途中で、shell1.2019.peactf.comがダウンし、添付ファイルをダウンロードすることができなくなり、シェルサーバやnc接続、Web問題の問題ページにアクセスできず、問題が解けない状況になり、最後まで復旧しませんでした。スコアボードもおかしな状況で、順位はわかりません。
最初にファイルを入手し、それだけで解ける問題だけしか挑戦すらできなかったので、どんな問題だったのか知りたいものです。CTFとしては最悪に近い大会でした。
一応自分で解けた問題をWriteupとして書いておきます。
Not The Droids (Reversing 1000)
apkファイルが添付されていたので、まず解凍してみる。
するとdex-layout/parsedump/dex-dump.dexにフラグが書いてあった。
peaCTF{Use_The_Forks}
Guillotine (Forensics 1200)
添付ファイルはPNGのIDATチャンクだけのデータのように見える。幅と高さ、カラータイプに問題に記載しているものを指定して、IHDRチャンクを作って、PNGを構成する。
import struct import binascii with open('hail-hydra', 'rb') as f: idat = f.read() PNG_HEAD = '\x89PNG\x0d\x0a\x1a\x0a' IHDR_LEN = '\x00\x00\x00\x0d' IHDR_CHUNK = 'IHDR' IHDR_TAIL = '\x08\x06\x00\x00\x00' IEND = '\x00\x00\x00\x00IEND\xae\x42\x60\x82' out = PNG_HEAD IHDR_WIDTH = struct.pack('>I', 2679) IHDR_HEIGHT = struct.pack('>I', 1724) IHDR = IHDR_CHUNK + IHDR_WIDTH + IHDR_HEIGHT + IHDR_TAIL IHDR_CRC = struct.pack('!l', binascii.crc32(IHDR)) out += IHDR_LEN + IHDR + IHDR_CRC + idat + IEND with open('hail-hydra.png', 'wb') as f: f.write(out)
復元したPNG画像にフラグが書いてある。
どうやら、フラグは"_"区切りで先頭を大文字にしてやる必要があるみたい。
peaCTF{Just_A_Flesh_Wound}
RSA 2 (Cryptography 1250)
Round 1のときのRSAの問題を参考に考え、方針を立てる。それぞれ得られた文字列を結合すると、フラグになる。
Encrypted Channel #1: nをfactordbで素因数分解し、復号する。 n = 699341830973140937533889347153873853 * 1038712512706646268598380266466164687 Encrypted Channel #2: nをfactordbで素因数分解し、復号する。 n = 737717913006402005436955273940076541 * 1297159581898303872138969477851535643 Authenticated Channel #1: encryptすると、mのhash値が得られるので、総当たりで求める。 Authenticated Channel #2: encryptすると、mのhash値が得られるので、総当たりで求める。
from Crypto.Util.number import * import string import itertools import hashlib chars = string.lowercase + string.digits n = 726415110490977923087790491827227969870609358082104062497204843521229011 e = 65537 c = 19893771441136011784712095817339088129586581147600336598861776491438381 p = 699341830973140937533889347153873853 q = 1038712512706646268598380266466164687 phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag1 = long_to_bytes(m) print flag1 n = 660472957694887679823683652043504023558962189001524727432185600461464707 e = 65537 c = 336302789914193201113048946294125165277516967600443771876900092183949803 m = pow(c, e, n) h = hex(m)[2:].rstrip('L').zfill(32) found = False for r in range(1, 6): for c in itertools.product(chars, repeat=r): flag2 = '{' + ''.join(c) if hashlib.md5(flag2).hexdigest() == h: found = True break if found: break print flag2 n = 956937859594273733490090980504656161254530199464758123399543277809650863 e = 65537 c = 833491301056670884588591723643760158187417664848645486045165661247902338 p = 737717913006402005436955273940076541 q = 1297159581898303872138969477851535643 phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag3 = long_to_bytes(m) print flag3 n = 654188640139815964805735669661611985336438765327491142066046193716545173 e = 65537 c = 382925171692094135776256838458454846460548877183442727284045377051487081 m = pow(c, e, n) h = hex(m)[2:].rstrip('L').zfill(32) found = False for r in range(1, 6): for c in itertools.product(chars, repeat=r): flag4 = ''.join(c) + '}' if hashlib.md5(flag4).hexdigest() == h: found = True break if found: break print flag4 flag = flag1 + flag2 + flag3 + flag4 print flag
peaCTF{br4k1ngh4sh3s4fun}
Droid Rage(Reversing 1400)
apkファイルが添付されていたので、まず解凍する。その後dex2jarでdexファイルからjarファイルに変換する。
>d2j-dex2jar classes.dex dex2jar classes.dex -> .\classes-dex2jar.jar
それからJD-GUIでデコンパイルする。フラグに関係があるコードがある。
if ((str1.equals("hulkhogan@exeter.edu")) && (str2.equals("HandShake"))) Toast.makeText(getApplicationContext(), "Junk_Food_Junkie", 1).show(); Toast.makeText(getApplicationContext(), "Incorrect Password", 0).show();
peaCTF{Junk_Food_Junkie}