SECCON Beginners CTF 2022

はじめに

SECCON Beginners CTF 2022 SECCON Beginners CTF 2022 を開催いたします! - SECCON2022に,playgroundというコミュニティの先輩方と3人で参加したので,僕が関わった問題についてWriteUPします。 CTFというものが完全に初めてだったので試行錯誤でしたが,意外と個人的には奮闘できたと思います。

Web

textex[128 team solved, 92pt]

texをpdfにするサービスを作りました。 texで攻撃することはできますか?

https://textex.quals.beginners.seccon.jp textex.tar.gz 31fd2c7d44bf76b937e3d141032ac62b5e301dee

Cloud LaTeXみたいな愉快なツールが登場した。

ファイルはこんな感じで,flagを読み込めればよさそうだ。

TeXでは\inputによりファイルの中身をそのまま(TeXのコードの一部として)読み込める。

\documentclass{article}
\begin{document}

This is a sample.
\input{requirements.txt}

\end{document}

とすると,

と読み込めた。

flagというファイルのテキストを引っ張り出せればOKだとわかったが,

        # No flag !!!!
        if "flag" in tex_code.lower():
            tex_code = ""

というコードに阻まれていた。flagという文字列を作成できれば良いので,

\newcommand{\aaa}{fl}
\newcommand{\bbb}{ag}

と適当に生成して,ファイル名を\aaa\bbbと指定したらうまくいった。

最後に,フラグに何らかのLaTeXの特殊文字が含まれていることがわかったので,そんな時はとlistingsを試したがインポートできなかった。調べてみて,verbatimをインポートすることに成功したので,最終的に

\documentclass{article}
\usepackage{verbatim}
\newcommand{\aaa}{fl}
\newcommand{\bbb}{ag}
\begin{document}
\verbatiminput{\aaa\bbb}
\end{document}

でうまくいった。

misc

phisher[238 team solved, 70pt]

ホモグラフ攻撃を体験してみましょう。 心配しないで!相手は人間ではありません。

nc phisher.quals.beginners.seccon.jp 44322

phisher.tar.gz bc81b6186868cb1d932a12bd5a3612010b52cb8d

入力したテキストを,Murechoというオープンなフォントで画像ファイルに書き出し,english指定でocrにかけ文字を復元していた。 このocrに掛け復元した文字が,www.example.comのどの文字も使わずにwww.example.comと騙して読み込むことができればflagが帰ってくるようになっていた。

実験レポで全角半角変換でお世話になっているサイトの Unicodeの一覧ツールをテキストエディタに貼り付け,Murechoフォントで表示した。その後はひたすら気合いで探しては試行錯誤を繰り返して,何とかωωω․εⅹáⅿρIε․ċοⅿという文字列でうまくひっかっかった。 ドットを探すのが特に大変だった。

❯ nc phisher.quals.beginners.seccon.jp 44322
       _     _     _                  ____    __
 _ __ | |__ (_)___| |__   ___ _ __   / /\ \  / /
| '_ \| '_ \| / __| '_ \ / _ \ '__| / /  \ \/ /
| |_) | | | | \__ \ | | |  __/ |    \ \  / /\ \
| .__/|_| |_|_|___/_| |_|\___|_|     \_\/_/  \_\
|_|

FQDN: ωωω․εⅹáⅿ𐌓Iε․ċοⅿ
"www.examile.com" is not "www.example.com" !!!!

❯ nc phisher.quals.beginners.seccon.jp 44322
       _     _     _                  ____    __
 _ __ | |__ (_)___| |__   ___ _ __   / /\ \  / /
| '_ \| '_ \| / __| '_ \ / _ \ '__| / /  \ \/ /
| |_) | | | | \__ \ | | |  __/ |    \ \  / /\ \
| .__/|_| |_|_|___/_| |_|\___|_|     \_\/_/  \_\
|_|

FQDN: ωωω․εⅹáⅿρIε․ċοⅿ
ctf4b{n16h7_ph15h1n6_15_600d}

文章比較ツールより。

Screen Shot 2022-06-05 at 19 14 54

上: www.example.com 下: ωωω․εⅹáⅿρIε․ċοⅿ

みなさんも,ホモグラフ攻撃によるフィッシングに遭わないよう気をつけましょう(?)。

hitchhike4b[125 team solved, 84pt]

helpを呼び出したら、ページャーとして猫が来ました。

nc hitchhike4b.quals.beginners.seccon.jp 55433

