feature image

2024年5月5日 | ブログ記事

睡眠を犠牲に戦った CPCTF 2024 参加記

こんにちは!!!24B の「りすりす/TwoSquirrels」ですよ!!!はい!その通り!僕は新入生です!!!(うるさいですか、ごめんなさい。今やめますね)
競プロと CTF を組み合わせた traP 主催のコンテスト「CPCTF 2024」に参加したのでその記録を残そうと思います。
CPCTF の詳細はここに乗ってます。
https://trap.jp/post/2204/

おはようございます。一日目が始まります

僕は競プロは普段からやっていますが CTF は初めてなのでとてもわくわくしていました。
CPCTF 2024 は土日に開催されました。コンテスト開始は 2024/04/20 10:00 で、それより前に起きて準備は万全かと思っていました。
はい、鋭い皆さんなら分かると思いますがこの書き方をするということは何かがありますね……
10:00 になりコンテストが始まったので、まずは競プロの簡単な問題を解こうとしました。

[PPC/NEWBIE] About half

正答者数: 92, 得点: 10/10, 提出時間: 2024/4/20 11:35:22

2 変数を受け取り場合分けをするだけなはずでした……
やるだけ~と思って書いてローカルのサンプルのテストを通して提出したら CE (Compile Error)。

CPCTF 2024 の競プロ問題のジャッジは YukiCoder が使われていたのですが、なぜかローカルでは動くのにジャッジ環境だけ CE になる現象が発生して、コンパイルエラーも C++ 特有の原因が分からないエラーで困っていました……
色々原因を調べると YukiCoder の GCC (C++ のコンパイラの一つ) のバージョンが低くバグが存在したのが原因だったらしいです。#pragma GCC の行をコメントアウトすると無事正解できました。この原因究明に一時間以上を費やしてしまいました……

解答コード

[PPC/NEWBIE] Compound Word

正答者数: 72, 得点: 10/10, 提出時間: 2024/4/20 12:00:03

制約が小さいので、普通に全部試せばよさそうです。C++ で std::set<std::string> を使うことで楽に全通りを重複なく記憶することができるので、これを使います。
(実は問題の誤読をして一回ミスりました)

解答コード

[Web/NEWBIE] Typing game

正答者数: 124, 得点: 10/10, 提出時間: 2024/4/20 12:11:54

とりあえず開発者ツールを開きソースを見てみると、フラグが書いてありました。/main.js を見ても同じフラグがソースコードに直に書かれています。
他にも、コンソールから clearTimeout(timeout); を叩いてゆっくりタイピングしてみたり、changeScene("game-clear"); を叩いてみたりするとクリアでき、フラグが見れます。

[Crypto/NEWBIE] Substitution

正答者数: 90, 得点: 10/10, 提出時間: 2024/4/20 12:45:16

問題文そのものが暗号になっていますが、おそらくこれは単一換字式暗号と呼ばれるアルファベットを置き換えただけの暗号なので、頻度分析などをすることで解けそうです。
まず最後の ETEIBCPCTF なので、IJPT から始まることになり、THE だろうと推測できます。すると EKRTIUCRYPTO っぽい……のように探っていくと、問題文が復号できます。

Well done! Solving this cryptogram requires both skill and patience. You've demonstrated exceptional acumen and perseverance. Bravo for cracking the code and unlocking its secrets! CPCTF{hello_crypto_world}

[OSINT/NEWBIE] mokomoko

正答者数: 97, 得点: 10/10, 提出時間: 2024/4/20 13:04:00

写真を見ると花畑のようですが、奥にゴルフ場が見えます。これだけだとよくわからないので特徴的な花を Google 画像検索にかけてみると……ありました。ひたち海浜公園という所らしいです。

[Reversing/NEWBIE] peeping

正答者数: 79, 得点: 10/10, 提出時間: 2024/4/20 13:07:30

