peaCTF 2019 (Round 2) Writeup

この大会は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画像にフラグが書いてある。
f:id:satou-y:20190912213312p:plain
どうやら、フラグは"_"区切りで先頭を大文字にしてやる必要があるみたい。

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}