TsukuCTF 2023 Writeup

今年も OSINT の季節がやってきた

はじめに

TsukuCTF 2023 にチーム TsukuShiGuesser のメンバー settyan117 として参加しました。初回の TsukuCTF に参加して感動したあのときから Geoguessr タイプの OSINT が大好きになったぼくにとっては、年に一度の大イベントです。

結果、チームとしては 27 時間と少しで全完、2 位を獲得できました。1 位の Wani Hackase の速さは異常です。勝てません。

以下、解くのにそれなりに関わった問題の Writeup というか解いてたときの思考を書いていきます。

注:見づらくてごめん。初めの方は出先で解いてたので、スマホのスクショばっかりです。

<2023/12/11 17:41 追記>

content_sign のジャンルが OSINT になっていた点と、一部表示が崩れていた点を修正しました。

[OSINT] 3636

ここはどこ…?
Flagフォーマットは TsukuCTF23{緯度_経度} です。
端数は少数第四位を四捨五入して小数点以下第三位の精度で回答してください。

12/9 12:20、待ちに待った TsukuCTF 2023 が開始。出先でスマホしか使えなかったので、とりあえず出ている OSINT を前から進めることにしました。 

(5?)-3636 で終わる電話番号と o.ed.jp/ で終わる URL が見える。「3636 ed.jp」で検索すると、「中瀬幼稚園(東京都杉並区)」「とうみょう子ども園(福島県会津若松市)」の順にヒット。

ストリートビューで中瀬幼稚園の周辺を見て回ってもそれっぽくない。そういえば過去回でも会津の問題見たことあるような気がするなって思いながらとうみょう子ども園の周辺を探すと、あった。

[OSINT] 3636 見つけた

イージーイージー、とか調子こいてたら Incorrect。なんで?

[OSINT] 3636 incorrect

23 をつけてませんでした。

Flag: TsukuCTF23{37.502_129.929}

[OSINT] RegexCrossword

クロスワードを解いてみて!
これを作った会社の本社の郵便番号をハイフンありで答えてね!!

[OSINT] RegexCrossword 問題

問題タイトルにもある通り、正規表現のクロスワードっぽい。解けと言われているが、出先なので解かずに解きたいね。

どうやら紙ナプキンっぽいので、「正規表現 クロスワード 紙ナプキン」で検索すると、https://tenmei.cocolog-nifty.com/matcha/2015/06/post-d9ac.html がヒット。どうやら会津大学の食堂らしい。これも会津問なのね。

Writeup 執筆時点見返すとこのページの末尾にめっちゃ答え書いてあったんですが、当時は一切気がついていなかったので「会津大学 学食 正規表現 ナプキン」で追加検索。reddit の記事 がヒットして、答えをゲット。nowhere.co.jp が本物の URL であることに気づくのに時間がかかった。

Flag: TsukuCTF23{965-0872} First blood!

[OSINT] TrainWindow

夏、騒音、車窓にて。

フラグのフォーマットは、TsukuCTF23{緯度_経度}です。
緯度経度は小数第五位を切り捨てとします。

[OSINT] TrainWindow 問題画像

手前の雰囲気、熱海周辺の車窓っぽい気がする。

そういえば、奥に見える島、まえ伊東線に乗ったときに見えた島にそっくりだな。

適当に伊豆多賀駅付近をストリートビューしてると奥の海辺のでかい建物があったので大まかには確定。それっぽいところをストリートビューで散歩してみると、問題写真の右側にある建物を見つけた(画像は Writeup 執筆時のスクショ)。

あの建物の隣の建物の正面くらいにいるので、位置を調整して、

Flag: TsukuCTF23{35.0641_139.0664}

 

参考までに昔撮った写真を引っ張り出してきたら、想像以上に近い場所で写真撮っててビビった。

[OSINT] TrainWindow 自分の写真

[OSINT] airport

つくしくんは、旅の思い出を振り返っていましたが、この写真はどこの空港かわからなくなりました。
ここはどこの空港か教えてくれませんか?
FlagフォーマットはTsukuCTF23{空港の3レターコード(IATA)}です。

[OSINT] airport 問題画像

結構市街地にある空港。市街地にある空港といえば、伊丹空港か福岡空港。