実行ファイルを実行してみると、フラグを当てろと言われるだけで何もわかりません。strings コマンドでバイナリのテキストを全列挙してみるとフラグが出てきました。

[Shell/NEWBIE] netcat

正答者数: 101, 得点: 10/10, 提出時間: 2024/4/20 13:10:22

nc コマンドを叩いてもいいですが、http://shell-netcat.web.cpctf.space:30010/ にブラウザでアクセスしてもフラグが手に入りました。

[OSINT/NEWBIE] omu-napo

正答者数: 36, 得点: 10/10, 提出時間: 2024/4/20 13:21:10

EXIF 情報を確認してみると、GPS のデータが残っているので Google マップで店舗名を調べればフラグが手に入ります。

[OSINT/EASY] Doctor yellow

正答者数: 69, 得点: 76.77/76.77, 提出時間: 2024/4/20 14:13:16

ドクターイエローが走る線路を調べて、Google マップでその線路を辿りながら川を調べると、多摩川が写真と一致していました。座標からフラグが得られます。

[Reversing/EASY] Just reversing?

正答者数: 60, 得点: 106/106, 提出時間: 2024/4/20 14:26:21

暗号化のプログラムとそのプログラムで暗号化されたフラグが渡されます。ソースコードを読んでみると文字列を 4 bit 毎に区切ってひっくり返しているので、同じことをもう一度すれば復元できそうです。
与えられた C 言語のプログラムをそのまま使ってもなぜか上手く復元できなかったので、自分で JS でプログラムを書いて復元しました。

const fs = require("fs");
const flagEnc = fs.readFileSync("./flag_enc.txt", "hex");
const flag = flagEnc.split("").reverse().join("");
console.log(Buffer.from(flag, "hex").toString());

[Web/EASY] Let's buy some array

正答者数: 67, 得点: 99.02/99.02, 提出時間: 2024/4/20 14:35:08

バックエンドのソースコードが与えられるので見てみると PHP で書かれていて、/src/purchase.php を見てみると eval とありやばいです。Web のフォームから任意コードが実行できそうですが、そのままだと文字列が数字しか書けないので開発者ツールからフォームの type="number"type="text" とでも書き換えてやってから getenv("FLAG");// を送ると、フラグが見れました。

[Reversing/EASY] Number Guesser

正答者数: 52, 得点: 133.09/133.09, 提出時間: 2024/4/20 15:48:43

実行ファイルしか渡されませんが、strings コマンドを使ってもフラグは見つかりません。おそらくプログラムでフラグを動的に構築しているので、その関数をどうにかして直接呼び出すか、数字を当てるかしかなさそうです。僕は objdump コマンドや adb コマンドに慣れていない上アセンブリも読めないので IDA という逆アセンブルソフトをインストールして確認すると、以下のような判定ロジックが見つかるので

数字は 17704 と分かります。実行してこれを入力するとフラグが得られます。
この程度の整数ならローカルで 0 から順に全探索して調べても見つかりそうです。

[Pwn/NEWBIE] Attack! Attack! Win!

正答者数: 80, 得点: 10/10, 提出時間: 2024/4/20 15:53:13

ソースコードが渡されるので読んでみると、どうやら負の数の入力の対策ができていない上 3 で関数のアドレスまで分かるので、差のバイト数を計算して -2 を送ると、フラグがでてきました。

[Forensics/EASY] Register

正答者数: 19, 得点: 289.68/289.68, 提出時間: 2024/4/20 17:21:38

問題文で「packetをcapture」と言ってるので Wireshark をダウンロードして見てみますが、どうやらこれば USB 入力のキャプチャーのようです。Wireshark ってネット通信以外のキャプチャーも取れるんだと驚きながら色々ググってみるとキーボード入力とコードの対応表が見つかりました。この表をもとに JS で変換プログラムを書いてあげて

