NITIC CTF Writeupという名の参加記

NITIC CTFという茨城高専有志の方々によるCTFの大会に参加しました。
結果としては量産型の4位でした(参加した方ならわかる)

主催者の方のツイートに名前が出ていたのは興奮しました。

せっかく参加したのでWriteUpを書こうと思います。
Discord上では公式からWriteupが出ているのですが参加記なので気にしません。

pwnのWriteUpはありませんので察してください。

Dangerous Twitter (Recon)

問題文

フレキ君はパスワードの管理がなってないようです。  
どうやらフレキ君はあるサイトへのログインパスワードを漏らしてしまったみたい。  
フレキ君のTwitterアカウントからそのパスワードを特定しましょう。 
フラグはnitic_ctf{特定したパスワード}になります。  

https://twitter.com/FPC_COMMUNITY

ということでフレキ君のTwitterを見ると、

セキュリティ観念ガバガバなTweetをしているじゃあありませんか!!
ということでこの問題はクリアです。

82 (Web)

大量のAscii文字が書かれたテキストファイルが与えられてそこからflagを読み取る問題でした。
先頭を見てみると

data:image/jpeg;base64,

という記述があったのでこれはbase64なのか、ということでdata:image/jpeg;base64,を切り取ってデコードすると画像形式で見れるようになりました。

cat flag2.txt | base64 -d > flag.jpeg

上記のコマンドを実行して画像を表示するとflagが得られました。
(flag2.txtはflag.txtから先頭のdata~を以降を抜き出したものです。)

nitic_ctf{nemu_nemu_panti_shitai}

私が想像していたWeb問題とは違ったので少しびっくりしました。
なぜWeb問題なのか有識者の方教えてください。

prime_factorization (PPC)

問題文

合成数Cが与えられる。
素因数分解してa_0^b_0 * a_1^b_1 * … * a_n^b_nの形にして、nitic_ctf{a_0_b_0_a_1_b_1…a_n_b_n}のがフラグとなる。
この時a_iは素数、b_iは1以上の整数、aは昇順に並んでいる。

例えばC=48の時、48=2^4*3^1より、フラグはnitic_ctf{2_4_3_1}である

与えられた数字は408410100000でした。
素因数分解してくれるテキトーなサイトに投げて終了です。
私はたまたま見つけたここで素因数分解を行いました。
factrdbでも良いと思います。

素因数分解計算機 - instant tools

結果は25 * 35 * 55 * 75だったのでflag形式に直して完了です。
nitic_ctf{2_5_3_5_5_5_7_5}

shift_only (Crypto)

暗号化されたflagと暗号化アルゴリズムの書かれたソースが渡され、解読するという問題でした。

暗号化されたflag

6}bceijnob9h9303h6yg896h0g896h0g896h01b40g896hz

encrypt_flag.py

from os import environ
flag = environ["FLAG"]
format = environ["FORMAT"]

shift_table = "abcdefghijklmnopqrstuvwxyz0123456789{}_"
def encrypt(text: str, shift: int) -> str:
    assert  0 <= shift <= 9
    res = ""
    for c in text:
        res += shift_table[(shift_table.index(c)+shift)%len(shift_table)]
    return str(shift) + res
for shift in format:
    flag = encrypt(flag, int(shift))
with open("encrypted.flag", "w") as f:
    f.write(flag)

文字をshift分だけシフトして、先頭にshiftを加えていく処理を暗号化では行っているので、その逆をやれば解けそうです。
で、私が書いたプログラムがこれ

shift_table = "abcdefghijklmnopqrstuvwxyz0123456789{}_"
def decrypt(flag, shift):
    res = ""
    for c in flag:
        res += shift_table[(shift_table.index(c)+len(shift_table)-shift)%len(shift_table)]
    return res

flag = '6}bceijnob9h9303h6yg896h0g896h0g896h01b40g896hz'
while flag[0] != 'n':
    flag = decrypt(flag[1:], int(flag[0]))