ANA のプロペラ機の就航路線で絞ろうかと思って調べたが、https://www.ana.co.jp/ja/jp/guide/inflight/service/domestic/dhc8-q400/ によると両方とも飛んでるみたい。

最終的に、プロペラの奥にある立派な橋を 2 つの空港の周りで探した結果、猪名川にかかる神津大橋と判明したので、伊丹で確定。

Flag: TsukuCTF23{ITM}

[OSINT] Yuki

雪、無音、窓辺にて。

フラグのフォーマットは、TsukuCTF23{緯度_経度}です。
緯度経度は小数第四位を切り捨てとします(精度に注意)。

[OSINT] Yuki 問題画像

定山渓温泉ってこんな感じじゃなかった?(クソデカ Guessing) 行ったこと無いけど。って思って調べてると、

[OSINT] Yuki 橋

左下に見える小さな橋の写真を見つけました 💯。でも地図にそれっぽいのないなーって思ってたら、

航空写真にしたら登場した。高山橋っていうのか。

ってこれ気づいてなかったけど、問題画像の上半分に大きい橋が写ってるやん。ということで、位置関係を鑑みてカフェサンリバーと特定。

Flag: TsukuCTF23{42.968_141.167}

[OSINT] big-statue

大きなドリアンだ!どこにあるんだろう?? フラグの形式はTsukuCTF23{緯度_経度}です。例えば、この像が東京の渋谷駅にある場合、フラグはTsukuCTF23{35.6580_139.7016}となります。

[OSINT] big_statue 問題画像

漢字が使われていて車は左側通行なので、香港かシンガポールあたりかなと予想。とりあえず Google レンズに投げると、Facebook の動画が出てきた。

ご丁寧に住所まで書いてあるじゃない。ラッキー。

シンガポールでした。そういえば、TVアニメ「宇宙よりも遠い場所」の、シンガポールが舞台のSTAGE06 「ようこそドリアンショーへ」でも、ドリアンが登場していましたね。

Flag: TsukuCTF23{1.3623_103.8872}

ここで別の予定が始まったので、一旦離脱。

[OSINT] kiZOU

ここは日本で一番のリゾート地!少し歩くと目の前に素敵な像が見えたから写真を撮ったつもりだったんだけど、見返したら端っこしか写ってない!困ったなぁ、この像についてもっと知りたかったんだけどなぁ。僕の代わりにこの像について調べてくれないか?
フラグ形式はTsukuCTF23{像を寄贈した人物の名前}です。

[OSINT] kiZOU 問題画像

16 時過ぎに予定が終わり、バ先に向かう電車の中で。

はじめライオン像か何かかと思って「au style ライオン像」で調べてみたものの、ヒットせず。Google レンズに投げると、像の正体がわかる写真が見つかった。シーサー像だったのね。ついでに、この店舗が沖縄にあるデパートリウボウ 1階 au Style NAHA であることも判明。

ここまでで 5 分程度、順調に進んだと思われたが、ここからが長かった。今回は場所ではなくて、寄贈者の名前を調べなければならないわけですが、これがまあ全然出てこない。「au Style NAHA シーサー像」「デパートリウボウ シーサー像」で検索しても情報や画質の良い画像は出てこず、Google Bard に頼ったら

[OSINT] kiZOU bardの解答

ウソです !!!
彫刻家の赤嶺正勝さんは調べた限り実在しません
結果的には寄贈者の名前とも一致しませんでした

こんなに出てこないことある? と思いながら色々探してみると、実はデパートリウボウは「パレットくもじ」という複合商業施設の一部であることに気づきます。

「パレットくもじ シーサー」で検索すると、高画質な銘板の画像が載ってる記事が出てきました。やったね!

錆びてて少し読みづらいけど頑張って読むと、寄贈者は上原清善さんとわかります。

Flag: TsukuCTF23{上原清善}

なんとかバイトが始まる前に解き終えられた。

[OSINT] stickers

この画像が撮影された場所を教えてください!
FlagフォーマットはTsukuCTF23{緯度_経度}です。
ただし、小数点4桁の精度で答えてください。

[OSINT] stickers 問題画像

21 時頃、バ先から帰宅中。

「なつかしの熱海プリン」がブラフではないと信じて、「熱海」というキーワードと共に Google レンズにぶち込むと、アメブロの記事があっさり出てきた。河原湯というらしいです。

Flag: TsukuCTF23{35.0967_139.0747}