コードなしでの取得だった。先輩が__main__と入力するとフラグの前半がもらえることを突き止めてくれて,後半(flag2)を探した。

❯ nc hitchhike4b.quals.beginners.seccon.jp 55433
 _     _ _       _     _     _ _        _  _   _
| |__ (_) |_ ___| |__ | |__ (_) | _____| || | | |__
| '_ \| | __/ __| '_ \| '_ \| | |/ / _ \ || |_| '_ \
| | | | | || (__| | | | | | | |   <  __/__   _| |_) |
|_| |_|_|\__\___|_| |_|_| |_|_|_|\_\___|  |_| |_.__/


----------------------------------------------------------------------------------------------------

# Source Code

import os
os.environ["PAGER"] = "cat" # No hitchhike(SECCON 2021)

if __name__ == "__main__":
    flag1 = "********************FLAG_PART_1********************"
    help() # I need somebody ...

if __name__ != "__main__":
    flag2 = "********************FLAG_PART_2********************"
    help() # Not just anybody ...

----------------------------------------------------------------------------------------------------

Welcome to Python 3.10's help utility!

If this is your first time using Python, you should definitely check out
the tutorial on the internet at https://docs.python.org/3.10/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".

help> __main__
Help on module __main__:

NAME
    __main__

DATA
    __annotations__ = {}
    flag1 = 'ctf4b{53cc0n_15_1n_m'

FILE
    /home/ctf/hitchhike4b/app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc.py


help>

help utilityについて調べていると,Python help() について - Opensourcetechブログに出会った。とりあえず,modulesと実行してみると,

help> modules
...(略)...
_codecs_jp          aifc                imghdr              socket
_codecs_kr          antigravity         imp                 socketserver
_codecs_tw          app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc importlib           spwd
_collections        argparse            inspect             sqlite3
_collections_abc    array               io                  sre_compile
...(略)...

なんか明らかに怪しいやつがいた。 こいつを2回打ち込んでみると,

help> app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc
 _     _ _       _     _     _ _        _  _   _
| |__ (_) |_ ___| |__ | |__ (_) | _____| || | | |__
| '_ \| | __/ __| '_ \| '_ \| | |/ / _ \ || |_| '_ \
| | | | | || (__| | | | | | | |   <  __/__   _| |_) |
|_| |_|_|\__\___|_| |_|_| |_|_|_|\_\___|  |_| |_.__/


----------------------------------------------------------------------------------------------------

# Source Code

import os
os.environ["PAGER"] = "cat" # No hitchhike(SECCON 2021)

if __name__ == "__main__":
    flag1 = "********************FLAG_PART_1********************"
    help() # I need somebody ...

if __name__ != "__main__":
    flag2 = "********************FLAG_PART_2********************"
    help() # Not just anybody ...

----------------------------------------------------------------------------------------------------

Welcome to Python 3.10's help utility!

If this is your first time using Python, you should definitely check out
the tutorial on the internet at https://docs.python.org/3.10/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".

help> app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc
Help on module app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc:

NAME
    app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc

DATA
    flag2 = 'y_34r5_4nd_1n_my_3y35}'

FILE
    /home/ctf/hitchhike4b/app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc.py

出てきた。

reversing

Quiz[650 team solved, 50pt]

クイズに答えよう!

quiz.tar.gz a7f225b59176baa3d888c6fc7452f8df9a58e204

fileコマンドでチェックしてみると,ELFというlinuxでの実行ファイルだったので,sshで,無料で立てていたubuntu on azureに繋いで実行してみた。すると,

$ ./quiz
Welcome, it's time for the binary quiz!
ようこそ、バイナリクイズの時間です!

Q1. What is the executable file's format used in Linux called?
    Linuxで使われる実行ファイルのフォーマットはなんと呼ばれますか?
    1) ELM  2) ELF  3) ELR
Answer : 2
Correct!

Q2. What is system call number 59 on 64-bit Linux?
    64bit Linuxにおけるシステムコール番号59はなんでしょうか?
    1) execve  2) folk  3) open
Answer : 1
Correct!

Q3. Which command is used to extract the readable strings contained in the file?
    ファイルに含まれる可読文字列を抽出するコマンドはどれでしょうか?
    1) file  2) strings  3) readelf
Answer : 2
Correct!

Q4. What is flag?
    フラグはなんでしょうか?
Answer : ?
flag length must be 46.

stringsコマンドなるものを教えてくれた。 strings quizを実行してみたら,