print(flag)

先頭をshiftとして抜き出してそれ以降を暗号文として渡します。
flag形式はnitic_ctf{hoge}なので先頭がnになるまでループを回すことで解読できます。
実行するとflagが出てきました。

nitic_ctf{shift_shift_shift_and_shift}

cha1n (Misc)

おそらく同じ動きをするであろうbatファイルとshスクリプトファイルが渡されそこからflagを見つけ出します。
2種類あるのはOSに依存しない配慮だと思います。
私は".sh"ファイルからflagを見つけました。
ファイルは1.sh a.sh c.sh h.sh n.shがありました。
すべてcatしたやつをとりあえず載せます。

str=$(cat -)
str=${str//s/a}
str=${str//x/c}
echo ${str//qq/rr}
str=$(cat -)
str=${str//3/\}}
str=${str//8/o}
echo ${str//ww/qq}str="njtjxpxtfwx()s1Kpx()s1Kpx()s1Kpx()s1Kpx()s1Kp5x8mb83"
str=${str//()/h}
str=${str//p/_}
echo ${str//w/oo}str=$(cat -)
str=${str//j/i}
str=${str//K/n}
echo ${str//oo/ww}
str=$(cat -)
echo ${str//rr/\{}

中腹にあるstrを置き換えを使ってflagに変換するのだろうと読み取れたので、とりあえずそれぞれ実行してみました。
暗号化された文字はc.shにあるのでそれだけは一番最初に実行しないといけません。

bash c.sh | bash 1.sh | bash a.sh | bash h.sh | bash n.sh

上記を実行するとnitic_ctfwwcha1n_cha1n_cha1n_cha1n_cha1n_5combo}という文字列が出てきました。
あとはエスパーしてflagに変えます。

nitic_ctf{cha1n_cha1n_cha1n_cha1n_cha1n_5combo}

これWriteUp書いていて気づいたのですが、cha1nの順で実行すればよかったのですね... やっているときはn.shを見落としていたのもあり、全く気が付きませんでした。

FORTRAN (Reversing)

実行形式のファイルが渡されてその中からflagを見つけるというものでした。

strings problem | grep ctf

これでやるとflagが出るのですが、出題者側のうっかりミスでflagが修正前のものだったらしいです。
上記のコマンドの結果がreplacenitictf{Fortran}だったので、私はミスなんて関係なく

置き換えやるんやな!

とか考えてもう一つwindows用に渡されていたexeファイルも同じコマンドを実行しました。
変更忘れはELFファイルだけだったようです。

nitic_ctf{No_FORTRAN_Yes_Fortran}

これでこの問題は終わりなのですが、置き換えを実行すると思っていた私はnitic_ctf{No_FORTRAN_Yes_nitictf}とかをsubmitし、解けない解けないをやっていましたw
諦めて元のflagを試しに投げたら通ったので !? って感じでした。

anim (Forensic)

実行形式ファイルが渡されるのでそこからflagを見つける問題です。
とりあえず実行しても実行形式エラーとなるのでfileコマンドを実行すると

flag: Microsoft PowerPoint 2007+

と出るじゃあーりませんか。
ということで拡張子をpptxに変換するとPowerPointで開けるようになるので開いて。
あとはスライドショーでアニメーションを見ると可愛らしくflagが出てきます。

nitic_ctf{ppppptx}

Pwn 諦め・感想

道路さん作門だったし、ポイント高かったしで最初から諦めていました()
とりあえずformat string attackを使うんだなということだけ察しをつけて撤退しました。
あっているかは知りません。
あとで復習しようと思います。

感想

レベル感としてはCTF初心者向けという感じでした。
どの問題も初心者でも調べればできるような問題。
かつ中には頭を使って解くような問題もありとても楽しめました。
第1回のみオープン開催らしいのでとても残念です。
もし第2回があればまた参加したいです。
ありがとうございました。