[CRYPTO] new_cipher_scheme

I wouldn’t worry about it being decrypted because of this complicated process!

from Crypto.Util.number import *
from flag import flag


def magic2(a):
    sum = 0
    for i in range(a):
        sum += i * 2 + 1
    return sum


def magic(p, q, r):
    x = p + q
    for i in range(3):
        x = magic2(x)
    return x % r


m = bytes_to_long(flag.encode())
p = getPrime(512)
q = getPrime(512)
r = getPrime(1024)
n = p * q
e = 65537
c = pow(m, e, n)
s = magic(p, q, r)
print("r:", r)
print("n:", n)
print("e:", e)
print("c:", c)
print("s:", s)

ここで帰宅したので、パソコンが必要な crypto に取り掛かりました。

\(\text{magic2}(a)\) は総和の形に擬態していますが、これは \(2a-1\) 以下の正の奇数の総和なので、つまるところ \(a^2\) です。すなわち、

$$s = \text{magic}(p,q,r) = (p+q)^8 \bmod r$$

となり、\(p+q\) は \(s\) の平方根の平方根の平方根(の一つ)とわかります。

奇素数 \(r\) について、\(s\) の \(\bmod r\) 上の平方根は、Tonelli-Shanks アルゴリズムを使って求めることができます。SageMath を使えば、sqrt メソッド を用いて簡単に実装できちゃう。平方根は 2 つあり、全部で 8 つの候補が出てくるので、全部について \(p, q\) の復元を試します。

r = 103223593878323616966427038558164830926502672938304332798494105455624811850665520007232855349275322661436610278579342219045141961390918581096853786570821153558254045159535424052709695034827346813080563034864500825268678590931984539859870234179994586959855078548304376995608256368401270715737193311910694875689
n = 90521376653923821958506872761083900256851127935359160710837379527192460953892753506429215845453212892652253605621731883413509776201057002264429057442656548984456115251090306646791059258375402999471135320210755348861434045380328105743420902906907790808856692202001235875364637226136825102255804354305482559609
e = 65537
c = 39668573485152693308506976557973651059962715190609831067529475947235507499262380684639847018675763554013384459402806860854682788726216001229367497152996318350435451964626471390994912819484930957099855090471916842543402636518804720798852670908465424119746453269056516567591615005540824659735238630769424838121
s = 47973982866708538282860872778400091099562248899259778360037347668440286307912908903978215839469425552581036546347166946878631770320447658019243172948791127890920650587484602734465156455346574205060576092006378013418405134156752490431761037178223087071698840062913540185985867322265081768252745826955229941850

s = Zmod(r)(s)

s1s = s.sqrt(all=True)
s2s = flatten([s1.sqrt(all=True) for s1 in s1s])
s3s = flatten([s2.sqrt(all=True) for s2 in s2s])