...(略)...
u+UH
[]A\A]A^A_
ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?}
Welcome, it's time for the binary quiz!
Q1. What is the executable file's format used in Linux called?
...(略)...

フラグが転がってた。あとでquizに打ち込んでみても正解できた。

WinTLS[102 team solved, 100pt]

TLSってなんだぁ?

wintls.tar.gz 4607f34efbcbc99137e684c00d7e4cb4425ec358

解けそうな問題がこれを始めた頃はなかったので,Macユーザーだけど,とりあえず調べてやってみた。基本は,IDA Tutorial + CTF・脆弱性診断 超入門 Reversing③ 動画版 - 株式会社Ninjastars 技術系ブログの動画の通りに進めた。さすがに全く同じではなく,パスワードをそのままチェックする部分が,

c4{fAPu8#FHh2+0cyo8$SWJH3a8X
tfb%s$T9NvFyroLh@89a9yoC3rPy&3b}

という2つの文字列に分かれていて,それぞれの部分で一致のチェックがされていた(問題修正前は片方だけだった?)。ただ,それぞれの長さが異なるように,単純に組み合わせれば良いわけではなさそうだった。 そのため,先ほどのサイトとほぼ同様にブレイクポイントを設定した上で,入力欄に0123456789abcdefghijklmnopqrstuvxyzと入力してみた。すると,

このように分かれた。終わったら,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0123456789abcdefghijklmnopqrstuvxyzでも試し,以下のようになった。

そしたらあとは,脳筋戦術で書き出して,

-大文字小文字のタイプミスをするなどしながら- ctf4b{f%sAP$uT98Nv#FFHyrh2o+Lh0@8c9yoa98$ySoCW3rJPH3y&a83Xb}を得た。 正解!

crypto

CoughingFox[443 team solved, 55pt]

きつねさんが食べ物を探しているみたいです。

coughingfox.tar.gz c2cdda5cb20d25e40be57a72a949591b7172d143

なんかの規則で暗号化してるみたいだった。

from random import shuffle

flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"

cipher = []
print(flag)

for i in range(len(flag)):
    f = flag[i]
    c = (f + i)**2 + i
    cipher.append(c)

shuffle(cipher)
print("cipher =", cipher)

outputにあったリストは49文字。

cipher = [12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649, 15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472]

フラグがctf4b{[\x20-\x7e]+}であることから,2乗しても少なくとも(0x20^2=)32^2=1024となり,隣の平方との差は少なくとも(32+1)^2=1089との差である65はあることがわかる。 リストの項目数は49個で,49文字だということが確認されているので,暗号化時のiは大きくとも48だとわかる。 よって,適当に0から平方の和をとって比較し,超える一つ前の値がf+iで,その時のiを差を取って求められるとわかった。 よって,あとは何の工夫もなく適当に汚いコーディングをして,

cipher = [12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649,
          15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472]
answerstr = [‘a’] * len(cipher)
for c in cipher:
    ans = 0
    location = 0
    for i in range(200):
        if c < i ** 2:
            ansd = i - 1
            location = c - ansd ** 2
            ans = ansd - location
            answerstr[location] = chr(ans)
            print(fans: {ans}, location: {location}, chr(ans): {chr(ans)}’)
            break
answerstr = ‘’.join(answerstr)
print(len(cipher))
...(略)...
ans: 110, location: 43, chr(ans): n
ans: 111, location: 11, chr(ans): o
ans: 104, location: 28, chr(ans): h
ans: 89, location: 44, chr(ans): Y
ans: 115, location: 34, chr(ans): s
ans: 119, location: 38, chr(ans): w
ans: 101, location: 24, chr(ans): e
ans: 111, location: 37, chr(ans): o
ans: 84, location: 23, chr(ans): T
ctf4b{Hey,Fox?YouCanNotTearThatHouseDown,CanYou?}

ctf4b{Hey,Fox?YouCanNotTearThatHouseDown,CanYou?}と求まった。

Welcome

Welcome[845 team solved, 50pt]

Discordでフラグが配られた,参加賞。 なぜここに書いた

終わりに

3人だったのですが意外となんか健闘して,74/891位となれました。初めてにしてはできすぎて怖いレベルです。pwnとかcryptとかgoとか色々,マジでわかんないやつ解いてくださって,マジすごかった。Playgroundの先輩方,ありがとうございました! 1000点取りたかったねと残念がってる

Screen Shot 2022-06-05 at 17 21 04