Rooters CTF Writeup

この大会は2019/10/10 15:30(JST)~2019/10/12 15:30(JST)に開催されました。
今回もチームで参戦。結果は6193点で450チーム中9位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (Misc)

Discordの入ると、#announcementsチャネルのメッセージにフラグが書いてある。

rooters{W3lc0m3_t0_RootersCTF}ctf

Programming (Misc)

pngファイルをStegsolveで開き、Red plane 0を見ると、フラグの後半が書いてある。
f:id:satou-y:20191018215534p:plain

_T0_d1g_deep3R}ctf

pngファイルの後ろにzipファイルがあるので取り出す。zipを展開すると、input.txtとreadme.txtのファイルが出てくる。readme.txtにはこう書いてある。

there is a file input.txt which contains 2 strings. and the longest common subsequence of those 2 strings will give you the flag

どうやらinput.txtの2行に対して、LCSを求めればよいらしい。
https://www.sanfoundry.com/python-program-find-longest-common-subsequence-using-dynamic-programming-memoization/を参考にスクリプトを組む。

def lcs(u, v):
    c = [[-1]*(len(v) + 1) for _ in range(len(u) + 1)]
    lcs_helper(u, v, c, 0, 0)
    return c

def lcs_helper(u, v, c, i, j):
    if c[i][j] >= 0:
        return c[i][j]

    if i == len(u) or j == len(v):
        q = 0
    else:
        if u[i] == v[j]:
            q = 1 + lcs_helper(u, v, c, i + 1, j + 1)
        else:
            q = max(lcs_helper(u, v, c, i + 1, j),
                    lcs_helper(u, v, c, i, j + 1))
    c[i][j] = q
    return q

def get_lcs(u, v, c):
    s = ''
    i = j = 0
    while not (i == len(u) or j == len(v)):
        if u[i] == v[j]:
            s += u[i]
            i += 1
            j += 1
        elif c[i][j + 1] > c[i + 1][j]:
            j += 1
        else:
            i += 1
    return s

with open('input.txt', 'r') as f:
    s1 = f.readline()
    s2 = f.readline()

c = lcs(s1, s2)
flag1 = get_lcs(s1, s2, c)
print flag1

LCSの結果は以下の通り。

rooters{s0m3times_U_h@v3

結合するとフラグになる。

rooters{s0m3times_U_h@v3_T0_d1g_deep3R}ctf

You Can't See Me (Forensics)

pdfを開くと、真っ白なページが93ページまである。
テキストを全選択し、コピーする。

    :
CUR PRAEMIA CRESCIT HAUSTAM VIM
IGNOTAS. AC II QUATENUS RELIQUAS
S23432EQ{rooters{Ja1_US1CT}ctfINC
ERTAS
EO LECTIONE ODORATUM. HA INFINITI
EARUMDEM AC FUNDITUS
RCTF CURANDUM EJUSMODI
CONVERTO.DEI QUID QUAM HUIC SAE
FORE NISI.
OLIM DERCtUS FOCO AGI SINE DURA
ULLO TAM. SU}O DISSIMILEM
incrementi duo_98UHB praevidere.
v RCTF Meo nullo ens
talem dubio age novum aucta eam.
In saepius infus}um
    :

最後の方にフラグらしきものが混ざっている。

rooters{Ja1_US1CT}ctf

Find The Pass (Forensics)

802.11の通信ばかりがあるcapファイルが添付されている。キーをクラックしてみる。

$ aircrack-ng inc0gnito.cap 
Opening inc0gnito.cap
Read 2275250 packets.

   #  BSSID              ESSID                     Encryption

   1  E8:DE:27:57:4F:32  BLUE_CORP                 WEP (20006 IVs)

Choosing first network as target.

