UTCTF 2021 Writeup

この大会は2021/3/13 9:00(JST)~2021/3/15 9:00(JST)に開催されました。
今回もチームで参戦。結果は9040点で697チーム中78位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (Beginner)

ルールのところでチェックマークに投票すると、他のチャネルが現れた。
#announcementsチャネルのトピックにフラグが書いてあった。

utflag{welcome_to_utctf}

HTML (Beginner)

HTMLソースのコメントにフラグが書いてあった。

utflag{you_found_me_0123959}

Stringy Things (Beginner)

$ strings calc | grep utflag
utflag{strings_is_op}
utflag{strings_is_op}

Magic Bytes (Beginner)

$ file out.txt
out.txt: PNG image data, 1920 x 1080, 8-bit/color RGBA, non-interlaced
$ mv out.txt out.png

png画像にフラグが書いてあった。
f:id:satou-y:20210325200214p:plain

utflag{file_extensions_mean_nothing}

Run-ELF (Beginner)

$ file run
run: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e29057709baef974009b1e676fd113ed20f1942f, for GNU/Linux 3.2.0, not stripped
$ ./run
utflag{run_run_binary_9312854}
utflag{run_run_binary_9312854}

Cipher Gauntlet (Beginner)

2進数で書かれているので、まずデコードする。2行目がbase64になっているので、base64デコードする。さらに2行目はシーザー暗号になっているので、復号する。

import string

def decrypt_caesar(s, key):
    d = ''
    for c in s:
        if c in string.lowercase:
            index = string.lowercase.index(c)
            index = (index - key) % 26
            d += string.lowercase[index]
        else:
            d += c
    return d

with open('secret.txt', 'r') as f:
    enc = f.read().rstrip()

enc = enc.split(' ')

dec = ''
for c in enc:
    dec += chr(int(c, 2))

pt1 = dec.split('\n')[0]
pt2 = dec.split('\n')[1].decode('base64')

pt2_1 = pt2.split('\n')[0]
pt2_2 = decrypt_caesar(pt2.split('\n')[1], 10)

print pt1
print pt2_1
print pt2_2

最終的な復号結果は以下の通り。