const keyboard = [
  [],
  [],
  [],
  [],
  ["a", "A"],
  ["b", "B"],
  ["c", "C"],
  ["d", "D"],
  ["e", "E"],
  ["f", "F"],
  ["g", "G"],
  ["h", "H"],
  ["i", "I"],
  ["j", "J"],
  ["k", "K"],
  ["l", "L"],
  ["m", "M"],
  ["n", "N"],
  ["o", "O"],
  ["p", "P"],
  ["q", "Q"],
  ["r", "R"],
  ["s", "S"],
  ["t", "T"],
  ["u", "U"],
  ["v", "V"],
  ["w", "W"],
  ["x", "X"],
  ["y", "Y"],
  ["z", "Z"],
  ["1", "!"],
  ["2", "@"],
  ["3", "#"],
  ["4", "$"],
  ["5", "%"],
  ["6", "^"],
  ["7", "&"],
  ["8", "*"],
  ["9", "("],
  ["0", ")"],
  ["[Enter]", "[Shift+Enter]"],
  ["[Escape]", "[Shift+Escape]"],
  ["[Backspace]", "[Shift+Backspace]"],
  ["[Tab]", "[Shift+Tab]"],
  ["[Space]", "[Shift+Space]"],
  ["-", "="],
  ["^", "~"],
  ["@", "`"],
  ["[", "{"],
  [],
  ["]", "}"],
  [";", "+"],
  [":", "*"],
  ["[半角/全角]", "[Shift+半角/全角]"],
  [", ","<"],
  [".", ">"],
  ["/", "?"],
  ["[CapsLock]", "[Shift+CapsLock]"],
  ["[F1]", "[Shift+F1]"],
  ["[F2]", "[Shift+F2]"],
  ["[F3]", "[Shift+F3]"],
  ["[F4]", "[Shift+F4]"],
  ["[F5]", "[Shift+F5]"],
  ["[F6]", "[Shift+F6]"],
  ["[F7]", "[Shift+F7]"],
  ["[F8]", "[Shift+F8]"],
  ["[F9]", "[Shift+F9]"],
  ["[F10]", "[Shift+F10]"],
  ["[F11]", "[Shift+F11]"],
  ["[F12]", "[Shift+F12]"],
  ["[PrintScreen]", "[Shift+PrintScreen]"],
  ["[ScrollLock]", "[Shift+ScrollLock]"],
  ["[Pause]", "[Shift+Pause]"],
  ["[Insert]", "[Shift+Insert]"],
  ["[Home]", "[Shift+Home]"],
  ["[PageUp]", "[Shift+PageUp]"],
  ["[Delete]", "[Shift+Delete]"],
  ["[End]", "[Shift+End]"],
  ["[PageDown]", "[Shift+PageDown]"],
  ["[→]", "[Shift+→]"],
  ["[←]", "[Shift+←]"],
  ["[↓]", "[Shift+↓]"],
  ["[↑]", "[Shift+↑]"],
  ["[NumLock]", "[Shift+NumLock]"],
  ["/"],
  ["*"],
  ["-"],
  ["+"],
  ["[Enter]"],
  ["1", "[End]"],
  ["2", "[↓]"],
  ["3", "[PageDown]"],
  ["4", "[←]"],
  ["5"],
  ["6", "[→]"],
  ["7", "[Home]"],
  ["8", "[↑]"],
  ["9", "[PageUp]"],
  ["0", "[Insert]"],
  [".", "[Delete]"],
];
const input = "0206021302060217020902300232005000090059005c005e2087001a005c005d20870006005c0061005f0018001500200007";
console.log(
  input.match(/..../g)
    .map((hex) => parseInt(hex, 16))
    .map((id) => keyboard[id % 256]?.[id >> 9] ?? `[${id.toString(16)}]`)
    .join("")
);

実行してみると CPCTF{}[←]f146[2087]w45[2087]c497ur3d が得られるので、これを元にフラグを復元できました。

[Web/EASY] Read Novels