for b in s3s:
    b = ZZ(b)
    D = b^2 - 4 * n
    if isqrt(D)^2 == D:
        p = (b + isqrt(D)) // 2
        q = (b - isqrt(D)) // 2
        if p * q == n:
            print(p)
            print(q)
            phi = (p - 1) * (q - 1)
            d = inverse_mod(e, phi)
            m = int(pow(c, d, n))
            print(m.to_bytes((m.bit_length() + 7) // 8, 'big'))

Flag: TsukuCTF23{Welcome_to_crypto!}

[MISC] content_sign

どうやら、この画像には署名技術を使っているらしい。この署名技術は、画像に対しての編集を記録することができるらしい。署名技術を特定し、改変前の画像を復元してほしい。 Flag形式はTsukuCTF23{<一個前に署名した人の名前>&<署名した時刻(ISO8601拡張形式)>}です。例えば、一個前に署名した人の名前は「Tsuku」で、署名した時刻が2023/12/09 12:34:56(GMT+0)の場合、フラグはTsukuCTF23{Tsuku&2023-12-09T12:34:45+00:00}です。なお、タイムゾーンはGMT+0を使用してください。

[OSINT] signed_flag 問題画像

※ 画像データに埋め込まれているデータが必要なので、画像クリックで元ファイルを開けるようにしてあります。

画像に署名が埋め込まれてるらしい。メディアの署名技術のことを一切知らないので、とりあえず strings してみると

IHDR
IrcaBX
Irjumb
jumdc2pa
c2pa
jumb
Gjumdc2ma
urn:uuid:d67f9244-8583-43d2-bdb6-12082bbb76e7
fSjumb
)jumdc2as
c2pa.assertions
jumb
2jumd@
c2pa.thumbnail.claim.png
bfdb
...

c2pa という文字列が気になったので調べてみると、どうやら署名関連で間違いなさそう。

署名の検証をできるウェブサイトがあったので試してみると、編集者名と作成時分は分かったものの、秒までは分からず。

[OSINT] content_sign 検証ウェブサイト

仕方がないので署名の情報を取得できるソフトウェアを探したところ、c2patool というものを見つけたので早速使ってみると

{
...

            "author": [
              {
                "@type": "Person",
                "name": "TSUKU4_IS_H@CKER"
              }
            ]

...

      "signature_info": {
        "issuer": "C2PA Test Signing Cert",
        "cert_serial_number": "640229841392226413189608867977836244731148734950",
        "time": "2023-12-08T13:00:26+00:00"
      },

...
}

Flag: TsukuCTF23{TSUKU4_IS_H@CKER&2023-12-08T13:00:26+00:00}

[WEB] basic

保護されていない通信ではパスワードはまる見えダゾ!
e.g. パスワードが Passw0rd! の場合、フラグはTsukuCTF23{Passw0rd!}となります。”

(パケットキャプチャが添付)

問題名から Basic 認証だろうとあたりをつけて HTTP パケットを見てみる。

[OSINT] basic HTTPパケット

一度 Unauthorized で弾かれていて、二度目は通っているので、二度目のリクエストを見ると

[OSINT] basic 認証情報

YWRtaW46MjkyOWIwdTQ= を Base64 逆変換すると、認証情報 admin:2929b0u4 が出てきました。

Flag: TsukuCTF23{2929b0u4}

[OSINT] river

弟のたくしから、「ボールが川で流されちゃった」と写真と共に、連絡がきた。
この場所はどこだ?
FlagフォーマットはTsukuCTF23{緯度_経度}です。
端数は少数第5位を切り捨てて小数点以下第4位の精度で回答してください。

[OSINT] river 問題画像

左の方に「newgin 専用駐車場」が見える。正確には、最初は「newqin」に見えていて、ググって「newgin」に直されてはじめて newgin だと知りました。

このロゴのニューギンを名前に持つ会社(事業所)の一覧が会社概要のページにあったので、ニューギンホールディングスから順番に Google マップ上で周辺を見ていったところ、ニューギン販売の一番最後にある鹿児島営業所の周辺で写真の場所を発見。

Flag: TsukuCTF23{31.5757_130.5533}

東経 130.55329 度と 130.55330 度のほぼ境界上だったので、最初前者で解答したら 1 回落ちてしまった。

[OSINT] grass_court

しばらく使われていないテニスコートのようだ。
この日本にあるテニスコートの場所はどこだろう。
フラグの形式はTsukuCTF23{緯度_経度}です。
小数点以下5位を切り捨てて、小数点以下4桁で答えてください。

[OSINT] grass_court 問題画像

奥に大きい電波望遠鏡が見える。このサイズの電波望遠鏡がある日本の場所、そんなに多くはなさそう。思いついた順に試してみたところ、野辺山天文台にはそれらしいところはなくて、次に見た水沢天文台で見つけました。

Flag: TsukuCTF23{39.1349_141.1324}

[OSINT] flower_bed

花壇の先にQRコードのキューブがあるようですね。友人曰く、モニュメントの近くに配置されているものらしいです。
こちらのQRコードが示すURLを教えてください!リダイレクト前のURLでお願いします!

Flagの形式はTsukuCTF23{URL}です。例えば、https://sechack365.nict.go.jpがURLなら、TsukuCTF23{https://sechack365.nict.go.jp}が答えになります。

[OSINT] flower_bed 問題画像

右上にちっちゃく写ってる QR コードを読み取る問題。

[OSINT] flower_bed QR 部分

微妙に写ってる文字をかき集めた「Prefectual Civil Hall and」で検索すると旧福岡県公会堂貴賓館がヒット。

ここからしばらくは QR コードの復元を試みようとして

[OSINT] flower_bed QR コードを書き起こしたもの

こんなものを作ったりしていました(実らず)。それとは別に、公会堂付近のストリートビューで FUKUOKA モニュメントなるものの横のキューブ上に QR コードがあるのを見つけました。

最初関連性に気がついていなかったけど、shizyukara さんや Balthazar さんたちと考えているうちに、よく見ると問題画像の QR コードもキューブの上に載っていて、奥を向いていることに気がつきました(ずっと手前向きだと思っていて、「QR コードの向きがおかしいなあ」と言っていた)。

どうやらこれらは同一の QR コードらしいとなって、FUKUOKA モニュメントの QR コードの写真を探す旅に出たところ、高解像度な写真が載った記事を見つけたので、QR コードリーダーへ GO。自分のスマホに入ってるリーダーは URL を読み取ると勝手にブラウザを開いてしまう仕様で、もたもたしてるうちに Balthazar さんが提出してくれていました。

Flag: TsukuCTF23{http://www.fukuokaken-kihinkan.jp}

Balthazar さん「HTTPS じゃないところがミソでした」

[OSINT] fiction

「座標を教えてくれ」
フラグフォーマットは、TsukuCTF23{緯度_経度}です。
小数点以下5位を切り捨てて、小数点以下4桁で答えてください。

[OSINT] fiction 問題画像

mug さんが VALORANT の Sunset マップ内の写真であるところまで特定してくれていました。どうやら VALORANT にはマップ上に緯度経度が設定されているらしく、はじめ、VALORANT 内で座標が見られるからプレイしてみろという問題だと思っていたので、帰宅した頃に VALORANT のインストールを初めてそのまま放置してました。

時間を掛けてインストールした VALORANT はなんとエラーで起動できず、絶望していたところ、よくよく調べてみるとそもそも VALORANT の座標はマップごとに 1 つ設定されているものらしい。https://valorantfiles.com/maps.php?action=92584fbe-486a-b1b2-9faa-39b0f486b498 によると Sunset の座標は 34° 2′ C″ N, 118° 12′ YT″ W で、アルファベットは マップ – Valorant Japan Wiki に書いてあるルールで数字に変換すると、34° 2′ 2″ N, 118° 12′ 16″ W となる。これを小数表現に変換するとフラグが得られました。

Flag: TsukuCTF23{34.0338_-118.2044}

[OSINT] udon_2023

ここのうどん、麺だけじゃなく、鶏天も美味しい!!!
お店の場所を忘れたから、7文字のplus codeで教えて!!!
フラグフォーマットは、+を含めてTsukuCTF23{**REDACTED**+**REDACTED**}

[OSINT] udon_2023 問題画像

実は fiction を解いた後 koi と hunter に夜通し苦しめられ、udon_2023 はその息抜きで解いたものなので、fiction と udon_2023 の提出時間は 4 時間くらい離れています。

最初勝手に高松のうどんと決めつけて高松のうどん屋を探していたが、見つからない。あまりに情報がなさすぎるため、作問陣から guess することを試してみました。

運営の shio さんは現役早稲田生とのことなので、「高田馬場 うどん屋 鶏天」でググったところ、問題画像と同じ器を使ったうどんが出てきました。この記事自体は神田店のものですが、店名の「甚三」で検索すると高田馬場店があったので、答えてみたら正解でした。

Flag: TsukuCTF23{PP63+G6}

初回 TsukuCTF の udon は、TSG が唯一解けず全完の st98 さんに敗ける要因となった因縁の問題ですが、今回は突破できてよかったです。

[OSINT] twin

ハッカーは独自に収集した大量の個人情報を、とあるWebサイト上で2023年11月23日に投稿した。
我々はこの投稿IDがKL34A01mであるという情報を得た。ハッカーのGitHubアカウントを特定せよ。

Hint: このWebサイトは28歳のオランダ人起業家によって2010年代初めに買収されている。

はじめオランダ人起業家によって買収されたウェブサイトを探していたけど、全く見つからず。思い当たったり調べて出てきたウェブサイトを片っ端から試しました。ファイルアップローダー系や Imgur などの画像系をいくつか見て回った後、ふと Pastebin.com の存在を思い出して投稿 ID を入れてみるとビンゴ。(偽の)個人情報リストが表示されたときはあまりに感動しました。

KL34A01m の投稿者の別の投稿を見ると、「Tsuine」というタイトルの Ruby の Quine が投稿されていたので、これを GitHub 上で検索すると gemini5612/Tsuine がヒット。

Flag: TsukuCTF23{gemini5612}

Tsuine の実行結果:https://wandbox.org/permlink/C6Lld029wFGBp9bH

[OSINT] koi

画像フォルダを漁っていると、鯉のあらいを初めて食べた時の画像が出てきた。
当時のお店を再度訪ね、鯉の洗いを食べたいが電話番号が思い出せない。

誰か、私の代わりにお店を調べ、電話番号を教えてほしい。

記憶では、お店に行く途中で見かけたお皿が使われていた気がする。。。

Flagは電話番号となっており、ハイフンは不要である。
TsukuCTF23{電話番号}

[OSINT] koi 問題画像

お皿の模様が特徴的。satos さんが結構早めの段階で「小石原焼か小鹿田焼っぽい」という情報を掴んでくれていた。しかし、それ以外の情報が一切得られず、Google レンズもあんまり情報をくれず、大分なすすべなしでした。

仕方がないので、小石原焼の東峰村や小鹿田焼の日田市、その周辺の鯉のあらいを出しているお店を片っ端から調べ、机や盛り方がちょっとでも似ているところをひたすら試しましたが、うまく行かず。2 時頃からの検索履歴が鯉で埋まりました。

udon_2023 や twin を解いて、8 時頃に一度寝て、12 時に起きてもう一度取り組んでもやっぱりわからない。そんなとき、ふともう一度 Google レンズを試してみると、なんと机の模様や境目がそっくりなお店がでてきたじゃないですか。

[OSINT] koi 見つけたお店

このお店を試したところ、無事正解でした。あまりに感動して奇声を発してしまいました。近所に聞こえてなければいいのだけれども。

Flag: TsukuCTF{0936176250}

[OSINT] hunter

名前をメールで聞こうとしたところ、相手のGmailの一部が分からなくなってしまいました。
大変お忙しいところ恐縮ですが、暇なときに調査してください。
qeinijo#iby#@gmail.com
#が不明な部分です。
なお、外部サービスに短期間で多くのアクセスをしないようにしてください。

私の睡眠は koi とこの問題に破壊されました。

Gmail のアドレスに使用できる文字はアルファベット・数字・ピリオド。アルファベットの大小は区別されないので、実質 37 種類になります。それが 2 文字分あるので、全部で 1369 通りです。

このなかから実在するアカウントを見つけ出すのが難しい。最初はアカウント作成を試みる(作れなかったら存在する)という方法を試したが、一つずつ真心込めて試すと時間もかかるし、いくつか試しているうちに何らかの limit にひっかかったっぽくて全部存在すると判定されるようになってしまいました。この方法はだめ。

次に、Gmail の宛先欄に全部入れてみるという方法を思いついたので試しました。

[OSINT] hunter 宛先欄

人生長しといえど、この人数を宛先欄にぶち込むことはもう二度と無いんじゃないかと思います。

対応する Gmail アカウントが存在していて、そのアカウントにプロフィール画像が設定されている場合、その画像がアイコンで表示されるので見つけられるという算段です。しかし、プロフィール画像が設定されていなかったようで、全員デフォルトアイコンで撃沈。

この画面をいろいろ触ってみたところ、各宛先の詳細表示の中の「メッセージを送信」ボタンは、相手が存在していない場合無効になるようだということがわかりました。が、これを一人ひとり確かめるわけにもいかず断念。

[OSINT] hunter 各宛先の詳細表示

Gmail アドレスが存在していない場合は存在しないよってちゃんと教えてもらえる方法は無いかなと考えた結果、考えついたのが Google Drive のファイル共有でした。他が管理するアドレスにも送れるメールとちがって、Google Drive は Google アカウントの存否で共有できるかどうかが決まるためです。

結果、この読みは(たぶん)正しかったようです。存在しないメールアドレスにℹ️マークがつく中、qeinijo.iby8@gmail.com のみが存在していることがわかりました。

[OSINT] hunter Google Drive 共有

たぶんこの人数にファイルを共有することも一生ないだろうなあ。実際には共有してないけど。

晴れてメールアドレス qeinijo.iby8@gmail.com を復元できたわけですが、これがフラグというわけではないようです。問題文を見たところ名前が分かれば良さそうなので、アカウント名を調べる方法を探してみたものの、見つけることはできず。

寝て起きて koi を考えている間に Balthazar さんが EPIEOS というウェブサイトを見つけてくれて、無事フラグを獲得していました。クエリのリンク

Flag: TsukuCTF23{GHun7_i5_u5efu1}

[OSINT] sunset

TsukuCTF運営の1人であるshioが、今年に開催されたあるイベントが終わった後に夕日を撮影した。
この写真が撮影された日時を求めよ。
フラグフォーマットはTsukuCTF23{YYYY/MM/DD_hh:mm}である。
例えば、TsukuCTF2023の開始日時はTsukuCTF23{2023/12/09_12:20}
なお、誤差は1分まで許容され、日本標準時を用いる。

提出回数制限:3 回

[OSINT] sunset 問題画像

この問題が TsukuShiGuesser にとってのラスボスになりました。

まず初めに、12/9 の夜頃に soup さんが撮影場所(日和山展望台)と日付(2023/09/10)を特定してくれました。shio さんの Twitter からイベントを特定して探してくれたようです。

ここでぼくは、なんと提出欄にフォーカスしたまま Enter を押してしまうという致命的なミスをやらかしてしまいます。その後、soup さんが当日の日没時刻 18:01 を提出してくれたものの、残念ながら不正解。提出可能回数が残り 1 回の特級呪物と化し、最後の一問になるまで放置されてしまいました。

hunter も解き終わっていよいよ全完がかかるラスト 1 問となった頃、ぼくとsoup さん、jiei さんの 3 人で仕留めにかかりました。

一発で確実に仕留めるに当たって、詰めなければならない点が 2 点ありました。一つは、「日付は 9/10 で間違いないのか」ということ。もう一つは、正確な撮影時刻はいつ頃なのかということです。

日付に関しては、日和山展望台 since:2023-09-09 until:2023-09-11 で検索して発見した一つのツイートが鍵になりました。

[OSINT] sunset 鍵となったツイート
https://twitter.com/crazystaygold/status/1700798539255926819 より引用

この太陽の沈み具合と雲、出題画像とかなり一致しています。つまり、日付は 9/10 でほぼ間違いないということがわかりました。

正確な撮影時刻については、jiei さんが見つけてくれたライブカメラ映像が大変役に立ちました。関屋浜という、日和山展望台からそれほど離れていないところに設置されたライブカメラです。

残念ながら 9/10 当日の映像はなかったのですが、前日 9/9 の映像が参考になりました。この動画の 4 時間 56 分~ 58 分あたりの風景が問題と似ています。概要欄によると昼の 12時45分~13時 にメンテナンスをしているとのことなので、この映像は 13 時から始まっていると考えられ、17:57~17:59 あたりに似ている風景が見られるということがわかります。

ここで、9/10 の新潟の日の入り時刻は 9/9 よりもおおむね 1 分 30 秒ほど早いことが、調べた結果わかりました。とすると、似ている風景が見られる時刻も同程度早くなると考えられます。すなわち、問題画像が撮影された時刻は 9/10 の 17:55:30~17:57:30 の範囲にあると推測できます。9/13 のライブカメラの映像での時間とも整合性がとれることも確認。

撮影位置や高さのズレの影響はゼロではないですが、大きくは変わらないようでしたので、9/10 の 17:56 をファイナルアンサーとしました。

[OSINT] sunset トリプルチェックの様子

typo したらそれで終わりなので、フラグ形式とも照らし合わせて、ぼく・soup さん・jiei さんでトリプルチェック。怖くて誰も出したがらなかったので、厳正なる抽選の上で jiei さんに提出してもらい、無事 Correct!

Flag: TsukuCTF23{2023/09/10_17:56}

あと 1 回提出回数が残っていたら、もう少し雑に解いても大丈夫だったんだろうなあ(白目)。

<2023/12/11 03:12 追記>

トリプルチェックなんていらんかったんや!

おわりに

これだけ味がある問題が集まっていると、解き甲斐もあってよいですね。日本でここまで OSINT メインで賑わってる CTF ってなかなか無いんじゃないかと思うので、ぜひ今後も OSINT に力を入れたコンテストを開いてもらえるとうれしいな~~と思いました(もちろん、他のジャンルへの進出を止めるものではないです!)

次回こそは 1 位を取りたいね。がんばるぞ~~