Opening inc0gnito.cap
Attack will be restarted every 5000 captured ivs.
Starting PTW attack with 20006 ivs.


                                 Aircrack-ng 1.2 rc2


                 [00:00:02] Tested 50922 keys (got 20006 IVs)

   KB    depth   byte(vote)
    0    0/  1   FF(32256) CE(25856) 0F(25600) 07(24832) 59(24832) 
    1   41/ 54   00(22272) 11(22016) 1E(22016) 25(22016) 33(22016) 
    2   11/ 19   AD(23808) EB(23808) F4(23808) 06(23808) 5F(23552) 
    3    2/  5   BE(26112) 58(25600) A7(25600) EA(25088) BF(24320) 
    4    0/ 10   EF(28928) 8F(27392) 30(27392) BF(26112) AD(25856) 

                         KEY FOUND! [ FF:DE:AD:BE:EF ] 
	Decrypted correctly: 100%

Wiresharkで開き、[編集]-[設定]から[Protocols]-[IEEE 802.11]の設定で、wepを選択し、キーをFF:DE:AD:BE:EFと設定し、復号する。
httpでフィルタリングして通信を見てみると、No.7076パケットにBasic認証のデータが入っている。

admin:blu3_c0rp_p4ss
rooters{blu3_c0rp_p4ss}ctf

Frames per Story (Forensics)

たくさんjpgが入っている。EXIFに文章が含まれていることがわかったので、全ファイルのEXIFを取得してみる。

$ exiftool *.jpeg | grep Comment
Comment                         : MICHAEL: All
Comment                         : right Jim,
Comment                         : your
Comment                         : quarterlies
Comment                         : look very
Comment                         : good. How
Comment                         : the thing is
Comment                         : going at the
Comment                         : library?JIM:
Comment                         : Oh I told
Comment                         : you couldn't
Comment                         : close it
Comment                         : soMICHAEL:
Comment                         : So you've
Comment                         : come to the
Comment                         : master for
Comment                         : guidance?
Comment                         : (imitating)
Comment                         : Is http://ti
Comment                         : ny.cc/rosvdz
Comment                         : this what
Comment                         : you're
Comment                         : saying grass
Comment                         : hopper?JIM:
Comment                         : Actually you
Comment                         : called me in
Comment                         : here, but ye
Comment                         : ah.MICHAEL:
Comment                         : All right,
Comment                         : well let me
Comment                         : show you how
Comment                         : it's done. h
Comment                         : ttp://tiny.c
Comment                         : c/rosvdz
Comment                         : (gets on
Comment                         : phone) Yes,
Comment                         : I liked to
Comment                         : speak to
Comment                         : your office
Comment                         : manager
Comment                         : please. Yes
Comment                         : hello this
Comment                         : is Michael
Comment                         : Scott, I am
Comment                         : the regional
Comment                         : manager of
Comment                         : Dunder
Comment                         : Mifflin
Comment                         : paper
Comment                         : products.
Comment                         : Just wanted
Comment                         : to talk to
Comment                         : you,
Comment                         : manager-on-
Comment                         : manager.
Comment                         : (cut to the
Comment                         : office and
Comment                         : cut back)
Comment                         : All right
Comment                         : done deal,
Comment                         : thank you
Comment                         : very much
Comment                         : sir, you're
Comment                         : a gentleman
Comment                         : and a
Comment                         : scholar. Oh
Comment                         : I'm sorry,
Comment                         : ok, I'm
Comment                         : sorry, my
Comment                         : mistake.
Comment                         : (hangs up)
Comment                         : That was a
Comment                         : woman I was
Comment                         : talking to
Comment                         : she had a
Comment                         : very low
Comment                         : voice.
Comment                         : Probably a
Comment                         : smoker. So,
Comment                         : so that's
Comment                         : the way it's
Comment                         : done.
Comment                         : Michael: (to
Comment                         : the camera)
Comment                         : I've been in
Comment                         : Dundler
Comment                         : Mifflin for
Comment                         : twelve
Comment                         : years, the
Comment                         : last four as
Comment                         : regional
Comment                         : manager. If
Comment                         : you want to
Comment                         : come through
Comment                         : here, (opens
Comment                         : the door to
Comment                         : the main
Comment                         : office) so
Comment                         : we have the
Comment                         : entire
Comment                         : floor, so
Comment                         : this is my
Comment                         : kingdom, as
Comment                         : far as the
Comment                         : eye can see,
Comment                         : ah this is
Comment                         : our
Comment                         : receptionist
Comment                         : Pam. (goes
Comment                         : to the recep
Comment                         : tionist)
Comment                         : Pam, Pam
Comment                         : Pam! http://
Comment                         : tiny.cc/rosv
Comment                         : dz Pam
Comment                         : Beesly. Pam
Comment                         : has been
Comment                         : with us for'
Comment                         : for ever,
Comment                         : Lavc57.70.100