正答者数: 87, 得点: 50/50, 提出時間: 2024/4/20 17:24:56

バックエンドのソースコードが与えられるので見てみると、パスを構築している所に好きな文字列を入れられるのが怪しいです。試しにディレクトリを ../ で遡ってみるとすべてのファイルの中身が見れてしまうので、フラグも見れました。

[Forensics/EASY] white has much information

正答者数: 60, 得点: 125.13/125.13, 提出時間: 2024/4/20 17:39:26

空白文字のみの文字列には見覚えがあって、すぐに Whitespace 言語だと分かったので、オンラインのインタプリタで実行するとフラグが得られました。

[Shell/EASY] veeeeeeery long text

正答者数: 66, 得点: 83.92/83.92, 提出時間: 2024/4/20 17:41:51

ssh 接続をすると、64 文字ごとに改行で区切られたとても長いテキストファイルが置いてあるので、とりあえず grep CPCTF flag.txt とかをするとフラグが見つかりました。

[OSINT/EASY] leaving

正答者数: 44, 得点: 174.09/174.09, 提出時間: 2024/4/20 19:51:44

電光掲示板や新幹線乗換の存在などから浜松駅と分かるので、そこから Yahoo! 乗換案内アプリで調べると現在時刻より前に終点駅の熱海についてしまうので、折り返し時間を適当に見積もって逆方向に調べるのを何度か繰り返すと目的の駅が分かりフラグが作れました。

[OSINT/MEDIUM] Great view

正答者数: 50, 得点: 146.27/146.27, 提出時間: 2024/4/20 20:45:43

とりあえず Google 画像検索に投げてみると卯辰山公園見晴らし台だとわかり、聖地巡礼のブログからゲームは「Link!Like!ラブライブ!」だと分かります。これをググるとピクシブ百科事典が出てきてリリース時間が書いてあるので、フラグが分かりました。

[PPC/EASY] Time is money

正答者数: 25, 得点: 244.76/244.76, 提出時間: 2024/4/21 0:59:52

競プロがしたくなったのでやります。
時間と金の二要素がありますがよく考えると時間の価値を金に変換して考えれば金だけになりダイクストラ法が使えます。最後に時間を切り上げ除算をします。

解答コード

[PPC/EASY] Old Maid

正答者数: 35, 得点: 191.89/191.89, 提出時間: 2024/4/21 1:14:29

うまくシミュレーションをします。
途中の要素をすぐに消せるように連結リストを使い、数とそのイテレータの連想配列を持てばできました。

解答コード

[PPC/EASY] CPC To F

正答者数: 40, 得点: 174.09/174.09, 提出時間: 2024/4/21 1:43:41

後ろから見て貪欲法をしましたが、実は前から見ても解けるらしいです。

解答コード

[PPC/EASY] Balanced Choice

正答者数: 32, 得点: 211.42/211.42, 提出時間: 2024/4/21 2:09:40

どう見てもナップザック DP です。石が二種類あるので DP を二本持って最後に答えを探せばよさそうです。

解答コード

[Pwn/EASY] CPCT......

正答者数: 61, 得点: 114.68/120.72, 提出時間: 2024/4/21 2:31:04

さらっと printf と書いてあるのに気付かずヒントを一つ開けてしまいました……
%99d とか入れれば 99 文字になってくれます。

[OSINT/MEDIUM] Patlite

正答者数: 38, 得点: 186.77/196.6, 提出時間: 2024/4/21 3:06:38

ヒントを一つ開けてしまいました。ゆりかもめに注目するらしいので、その条件で大きな駅を探すと新橋駅が見つかり、そのあたりの座標を色々試すと正解できました。

[OSINT/EASY] Dokoda?

正答者数: 40, 得点: 255.09/255.09, 提出時間: 2024/4/21 3:11:59

fukushin が怪しいです。ググると福しんというチェーン店が出てくるので、店舗情報 から最寄り駅を全探索すると正解できました。

