[参加レポ]『SECCON Beginners CTF 2022』に初参加してみた

CTFはじめました。
2022.06.13

こんにちは、AWS事業本部@福岡オフィスのべこみん(@beco_minn)です。

今回は先週末に参加した『SECCON Beginners CTF 2022』というイベントの参加レポートになります。

ちなみに私はCTFガチ初心者で、今回がCTFイベント初参加になります。

「何やら楽しく情報セキュリティに関する勉強が出来るCTFっていう最高のコンテンツがあるらしい」との噂を聞きつけ、CTFやってみるか!となったので参加してきました。

今回私は同僚と3人チームを組み参加したのですが、結果から言うと 426位 / 891チーム でした。(ちなみに同得点数のチームが65チームいました。)

『SECCON Beginners CTF 2022』の概要

  • 開催日程

    2022/6/4 (土) 14:00 JST から 2022/6/5 (日) 14:00 JST まで

  • 開催時間

    24時間

  • 競技形式

    Jeopardy 形式

  • 問題難易度について

    本 CTF は日本の CTF 初心者〜中級者を対象としたものです。そのため、近年の一般的な CTF ではほぼ見かけない初心者向けの簡単な問題も一定数出題される予定です。これを機に CTF を始めたいという方や、最近 CTF を始めた方は、ぜひそれらの問題をお楽しみください。 それと同時に、上級者でも楽しめる、少しだけ難易度が高めの問題の出題も予定しています。何度か CTF に参加したことがある方は、ぜひそれらの問題を腕試しとしてご活用いただければと思います。 また、より競技に取りかかりやすくなるように、各問題で「Beginner」「Easy」「Medium」「Hard」といった難易度を示す情報を表示しております。 ​なお、本 CTF の問題数や難易度は複数人からなるチームでご参加いただくことを想定して設定されております。 1 ~ 2 人チームで参加される場合は、競技時間内に着手・正答できる問題数が限られることが予想されますので、ぜひお誘い合わせの上ご参加ください。

他の詳細なルールについては下記ページをご覧下さい。

そもそもCTFとは?

CTF(Capture the Flag)とは、情報セキュリティに関連する問題を解いてポイントを獲得する競技性のあるゲームです。基本的には各問題の中にFlagという文字列が隠されています。Flagの形式はそのイベントによって様々です。今回は cfb4b{xxxxx} という形式でした。(xxxxxの部分には問題ごとに設定された文字列が入ります。)

「情報セキュリティに関連する問題」とざっくり書きましたが、CTFには代表的なジャンルがいくつか存在するようです。ここでは今回のイベントでも出題されたジャンルをいくつかご紹介します。

  • Web
    • Web技術に関するジャンル
  • Pwnable(Pwn)
    • 読み方はポウナブル(ポウン)
    • プログラムの脆弱性を突いてサーバーを乗っ取る問題が出題されるジャンル
    • 言葉の由来はネットスラングだとか。「own(勝利する)」のtypoらしいですね。
  • Reversing(Rev)
    • リバースエンジニアリングに関するジャンル
  • Cryptography(Crypto)
    • 暗号技術に関するジャンル
    • CTF初心者が一番取っ付きやすいジャンルな気がする(私感)

上述の他にも様々な問題があるようです。今回のイベントでは「Misc」という『その他』のようなジャンルもありました。

また、競技形式にもいくつかパターンがあるようです。今回は「Jeopardy形式」という運営から出題される問題を解いてポイントを獲得し、最終獲得ポイントで競い合うという形式でした。昨今開催されているオンラインCTFイベントはほぼこの形式のようです。他にも各チーム間で攻防を行う形式(Attack & Defense)や、問題を解いた状態(例えばサーバーを乗っ取っている状態)をキープし続けることでポイントが増える形式(King of the Hill)などがあるようです。

以下のように常設のCTFが遊べるサイトも存在します。興味を持たれた方は是非遊んでみてください。

唯一解けた問題のWrite Up

CTFには模範解答というものが存在しません。参加者の数だけ解き方はあり、多くの参加者の方がWrite Upという自分の解法を載せる記事を書いています。Write Upはゴリゴリのネタバレなので閲覧にはご注意ください!

お恥ずかしながら今回私が自力で解けた問題は1問だけでした。Write Upを書くほどでも無いか。。と思ったのですが、これからCTFの勉強をしてもっともっとWrite Upを書けるように頑張るぞ!という意思表示も込めて今回は書くことにしました。生暖かい目で見てやってください。

  • [crypto] CoughingFox

problem.py

from random import shuffle

flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"

cipher = []

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

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

output.txt

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]

『CoughingFox』はcryptoジャンルの一番易しい問題です。超初心者向け問題ということもあり、cryptoジャンルなのに暗号化技術に関する知識は全く必要ありません。

「きつねさんが食べ物を探しているみたいです。」という謎のヒントと共に上記2ファイルが提供されました。

pythonで書かれたプログラムでflagが暗号化されているようです。output.txtに記載されたcipherを復号することでflagがゲット出来そうですね。

problem.pyのfor文以下を見てみると、flagの各文字のバイトコードに +1 → ^2 → +i(元の文字位置) を行い、それらの文字をシャッフルして出来た文字の配列がcipherのようです。

最後にシャッフルされているため i(元の文字位置) は分かりませんが、cipherの各文字コードから i を減算することで平方数が出てきそうな気がしました。

その後出てきた文字コードを文字に変換したり順番を並び替えるとflagが出てきました。実際に書いたコードは以下です。

ans.py

import math
import numpy as np

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]

cleartexts = np.zeros((len(cipher), 2))

for i in range(len(cipher)):
    for j in range(len(cipher)):
        sqr = math.sqrt((cipher[i] - j))
        cleartext = sqr - j
        if float.is_integer((cleartext)):
            cleartext = int(cleartext)
            # 答えを入れる
            cleartexts[i][0] = j
            cleartexts[i][1] = cleartext

# 並び替え
index = np.argsort(cleartexts[:,0])
sorted = cleartexts[index,:]

# 文字列変換
ans_str = ""
for i in range(len(sorted)):
    ans_str+=(chr(int(sorted[i][1])))

print(ans_str)

他の方々のWrite Upを見るともっと綺麗に書かれているものばかりでした。。。CTFの勉強を通して綺麗で簡潔なコードを書く意識もしていきたいです。

最後に

今回はほぼ無策で散々な結果となってしまいましたが、SECCON Beginners CTF 2022に参加したことでCTFイベントの雰囲気を感じることが出来ました。

次回参加までには常設CTF問題をいくつか解いたりハリネズミ本を読んだりして勉強します!もっともっとWrite Up書けるように頑張ります!

もし本記事でCTFに興味を持たれた方がいらっしゃれば幸いです。私と一緒に頑張りましょう!

SECCON Beginners CTFは年に一度のようですが、CTF未経験者向けイベントとしてライブイベントやワークショップの開催も今後予定されているようです。是非チェックしてみてください。

また、メインイベントであるSECCON CTF 2022予選は10月に開催予定とのことです。こちらもチェックしておきたいですね。

以上、べこみんでした。