URLが含まれている。http://tiny.cc/rosvdzにアクセスしてみる。実体はGoogleドライブでfinal.pngがダウンロードできる。
f:id:satou-y:20191018220650p:plain
ダウンロードした画像をよく見ると二人の間に不自然な線がある。この線の部分のRGBをASCIIコードとして文字にする。

from PIL import Image

img = Image.open('final.png').convert('RGB')
w, h = img.size

flag = ''
for y in range(6, 20):
    r, g, b = img.getpixel((374, y))
    flag += chr(r) + chr(g) + chr(b)

print flag

実行結果は以下の通り。

rooters{WHY_4R3_TH3_W4Y_TH4T_Y0U_4R3!}c tf

\x00がcとtfの間に入るので、詰める。

rooters{WHY_4R3_TH3_W4Y_TH4T_Y0U_4R3!}ctf

babyRSA (Cryptography)

RSA暗号。factordbでnを素因数分解する。

p = 244117596642286059282649228191796982671
q = 312461564294690980358123469116445272347

あとはそのまま復号する。

from Crypto.Util.number import *

c = int('a0d8e768fa9d7238a6974b4a54073165fede084494d52b2ed600e6d0e77c1113', 16)
n = 76277366118709104496037524736448350894293924248428417186334555697457434498837
e = 65537

p = 244117596642286059282649228191796982671
q = 312461564294690980358123469116445272347

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print flag
rooters{L34RNING_N3W_TH1NGS}ctf

Really Silly Algorithm LIBrary (Cryptography)

スクリプトの変数名から、RSA鍵生成脆弱性ROCAの問題と推定し、necaで素因数分解する。

$ ./neca 11127212863544389237262565582342312793444654886136310133705565382574067475157051952050355000097126157942244686899397157941082263117851
NECA - Not Even Coppersmith's Attack
ROCA weak RSA key attack by Jannis Harder (me@jix.one)

 *** Currently only 512-bit keys are supported ***

N = 11127212863544389237262565582342312793444654886136310133705565382574067475157051952050355000097126157942244686899397157941082263117851
Factoring...



Factorization found:
N = 3851789689222186911734129440311249236982321127122393533115947118361 * 2888842268486202984677183224410114807785901996516180457699983627091

素因数分解できたので、あとはそのまま復号する。

from Crypto.Util.number import *

c = int('014107b18849e23cc0494a1f32d2176a0c0a497e2ad35d054941716d6a60c5be5656b369e0e4bba72fbcaba4586bc0cd352d4da34023b5a8', 16)
n = 11127212863544389237262565582342312793444654886136310133705565382574067475157051952050355000097126157942244686899397157941082263117851
e = 0x10001

p = 3851789689222186911734129440311249236982321127122393533115947118361
q = 2888842268486202984677183224410114807785901996516180457699983627091

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print flag
rooter{H0W_0DD_W45_17}ctf

Digene (Cryptography)

1行目と3行目にURL SafeなBase64文字列がある。いろいろと調べたところ、Fernet暗号である可能性が高い。1行目を暗号データ、3行目を鍵として復号する。

from cryptography.fernet import Fernet

token = 'gAAAAABdnF6L7Gb1WxFUr4AVSs3Lg0lHetYDwxJvo84WN9DZd2_UASlX26XhPuFgIFs5v54yzxAbmQaZet9tOP-__y46eLqW5OeyLNlKlRpX_UfMm-aDLAM5p-DrBEBK_IzH_2kXJxc3'
key = 'eH9Yta38cisI5gPZiNA3C6yKRRqqEy-K9Q9ZwfF5r1k='

f = Fernet(key)
flag = f.decrypt(token)
print flag
rooters{d!g3st!f_th4t_d!g3sts_y0ur_m3ss4g3s}ctf