疲れたので寝ます。

ふつかめです

解けそうな競プロ問があと 1 問あったのでそれから解きます。

[PPC/MEDIUM] Car Flow

正答者数: 21, 得点: 270.5/270.5, 提出時間: 2024/4/21 10:27:11

実験すると 01 の数は常に変わらなそうと予想でき、じっくり考えてみると渋滞を表していることが分かります。(これがタイトルの伏線回収になっていることは後で気がつきました)
さらに実験をすると周期は n でそのうちシグマの中が 1 になるのは 1 の数と 0 の数の少ないほうになることが予想できるので、その確率を求めたら正解できました。

解答コード

[Forensics/MEDIUM] which is true flag

正答者数: 30, 得点: 25.51/255.09, 提出時間: 2024/4/21 11:33:28

ほとんど同じファイルばかりで色々調べてもよくわからず、ヒントを開けると正しいアドレスを調べる必要があることが分かりました。dig コマンドを知らなかったので全てのヒントを開けてしまいました……

[OSINT/HARD] Electric Town

正答者数: 15, 得点: 50/500, 提出時間: 2024/4/21 11:44:48

この問題は一日目から考えていました。
ぱっと見で秋葉原のラジオ会館前ということは分かりますが、時間はどこにも書いてありません。
NieR:Automata の旗から大体 2023 年の 08 月中旬以降ということが分かり、ソフマップのシャッターが閉まっていることから朝から 11:00 までということは分かります。
天気予報が書いてあるのでその時期の天気予報の履歴を見ながら日にちを絞り、細かな時間までは分からないので頑張って全探索をしますが正解が見つかりません……
他の怪しい日も全探索したいですが流石に手がつかれました。ルールを見てみると鯖に負荷をかけてはいけないというのはありますが自動化は禁止されていなかったので、手で全探索するのと同じくらいの速度で自動化します。
これで怪しい日を色々調べましたが見つからず、自動化禁止のルールが加えられました。
あきらめて二日目にヒントを全て開けると、雲とライブカメラを使うとあり、流石に無理~~~となりました。

[Misc/EASY] turning over

正答者数: 26, 得点: 25.94/259.38, 提出時間: 2024/4/21 14:34:18

Blender の使い方を知らなかったのでヒントを全て開けてしまいました……

[Pwn/EASY] The sky's the limit

正答者数: 35, 得点: 26.82/268.23, 提出時間: 2024/4/21 14:44:34

gets 関数が怪しいということしか分からなくてヒントを全て開けました。

[OSINT/MEDIUM] Forbidden Code 1

正答者数: 28, 得点: 32.84/328.36, 提出時間: 2024/4/21 14:55:44

面白そうでしたがとても難しいのでヒントを全て開けました。

[Misc/NEWBIE] 参加者アンケート

正答者数: 31, 得点: 10/10, 提出時間: 2024/4/21 15:26:31

アンケートを開くとフラグが貰えました。

終了!!!お疲れ様でした!!!

新入生 3 位になれました!!!わーい
CTF は初めてでしたが面白かったです。
全探索に関しては、ごめんなさい!!!
運営の方々ありがとうございました!

TwoSquirrels icon
この記事を書いた人
TwoSquirrels

24B/工学院のプログラミング大好きな「りすりす」だよ。 パソカタやアニメが好きだが運動や暗記は嫌い。 C++ を CLion で書いたり VS Code で Web 書いたりしている。 移動中にスマホで Emacs でコーディングすることもある。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2021年5月16日
CPCTFを支えたインフラ
mazrean icon mazrean
2019年4月22日
アセンブリを読んでみよう【新歓ブログリレー2019 45日目】
eiya icon eiya
2023年4月29日
CPCTF2023 PPC作問陣 Writeup
noya2 icon noya2
2023年4月21日
CPCTFを開催します
noc7t icon noc7t
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記