はじめに
本記事は、技術書典14やBOOTHで のみぞうさん (@nomizooone) が制作されている「ナゾトキCTF-虹色の研究-」に関するWriteupです。
クリアしていない方はネタバレにご注意ください。
ナゾトキCTF-虹色の研究- とは
ナゾトキとCTFを組み合わせた初心者向けCTFイベントです。購入すると手に入るクリアファイルとペーパーがものすごく巧妙に作りこまれていて感動します。これらを物理的に使うナゾトキもあり、物をいじりながら閃いたときの爽快感も味わえる、とても楽しめるコンテンツです。
Jeopardy(ジョパディ)形式でおこなれます。
ナゾトキCTFのTwitterハッシュタグ: #nazotokiCTF
(2023/05/31時点)
CTFイベント開催期間は 2024年1月3日13:30 までなのでご注意ください。
クリアファイルとレジストレーションコードが書かれたペーパーは、下記サイトで購入できます。
1st Challenge
1st Challenge 赤:Reversing
問題
情報収集
-
問題にあるコマンドで問題サーバに接続すると”Enter your name:”と名前を求められる。”DonGury”と入力するとMineNumberは712だと返ってきた。これが777になる文字列を探せばよい。
nc
┌──(kali㉿kali)-[~] └─$ nc xxx.xxx.xxx.xxx 12345 ************************ MineNumber Search Engine ************************ Enter your name: DonGury Your MineNumber is : 712 Don’t mind. I'm looking for the 777.
-
ダウンロードした “1_Reversing” に対して、コマンドで怪しげな平文が無いか検索すると、flag.txtという文字が見つかった。おそらくコマンドで接続した先にflag.txtがあってその中にフラグがあると思われる。
strings
nc
┌──(kali㉿kali)-[~/work/nazotoki_7color/1st_red] └─$ strings 1_Reversing | grep -E "((nazo)|(777)|(flag))" flag.txt t mind. I'm looking for the 777. flag
逆アセンブル
-
Ghidra 10.2.2をインストールする (名前だけは聞いたことあったけど初めて使います!)
-
1_Reversingを読み込む
-
“Symbol Tree”から関数を選択しデコンパイルコードを確認する。
main
-
デコンパイルしたコードを見ると、 が () になる入力文字を探せばflagを出力してくれそう。
local_64
777
0x309
// デコンパイルしたコード while ((local_60 < 0x40 && (local_58[(int)local_60] != 10))) { local_64 = local_64 + (int)local_58[(int)local_60]; local_60 = local_60 + 1; } printf("Your MineNumber is : %d\n",(ulong)local_64); if (local_64 == 0x309) { puts(flag); puts("You are the luckiest!"); }
-
なおデコンパイルしたコードには “You are Mr. Polmes. Your crypto key is ‘VIGENERE‘. but, This is not Flag!” という怪しげな記述があった。後で使えるかもしれないので覚えとく。
デコンパイルコードから結果が777になる文字列を考える
- デコンパイルしたコードから、入力文字を1文字ずつにキャストして加算しその合計がになればよいということがわかる。
int
777
- ASCIIコードでは “d” が “100”, “M” が “77” なので, “dddddddM” を入力すればよさそう。
nc
コマンドで問題サーバに接続し”dddddddM”と入力すると無事にフラグが取れた!
1st Challenge 橙:Crypto
問題
ポームズの番号を調べる
-
「1st Challenge 赤:Reversing」のコード内に、”You are Mr. Polmes. Your crypto key is ‘VIGENERE‘. but, This is not Flag!” という記述があったのでこれが使えそう。
-
問題文の”FWTS ZSEHVQ TS XSKEZ PG WHMU HZAA.WHMU XJPG WRX LWZZ OH AS ICVSA HRWL.”が暗号化された文字列で、”VIGENERE”が暗号キーとして復号してみる。
復号
-
スペース や “.” が入っていたので、アルファベットを何かしら変換して読むんじゃないかなぁとあたりをつけてみたがわからない…
-
“VIGENERE”がヒントなのかな?なぞなぞ?
-
…全くわからん。保留。
-
(数時間後) Google先生なら “VIGENERE” をご存じか?と思ってググるとヴィジュネル暗号というものがあることを知った。知らなかった…
-
ヴィジュネル暗号を解くとフラグが判明!! (自分でコードを書かなくてもサッと変換できるサイトはありそうですねw)
# ヴェジェネル暗号で暗号化された文字列を復号するサンプルコード enc_code = "FWTS ZSEHVQ TS XSKEZ PG WHMU HZAA.WHMU XJPG WRX LWZZ OH AS ICVSA HRWL." key = "VIGENERE" A_ASCII = ord('A') ALFABET_NUM = ord('Z') - (A_ASCII - 1) dec_code = "" i_key = 0 for i in range(0,len(enc_code)): if enc_code[i] == " " or enc_code[i] == ".": dec_code = dec_code + enc_code[i] next else: tmp_num = ord(enc_code[i]) - (ord(key[i_key]) - A_ASCII) if tmp_num < A_ASCII: tmp_num = tmp_num + ALFABET_NUM dec_code = dec_code + chr(tmp_num) i_key = i_key + 1 if i_key >= len(key): i_key = 0 print(dec_code)
1st Challenge 黄:Forensics
問題
-
世界一かわいい犬が虹色の布に巻かれて宇宙位置かわいくなった瞬間ニャ。
-
ここでデイジーちゃん登場!かわいい!!!
-
3_Forensics.pngというデイジーちゃん画像をダウンロードできる。これは良いサービス。
デイジーちゃん画像を解析してみる
-
拡大してくりくりお目目などを見てみたが ただただ可愛かった。
-
exiftoolをインストールして情報を見るも怪しい情報はなく
-
stringsコマンドでも怪しい情報はなく
-
binwalkをインストールして情報を見てみると…おや? PNGがもう1枚埋め込まれている?
┌──(kali㉿kali)-[~/work/nazotoki_7color/1st_yellow] └─$ binwalk -e 3_Forensics.png DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 PNG image, 1000 x 1333, 8-bit/color RGB, interlaced 78 0x4E Zlib compressed data, best compression 2127564 0x2076CC PNG image, 115 x 20, 8-bit/color RGB, interlaced 2127642 0x20771A Zlib compressed data, best compression
-
splitコマンドでバイナリ分割すると、フラグが取れた!!
┌──(kali㉿kali)-[~/work/nazotoki_7color/1st_yellow] └─$ split -b 2127564 3_Forensics.png --additional-suffix .png
1st Challenge 緑:Web
問題
チャッピーの自己紹介ページ
-
おしゃれなページ
-
API仕様書も見れる。チャッピーにkeyとquestion(番号)を付けてAPI発行すると答えが返ってくるらしい。
-
とりあえずAPIを実行してみたいけどAPIキーがわからない。
-
チャッピーの自己紹介ページのAboutをじっくり読むと怪しげな情報がある。
- 16番の「履歴」というキーワードがヒントになりそう。
- 17番は後で使うかも知れないので覚えておく。
APIキーを探す
-
API仕様書のあるGitHubの変更履歴には見当たらなかった
-
チャッピーの自己紹介ページのソース(HTML)内にも無かった
-
それ以外にも履歴…履歴…とブツブツ言いながら、別問題で提供されたパケットキャプチャデータを漁ったり、「チャッピー SF映画」でググってチャッピー(2015年)という映画があることを知ったり、ChatG[ピーー]T先生に「チャッピーという猫型AIのAPIキーを教えて」という無茶プロンプトをふっかけたり、「APIキーを忘れたPolmesさん」を装ってチャッピーにメールするも無視されるというソーシャルエンジニアリング失敗の巻を経験するなど、成果なし…
ポイント消費無しのヒントを見ちゃう
-
作者である のみぞうさん より「今回は得点消費しないヒントも用意してますのでこっそり見てもいいのよ」というありがたい情報を入手したので、得点消費しないヒントをチラ見すると、なんか「ロボット」が強調されてる。
-
「ロボット」で「あっ!」となりました。つい最近業務で触ったあいつ、robots.txt か!?
-
ブラウザのアドレスバーに を追加するとフラグが出ました!!
/robots.txt
1st Challenge 青:Network
問題
5_Network.pcapng(パケット)の内容確認
-
“GET /” に対する応答をみると secret/flag.html に何かありそう
Line-based text data: text/html (10 lines) <!DOCTYPE html>\r\n <html lang="ja">\r\n <head>\r\n <meta charset="UTF-8">\r\n <title>青</title>\r\n </head>\r\n <body>\r\n <a href="secret/flag.html">secret</a>\r\n </body>\r\n </html>\r\n
-
“GET /secret/flag.html” に対する応答パケットを見る。初回アクセスの応答は 401 Unauthorized が返っている。”WWW-Authenticate”ヘッダ情報より Basic認証でrealmは”Restricted Content”であることがわかる。
Hypertext Transfer Protocol HTTP/1.1 401 Unauthorized\r\n : WWW-Authenticate: Basic realm="Restricted Content"\r\n :
-
パケットを読み進めていくと、その後何度か認証を試行し最終的に “Authorization” ヘッダの”Credentials”に正しい認証情報を与えて200OKが返っている。bodyに書かれた情報より、”Credentials”に書かれた情報がフラグであることわかる。
(リクエスト) Hypertext Transfer Protocol GET /secret/flag.html HTTP/1.1\r\n : Authorization: Basic bmF6b3Rva2lDVEY6T0FVVEg=\r\n Credentials: ※ここの文字をフラグ形式にするとよい※ :
(レスポンス) <!DOCTYPE html>\r\n <html lang="ja">\r\n <head>\r\n <meta charset="UTF-8">\r\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\r\n <title>blue</title>\r\n </head>\r\n <body>\r\n The basic flag is in the password on this page.\r\n </body>\r\n </html>\r\n
1st Challenge 藍:OSINT
問題
画像検索する
- Googleレンズで検索すると見つかる。バンド名を全部大文字にすればフラグ完成!!
1st Challenge 紫:Misc
問題
この暗号文は何?
-
文字はどうやら1行で構成されているもよう。211文字…わからん…
-
ブラウザの横幅を変えたり目を細めたりしたが、おぼろげながらも何も浮かんでこない。
-
ぜんっっっぜんわからないのでダメ元でこのまんまググってみる。するとブレインファック(Brainf**k)という8命令チューリング完全プログラミング言語らしいことが判明。知らなかった…
- 解析してくれるサイトがあったのでそこに放り込んでみるとフラグ判明!!
2nd Challenge
2nd Challenge クロスワード
問題
クロスワードパズルを埋めて番号順にならべる
- 1st Challengeが全て解けていればフラグがわかる問題
2nd Challenge フリーな暗号
問題
情報収集
-
提示されたURLへアクセスすると、謎の暗号文とPassword入力フォームがある。
-
謎の暗号文を解く必要がありそうだけど、何も思いつかない。ナメック語かな。
-
いくら考えてもわからないのでGoogleレンズで画像&追加キーワードに「暗号」を入れて検索すると、フリーメイソンの「ビッグベン暗号」であることがわかった。知らなかった…
-
ビッグベン暗号はとても上手に表現された暗号であることが理解でき、すぐ覚えれました。
暗号文の解読とナゾトキ
-
ビッグベン暗号を解読すると「ANGOU NO ITO TANI ORI SEYO」
-
ペーパーを開いて糸の直線を谷折りすると、割り印みたいに隠されていた文字がでてくる。「?(ねこマーク)アワセ△(三角マーク)ニジイロジュンニヨメ」
-
ペーパーとクリアファイルにはそれぞれ同じ絵柄のチャッピー(自称超高性能ネコ型AIロボット)が描かれている。それがぴったり合わさるようにペーパーをクリアファイルに入れると、クリアファイル裏面に印刷された〇や△のマークがクロスワードパズル上にぴったり合う!
-
△部分の文字を虹色の順に繋げるとPasswordが完成する。
-
完成したPasswordで認証するとフラグ入手!!
-
さらに最後のフラグにつながるナゾ「final.zip」がDOWNLOADできた。
Final Challenge
Final Challenge 虹の研究
問題
「2nd Challenge フリーな暗号」で入手した final.zip を確認
-
解凍時にパスワードを求められる…。そういえば「2nd Challenge フリーな暗号」の認証後ページにはこんなことが書いてあった。「問い合わせ先」で思いつくのは、チャッピーのプロフィールページに書かれていたメールアドレスかAPIの2つ。にゃ~ん?
-
チャッピーにメールで問い合わせるも「でもごめんニャ。チャッピーへのお問い合わせはAPI経由でお願いしているのニャ。」と丁重にお断りされる。やはりAPIキーを探さないとダメなのかなぁ。
-
チャッピーは1日1回しかメール返信してくれないのか(?)塩対応だし、APIキーを入手するしかないもよう。改めてチャッピーのプロフィールページを訪れる。まってろチャッピー。
APIキー探索
-
「1st Challenge 緑:Web」のときにAPIキーを探して見つからなかったが、見落としが無いかもう一度確かめる。
-
まずAPI仕様書があるGitHub上で見落とし無いか確認する。
-
“Create api.key”の内容から無事APIキーを入手
APIを使ってチャッピーにリクエストを投げる
-
「1st Challenge 緑:Web」からチャッピーのプロフィールページに移動し、入手したAPIキーを含むURIでチャッピーにリクエストをぶん投げると以下のような回答が返ってきた。
{ "answer": "Number not found" }
-
質問番号が合っていない模様。ここで「1st Challenge 緑:Web」で気になっていた 17番の情報が 使える。質問番号は虹の色の数、つまり 7 を指定すればよい。
-
正しい質問番号でAPIを発行するとパスワード情報が手に入った。
入手したパスワードを使って final.zip を解凍
問題文から最後のフラグをあぶりだす
- 問題文に書かれたCTFのジャンル名を虹色で読みかえる。
- その虹色と横に書かれた数字に従って、ペーパーとクリアファイルを動かす。
- クリアファイル表紙のポームズくんの虫眼鏡(透明)に、ペーパー裏表紙の英語の文字が写るようにクリアファイルとペーパーを配置する。
- 問題文の虹色と数字に従って、クリアファイル表面右端中央あたりの指マークをペーパー裏表紙の虹色線のメモリ位置に合わせる。
- ポームズくんの虫眼鏡に出てくる文字を順番に繋げていくと文字列が完成する。
- 問題文に書かれている謎のアイコンの意味は「1st Challenge 藍:OSINT」の問題文の中に答えがある。それは「鏡」。アイコンがついている箇所の文字を鏡で映した文字で置き換えると最後のフラグが完成!!
Final Challenge Congratulations
-
Final Challenge 虹の研究のフラグをSubmitすると、Congratulationsステージが出現
-
Congratulations内のエピローグにはボーナスフラグが書かれています。200ポイントもらえるので忘れずにSubmitしましょう!!
原文始发于@DonGury:ナゾトキ x CTF? -虹色の研究- WriteUp