Uh-oh, looks like we have another block of text, with some sort of special encoding. Can you figure out what this encoding is? (hint: if you look carefully, you'll notice that there only characters present are A-Z, a-z, 0-9, and sometimes / and +. See if you can find an encoding that looks like this one.)
New challenge! Can you figure out what's going on here? It looks like the letters are shifted by some constant. (hint: you might want to start looking up Roman people).
congratulations! you have finished the beginner cryptography challenge. here is a flag for all your hard efforts: utflag{now_youre_playing_with_crypto}. you will find that a lot of cryptography is building off this sort of basic knowledge, and it really is not so bad after all. hope you enjoyed the challenge!
utflag{now_youre_playing_with_crypto}

Sizzling Bacon (Beginner)

ベーコン暗号。'u'は'BABAA'なので、小文字を'B'、大文字を'A'とすれば復号できそう。

bacon = {'AAAAA': 'a', 'AAAAB': 'b', 'AAABA': 'c', 'AAABB': 'd', 'AABAA': 'e',
    'AABAB': 'f', 'AABBA': 'g', 'AABBB': 'h', 'ABAAA': 'i', 'ABAAB': 'j',
    'ABABA': 'k', 'ABABB': 'l', 'ABBAA': 'm', 'ABBAB': 'n', 'ABBBA': 'o',
    'ABBBB': 'p', 'BAAAA': 'q', 'BAAAB': 'r', 'BAABA': 's', 'BAABB': 't',
    'BABAA': 'u', 'BABAB': 'v', 'BABBA': 'w', 'BABBB': 'x', 'BBAAA': 'y',
    'BBAAB': 'z'}

enc = 'sSsSSsSSssSSsSsSsSssSSSSSSSssS{SSSsSsSSSsSsSSSsSSsSSssssssSSSSSSSsSSSSSSSSsSSsssSSssSsSSSsSSsSSSSssssSSsssSSsSSsSSSs}'

i = 0
flag = ''
while True:
    if enc[i].lower() == 's':
        part = enc[i:i+5]
        part = part.replace('S', 'A').replace('s', 'B')
        flag += bacon[part]
        i += 5
    else:
        flag += enc[i]
        i += 1
    if i >= len(enc):
        break

print flag
utflag{crispybaconcipher}

Various Vernacular (Beginner)

換字式暗号と推測。quipqiupで復号する。

ciphertext: Hkgxologflutleiaymt xgf Azutgkrftmtf ltmntf ERW wfr ELW wfmtk Rkweq.
plaintext : Provisionsgeschafte von Algeordneten setzen CDU und CSU unter Druck.

同様に調整しながら対応するよう復号する。最終的には暗号 s は平文 l に対応するよう調整して復号できた。

wmysau{foeim_Tfusoli}
  ↓
utflag{nicht_English}
utflag{nicht_English}

Source it! (Web)

HTMLソースを見ると、以下のようなチェックがあることがわかる。

            function checkPassword(form) { 
                password1 = form.password1.value; 
                name = form.name.value;
                var username = "admin";
                var hash = "1bea3a3d4bc3be1149a75b33fb8d82bc"; 
                var hashedPasswd = CryptoJS.MD5(password1);
   
                if (password1 == '') 
                    alert ("Please enter Password"); 
              
                else if (username != name) { 
                    alert ("\nYou lack access privlages...") 
                    return false; 
                }
                     
                else if (hash != hashedPasswd) { 
                    alert ("\nIncorrect password...") 
                    return false; 
                } 
  
                else{ 
                    alert("Access Granted\n" + text) 
                    return true; 
                } 
            } 

ユーザ名は"admin"。パスワードは"1bea3a3d4bc3be1149a75b33fb8d82bc"をmd5逆変換すると、"sherlock"。これでログインすると、フラグが表示された。

utflag{b33n_th3r3_s0uRc3d_th4t}

Cutest Cookie Clicker Rip-Off (Web)

クッキーのhighScoreをHigh scoreを上回るように設定する。ページを更新し、時間切れになるのを待つと、フラグが表示された。

utflag{numnum_cookies_r_yumyum}

Doubly Deleted Data (Forensics)

FTK Imagerで開く。[root]直下を見ると、削除マーク付きでsus_image.imgがあるので、エクスポートする。
今度はsus_image.imgをFTK Imagerで開く。[root]-[hacker]-[.bash_history]をエクスポートし、そのファイルを見てみる。

mkdir secret_hacker_stuff
cd secret_hacker_stuff/
nano flag.txt
echo "utflag{d@t@_never_dis@ppe@rs}" > real_flag.txt
rm real_flag.txt
utflag{d@t@_never_dis@ppe@rs}

Sandwiched (Forensics)

$ binwalk secret.pdf

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PDF document, version: "1.5"
71            0x47            Zlib compressed data, default compression
290           0x122           Zlib compressed data, default compression
6017          0x1781          Unix path: /Type/FontDescriptor/FontName/BAAAAA+LiberationSerif
6252          0x186C          Zlib compressed data, default compression
6550          0x1996          Unix path: /Type/Font/Subtype/TrueType/BaseFont/BAAAAA+LiberationSerif
6907          0x1AFB          Unix path: /S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>
7824          0x1E90          JPEG image data, JFIF standard 1.01
37768         0x9388          PDF document, version: "1.5"
37839         0x93CF          Zlib compressed data, default compression
38058         0x94AA          Zlib compressed data, default compression
43785         0xAB09          Unix path: /Type/FontDescriptor/FontName/BAAAAA+LiberationSerif
44020         0xABF4          Zlib compressed data, default compression
44318         0xAD1E          Unix path: /Type/Font/Subtype/TrueType/BaseFont/BAAAAA+LiberationSerif
44675         0xAE83          Unix path: /S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>
75536         0x12710         PDF document, version: "1.5"
75607         0x12757         Zlib compressed data, default compression
75826         0x12832         Zlib compressed data, default compression
81553         0x13E91         Unix path: /Type/FontDescriptor/FontName/BAAAAA+LiberationSerif
81788         0x13F7C         Zlib compressed data, default compression
82086         0x140A6         Unix path: /Type/Font/Subtype/TrueType/BaseFont/BAAAAA+LiberationSerif
82443         0x1420B         Unix path: /S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>
113304        0x1BA98         PDF document, version: "1.5"
113375        0x1BADF         Zlib compressed data, default compression
113594        0x1BBBA         Zlib compressed data, default compression
119321        0x1D219         Unix path: /Type/FontDescriptor/FontName/BAAAAA+LiberationSerif
119556        0x1D304         Zlib compressed data, default compression
119854        0x1D42E         Unix path: /Type/Font/Subtype/TrueType/BaseFont/BAAAAA+LiberationSerif
120211        0x1D593         Unix path: /S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>
151072        0x24E20         PDF document, version: "1.5"
151143        0x24E67         Zlib compressed data, default compression
151362        0x24F42         Zlib compressed data, default compression
157089        0x265A1         Unix path: /Type/FontDescriptor/FontName/BAAAAA+LiberationSerif
157324        0x2668C         Zlib compressed data, default compression
157622        0x267B6         Unix path: /Type/Font/Subtype/TrueType/BaseFont/BAAAAA+LiberationSerif
157979        0x2691B         Unix path: /S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>
188841        0x2E1A9         PDF document, version: "1.5"
188912        0x2E1F0         Zlib compressed data, default compression
189131        0x2E2CB         Zlib compressed data, default compression
194858        0x2F92A         Unix path: /Type/FontDescriptor/FontName/BAAAAA+LiberationSerif
195093        0x2FA15         Zlib compressed data, default compression
195391        0x2FB3F         Unix path: /Type/Font/Subtype/TrueType/BaseFont/BAAAAA+LiberationSerif
195748        0x2FCA4         Unix path: /S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>

間にJPEGが入っている。foremostで切り出す。

$ foremost secret.pdf
Processing: secret.pdf
|*|

JPGファイルが壊れているが、適当な修復ツールで修復する。
f:id:satou-y:20210325202014j:plain

utflag{file_sandwich_artist}

Small P Problems (Cryptography)

DSAの離散対数問題。pが小さいので、総当たりで秘密鍵を求め、そこから共通鍵を求める。

p = 69691
g = 1001

A = 17016
B = 47643

for sec in range(p):
    if pow(g, sec, p) == A:
        sec_A = sec
        break

shared_key = pow(B, sec_A, p)
flag = 'utflag{%d}' % shared_key
print flag
utflag{53919}

Half-time survey (Beginner)

アンケートに答えたらフラグが表示された。

utflag{thank_you_278672}