Securityout

Web security research

setodaNote CTF 2021: Writeup

目次

Writeupは目次の「問題」より設問の解答をご覧ください。

 

競技概要

CTF競技名: setodaNote CTF

競技期間: 2021.8.21 PM 9:00 ~ 2021.9.4 PM 9:00 (JST)

参加登録者数: 854名 ※競技終了時点で /users ディレクトリを参照

備考: カテゴリ名「Programing」(正: Programming)とflagのフレーズ「MATLIX」(正: MATRIX)はスペルミスだった模様。※本稿では、そのまま元のスペルで記載します。

 

スコア

f:id:reinforchu:20210905071817p:plain

August 22nd, 18:23:41(JST)より、ユーザー名 reinforchu で個人として参加。

36/592位、7310点、69問中63問を解答にて競技終了。 ※SolvesあるユーザーのみScoreboardに掲載される

傾向分析

記録のために、ここに残しておきます。

f:id:reinforchu:20210905075802p:plain

🪧Slove Percentages

画像ファイルからflag文字列を起こした時に、誤読が多発した。Miscのi_knew_it問が当てもん状態になってしまったため、Failが多い。(当てもんゲームじゃないので途中で諦めました。)

f:id:reinforchu:20210905075918p:plain

🍩Category Breakdown

f:id:reinforchu:20210905080030p:plain

🕸️Category Score Radarchart

f:id:reinforchu:20210905080155p:plain

✊Category Level

何にしろPwnが弱すぎる。個人的にOSINTの最後2問がいい線までいってたけど、解けず難しかった。各カテゴリの強み弱みがしっかりグラフに出ました。

f:id:reinforchu:20210905074640p:plain

💍Badges

各カテゴリの問題をすべて解いた場合に実績が解除されます。今回、私はRev(リバースエンジニアリング), Programing(プログラミング解法), Crypto(暗号解読), Web(ウェブ技術), Network(通信解析)を全問回答しました。Misc(その他雑学)とForensics(科学捜査)があと一問でしたが、解ききれませんでした。

f:id:reinforchu:20210905080323p:plain

✅Sloves

概ね解けているんだけど、肝の問題が解けなかったのが惜しい。個人的にはForensicsのTITLE問(lo3rs1tkd.jpg)が、思いっきりシュタインズ・ゲートで解けなかったのが悔しい。

スコアボード

f:id:reinforchu:20210905083036p:plain

📈Scoreboard

36位。まずまず健闘したと思われます。完走者(全問回答)は13名/チームでした。めっちゃ強い。

 

問題

Challengesの表示の順番で、解けた問題は解法のみを記載し、試行錯誤のログは記載しません。解けなかった問題は、概要のみ記載します。

Misc

問題文やタイトルに記載されていることを、やるだけの問題が多かったように思いました。

i_knew_it問のみ解けませんでした。

Welcome

20pt問題。今回のCTFではWeb shellのLinuxターミナルを操作する環境でした。問題文の通り「welcome.txt」の内容を確認するとフラグが得られます。

最初の触りなので、ログインからflag表示までのログを貼り付けておきます。

Terminal log

Enter your username: reinforchu

reinforchu@webshell.setodanote.net's password: 
======================================================================

Welcome to setodaNote CTF web based terminal!

 💻  This is an isolated environment and will not be shared with other users.

 ⏳  Idle sessions will automatically log out after 30 minutes.

 🧨  Any files you create in this terminal will be deleted when you exit.

 🚫  It is strictly prohibited to use this terminal for any purpose other than solving questions.

 📄  By using this terminal, you agree to the following privacy policy and terms of service.
     * https://ctf.setodanote.net/privacy
     * https://ctf.setodanote.net/tos

======================================================================
user@c169b756e07f:~$ ls -a
.  ..  .bash_history  .bash_logout  .bashrc  .cache  .local  .profile  welcome.txt
user@c169b756e07f:~$ cat welcome.txt 

  Welcome to the setodaNote CTF!!

  *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
  *                                 *
  *   flag{Enjoy_y0ur_time_here!}   *
  *                                 *
  *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  This is the flag.

user@c169b756e07f:~$ 

flag{Enjoy_y0ur_time_here!}

morse_one

30pt問題。「DBS」が羅列された文字列のテキストファイルが渡されました。タイトルの通り、あの有名な「ツー」「トン」のモールス信号となっています。

morse_one.txt

DDDBSDDSBDDDSDBDSBBBSDBBDSDBDDSDSBDDB

Dが・、Bがー、Sが区切り文字なので、モールス信号に変換するWebツールで確認しました。

Morse Code Translator by Various Words

f:id:reinforchu:20210905162957p:plain

morse_one: flag

flag{VIBROPLEX}

Hash

50pt問題。配布されたzipアーカイブを展開すると大量のファイルが出てきます。問題文には、「以下のハッシュ値を持つファイル見つけ出してください。フラグはそのファイルに記載されている文字列を組み合わせたものとなります。」とありました。

aff02d6ad353ebf547f3b1f8ecd21efd7931e356f3930ab5ee502a391c5802d7
8428f87e4dbbf1e95dba566b2095d989f5068a5465ebce96dcdf0b487edb8ecb
e82f6ff15ddc9d67fc28c4b2c575adf7252d6e829af55c2b7ac1615b304d8962

まず何のハッシュアルゴリズムの値か特定しますが、文字列の長さからSHA256で決め打ちでコマンド叩きましょう。

Command

shasum -a 256 * | grep "<hash>"

cat <file>

Terminal log

reinforchu@ReinPro hash % shasum -a 256 * | grep "aff02d6ad353ebf547f3b1f8ecd21efd7931e356f3930ab5ee502a391c5802d7"

aff02d6ad353ebf547f3b1f8ecd21efd7931e356f3930ab5ee502a391c5802d7  pass024.txt

reinforchu@ReinPro hash % shasum -a 256 * | grep "8428f87e4dbbf1e95dba566b2095d989f5068a5465ebce96dcdf0b487edb8ecb"

8428f87e4dbbf1e95dba566b2095d989f5068a5465ebce96dcdf0b487edb8ecb  pass034.txt

reinforchu@ReinPro hash % shasum -a 256 * | grep "e82f6ff15ddc9d67fc28c4b2c575adf7252d6e829af55c2b7ac1615b304d8962"

e82f6ff15ddc9d67fc28c4b2c575adf7252d6e829af55c2b7ac1615b304d8962  pass079.txt

reinforchu@ReinPro hash % cat pass024.txt 

flag{hardest

reinforchu@ReinPro hash % cat pass034.txt

_logic_

reinforchu@ReinPro hash % cat pass079.txt

puzzle}

reinforchu@ReinPro hash % 

flag{hardest_logic_puzzle}

F

80pt問題。以下のソースコードが配布されました。

+++++++[->++++++++++>+++++++++++>+++++++++>++++++++++<<<<]>.>-.>++.>+.>++++++++[>++++<-]>.>+++++[->+++++++++++++++++++++>+++++++++++++++++++++++<<]>.>.>++++++++[>++++<-]>.>++++++++++[->++++++++++>++++++++++>++++++++++>++++++++++>++++++++++++<<<<<]>++.>++++++++.>---.>+++.>+++.>++++++++[>++++++++<-]>++++.>+++++++++++[>++++++++++>++++++++++<<-]>+.>.>++++[>++++++++++<-]>-.>+++[->+++++[->++++++++<]<]>>----.>++++++++++[->++++++++++>+++++++++>++++++++++++>++++++++++>+++++++++<<<<<]>-----.>-----.>-----.>+.>+++++.>++++++++++++++++++++[>++++++>+++++>+++++>+++++>+++>++<<<<<<-]>----.>++++.>+.>-----.>++++++++++.>+++++.>++++++++++[->+++++++++>+++++++++++>+++++++++++>++++++++++<<<<]>---.>+.>++++.>.>+++[->+++++++++++<]>..>+++++[->+++++[->+++++<]<]>>.

言うまでもなく、Brainf*ckですね。Web上にあるインタプリタで実行してみます。

BrainFuckインタープリタ:いで庵

Output

FLAG is flag{Don't_Use_the_F-Word!!}

flag{Don't_Use_the_F-Word!!}

magic_number

80pt問題。配布されたzipアーカイブを展開すると大量のファイルが出てきます。要約がややこしいので、問題文を下記にそのまま引用します。

添付されたファイルから以下が示す3つのファイルを探してください。

[89 50 4e 47]
[52 61 72 21]
[ff d8 ff e0]

フラグは該当するファイル名を以下の順番にアンダースコアでつないで回答してください。

flag{[89 50 4e 47]_[52 61 72 21]_[ff d8 ff e0]}

例えばファイル名がそれぞれ以下の場合は flag{aaa_bbb_ccc} と答えてください。

[89 50 4e 47] = aaa.txt
[52 61 72 21] = bbb.exe
[ff d8 ff e0] = ccc.zip

問題文から、ファイルのマジックナンバーをGoogle検索などで調べれば良いので、下記の結果になった。

[89 50 4e 47] = post.png
[52 61 72 21] = rar.png
[ff d8 ff e0] = light.jpg

flag{post_rar_light}

Stegano

100pt問題。ステガノグラフィー問題でした。flag文字列が3パターンで埋め込まれており、うさみみハリケーンの青い空を見上げればいつもそこに白い猫のステガノグラフィー解析機能を使いました。

flag1 左上

f:id:reinforchu:20210905180554p:plain

赤色 ビット3 抽出

flag2 中央

f:id:reinforchu:20210905180849p:plain

XOR (全てのビットを反転)

flag3 右下

f:id:reinforchu:20210905181042p:plain

ビットプレーン ビット4

flag{Re4l17y_1s_cReA73d_by_7h3_m1nd_rA9}

morse_zero

100pt問題。ゼロ幅スペースのUnicode文字列が混入しているモールス信号のテキストファイルが配布されました。

f:id:reinforchu:20210905183053p:plain

morse_zero.txt

E2 80はこの問題上Unicodeのゴミなので削除し、残った8Bが.、8Cが_、5Aを[SP]の区切り文字として、モールス信号に変換するWebツールで確認しました。

Morse Code Translator by Various Words

f:id:reinforchu:20210905182347p:plain

morse_zero: flag

Input

__.. . ._. _____ ..__._ .__ .____ _.. _ .... ..__._ ... .__. ._ _._. .

Output

ZER0_W1DTH_SPACE

flag{ZER0_W1DTH_SPACE}

ransom_note

100pt問題。重大なセキュリティインシデントです。どうやらflagがランサムウェアに感染して暗号化されてしまったようです。実際に暗号化されたflagを復号するとflagが得られる。配布されたzipアーカイブを展開すると下記の3つのファイルが出てきました。そのうち、脅迫状の一部を下記に掲載します。

NPIEWI-DECRYPT.txt

---=    GANDCRAB V5.0.3  =--- 
 
***********************UNDER NO CIRCUMSTANCES DO NOT DELETE THIS FILE, UNTIL ALL YOUR DATA IS RECOVERED***********************
 
*****FAILING TO DO SO, WILL RESULT IN YOUR SYSTEM CORRUPTION, IF THERE WILL BE DECRYPTION ERRORS*****
 
Attention! 
 
All your files, documents, photos, databases and other important files are encrypted and have the extension: .NPIEWI
以下省略

NPIEWI-DECRYPT.txtには、まさしく--BEGIN GANDCRAB KEY--の記載がある鍵となるファイルなので、このファイルと暗号化されてしまったファイルの復号を試みる。なお、ランサムウェアはGANDCRAB V5.0.3の模様。

Google検索で「GANDCRAB Decrypt」など検索すればBDGandCrabDecryptTool.exeという復号ツールを手に入れられるので、これを使いました。

https://www.bitdefender.com/blog/labs/gandcrab-ransomware-decryption-tool-available-for-free/

f:id:reinforchu:20210905185905p:plain

BDGandCrabDecryptTool.exe

画面の指示通りに進めればsecret.txt.npiewiは復号された。

f:id:reinforchu:20210905190012p:plain

secret.txt

flag{unlock1ng_y0ur_d1gital_life_with0ut_paying;)}

Nothing

120点問題。問題名の時点でWhitespace言語と推定でき、まさしくそれはWhitespaceで書かれたソースコードでした。

f:id:reinforchu:20210905190446p:plain

nothing.txt

WebツールでWhitespace言語のインタプリタを実行します。

Whitespace Interpreter

f:id:reinforchu:20210905190754p:plain

Nothing: flag

flag{And_Then_There_Were_None}

i_knew_it

120pt問題。問題文を要約せずに下記に引用します。

「このアセンブリ、見た瞬間あなただと分かりましたよ。」

ある暗号方式の名称がフラグになっています。添付ファイルからその暗号方式の名称を特定し、フラグ形式で回答してください。

フラグに英字が含まれている場合は、すべて大文字で答えてください。例えば This_is_FLAG が得られた場合は flag{THIS_IS_FLAG} となります。

 

f:id:reinforchu:20210906095537p:plain

I_knew_it.png

このアセンブリ、見た瞬間分かるかーーー!

Incorrect

Redacted

150pt問題。黒塗りにされたPDFドキュメントが配布されたので、ひとまずAdobe Acrobat DCで開きました。

f:id:reinforchu:20210906141902p:plain

top_secret.pdf

黒塗りにされたところがflagだろうと予想がつくので、PDFを編集して黒い箱を消しました。

f:id:reinforchu:20210906142354p:plain

Redacted: flag

今回はたまたま私がAdobe DCが使えたのでAcrobatで解きました。

flag{weather_balloon}

strong_password

250pt問題。配布されたzipアーカイブはパスワードがかかっており、それを解析する問題でした。ただし、パスワード規則が記載されたPDFドキュメントが同梱されていました。

f:id:reinforchu:20210906142957p:plain

情報セキュリティガイドライン(別紙1).pdf

つまりパスワード規則を読み解くと、/[A-Za-z]{3}[@#$%!-]{1}202[0-9]{1}[0-9]{4}[@#$%!-]{1}/こんな感じのパスワード規則である。もっとも、年月日は規則がまだあるのでもっと絞れる。このパスワード規則が分かっていれば現実的に総当りでパスワードを割り出すことが可能である。

CTFにおいてはコード書いてなんぼのところがありますが、たまたま有償のZIPパスワード解析ツール「Zip Password」のライセンスがあったので、それで解きました。あまり参考にならないと思ってます。解析ルールは下記の通りです。

f:id:reinforchu:20210906144225p:plain

strong_password: Zip Password rule

この解析ソフトはGPUも使ってくれるので、1分足らずで解析が終了しました。

f:id:reinforchu:20210906144649p:plain

strong_password: Found password

パスワードは「qYL%20210228!」でした。このパスワードでTopSecret.zipを展開します。TopSecret.txtが出てくるので開きます。

f:id:reinforchu:20210906144956p:plain

TopSecret.txt

flag{And_n0w_h3re_is_my_s3cre7}

 

Network

yes_you_can、問題名を見た瞬間CAN通信の問題だと分かってわくわくしました!基本的にオーソドックスに解いていく問題がほとんどで、CAN問題が一番面白かったです。全問回答しました。

Host

30pt問題。pcapが配布されるので、そのキャプチャ内のHTTP通信の宛先ホスト名がflagでした。

Wiresharkで開き、HTTP Streamで通信を追いかけます。

f:id:reinforchu:20210906151759p:plain

Host: flag

flag{ctf.setodanote.net}

tkys_never_die

50pt問題。pcapが配布され、そのキャプチャの中にflagがあるそうです。

Wiresharkで開き、HTTP Streamで追っかけると、flag.pngというファイルを見つけることができるので、File > Export Objects > HTTPでPNGイメージを抽出しました。

f:id:reinforchu:20210906152454p:plain

tkys_never_die: Object

f:id:reinforchu:20210906152629p:plain

tkys_never_die: flag

flag{a_treasure_trove}

echo_request

120pt問題。問題名と問題文から、ICMP通信がフラグであると推定できる。配布されたpcapをWiresharkで開き、ICMP通信を見ます。

ICMP通信が連続している部分があるので、ASCIIデータ部分に注目しながら流し見ます。

f:id:reinforchu:20210906153949g:plain

echo_request: flag

flag{ICMP_Tunneling_T1095}

stay_in_touch

150pt問題。例によってpcapngが配布されるのでWiresharkで開き、通信を見てみる。

IMAP通信をしているので、IMFが抜き出せないか試みる。

f:id:reinforchu:20210906155203p:plain

stay_in_touch: IMF

全部Exportして一個一個みるのはつらいくどのみち平文なのでNotepadで開き、IMAP通信(メール)の流れを読んでいく。

f:id:reinforchu:20210906155616p:plain

stay_in_touch: Suspicious

試作機のレポートを転送、という不審なキーワードのメッセージを見つけました。続きを見ます。

f:id:reinforchu:20210906155948p:plain

stay_in_touch: Report-AV-T0097.zip

Report-AV-T0097.zipという怪しいファイルがBase64で発見しました。これをCyberChefでデコードして取り出してみましたが、残念ながらパスワードがかかっていました。パスワードは別に送るらしいので、メールの続きを読んでみましょう。

f:id:reinforchu:20210906160518p:plain

stay_in_touch: Password

パスワードは「Yatagarasu-Takama-Kamuyamato2」のようです。先ほどのZIPアーカイブを展開してみると、Report-AV-T0097.txtというファイルが出てくるので、それを開きflag獲得です。

f:id:reinforchu:20210906160751p:plain

Report-AV-T0097.txt

flag{SoNtOkIhAmOuKaTaHoUmOtSuMuRuNoSa;)}

yes_you_can

150pt問題。仮想CANデバイスのvcan0のCAN通信をダンプしたものと思われるファイルが配布されました。

f:id:reinforchu:20210906161243p:plain

yes_you_can: dump.log

まずはLinux(今回はUbuntu)で仮想CAN通信の環境を構築しました。環境構築に関しては本稿では割愛させていただきますが、下記の記事を参考にさせていただきました。

www.shutingrz.com

CAN通信の中身についてはよく分かってなかったので、まずどんな通信内容になっているところから勉強しました。配布されたdump.logを再送するコマンドで流すとメーターが振れるという挙動になり、これがflagだと推測しました。

Command

canplayer -I dump.log

f:id:reinforchu:20210906162046p:plain

yes_you_can: Meter

つまり、速度のCAN通信のみ抽出すれば良いのですが、これが難しく無茶苦茶なログが大量に出力されてしまうので、操作対象のCAN IDを特定しないといけません。実際にジョイスティック(ゲームパッド)を使って、通信のdumpを見ながらデバッグした結果、CAN IDは244であると特定しました。わりと勘と人力です。

ノイズのログをgrepで除外して最終的にflagを表示させるコマンドは下記の通りです。

Command

candump -d -x -e -a vcan0,0:0 | grep "244" | grep -v "00 00 00 01"

f:id:reinforchu:20210906164821g:plain

yes_you_can: flag

flag{can_bus_hacking}

Digdig

200pt問題です。配布されたpcapをWiresharkで開いて見ると、C&Cでドメイン名にクエリ文字列を埋め込む手法と推測しました。文字列もHexっぽいのでASCII文字列に変換が出来そうでした。

f:id:reinforchu:20210906170245p:plain

Digdig: pcap

例えば「005aa002735f69735f44414d.setodanote.net」この文字列からサードレベルドメイン名のみ切り取って集めました。

Hex list

005aa002735f69735f44414d
005aa00663655f7472795f53
005aa0034d595f464c41477d
005aa0085f746861747d2066
005aa00a6c61677b444e535f
005aa00b5333637572313779
005aa0076f7272795f666f72
005aa00420666c6167206973
005aa0096c61672069732066
005aa00c5f5431303731217d
005aa011797d323232323232
005aa00d20666c6167206973
005aa00f335f6b33795f3135
005aa00e20666c61677b3768
005aa001666c61677b546869
005aa0105f35336375723137
005aa000666c616720697320
005aa00520666c61677b4e69

CyberChefでFrom HexでASCII表示させます。

f:id:reinforchu:20210906170737p:plain

Digdig: From Hex

Output

.Z .s_is_DAM.Z .ce_try_S.Z .MY_FLAG}.Z ._that} f.Z 
lag{DNS_.Z .S3cur17y.Z .orry_for.Z . flag is.Z lag is f.Z ._T1071!}.Z .y}222222.Z 
 flag is.Z .3_k3y_15.Z . flag{7h.Z .flag{Thi.Z ._53cur17.Z .flag is .Z . flag{Ni

確かにflag文字列が得られましたが、ゴミが入っているし、順番がバラバラです。コード使って整形抽出すればいいのですが、Notepadで手作業で組み立て直しました。

「Z」「[SP]」「flag is」「.」を削除して、意味が通るようにしました。

flag is ?

flag{Nice_try_Sorry_for_that}

flag{This_is_DAMMY_FLAG}

flag{DNS_S3cur17y_T1071!}

flag{7h3_k3y_15_53cur17y}222222 

上から3番目がもっともflagっぽいので、投げたら通りました。賢いやり方があるはず。

flag{DNS_S3cur17y_T1071!}

Logger

250pt問題。pcapが配布されましたが、どうやら今回はよくある通信と違うようです。

f:id:reinforchu:20210906171812p:plain

Logger: pcap

USBの通信で、キーボード入力の操作キャプチャっぽいことは分かりました。様々Google検索をしても解析方法が分からなかったので、入力結果を出してくるToolを探してそれで解いてしまいました。

github.com

Command

UsbKeyboardDataHacker.py logger.pcap

f:id:reinforchu:20210906194735p:plain

Logger: Output

flagはもう見えていますが、制御文字を置換するなどして原文を出してみました。

One popular bbut unverified explanatioon for the QWERTY arrangement is that it wwas designed to reduce the likelihood of flag{QWE_keyb0ard_RTY} internal clashhing of typebars by placing commonly ussed combinatiioons of letters farther froom each oher inside the machine. 

flag{QWE_keyb0ard_RTY}

tkys_not_enough

250pt問題。pcapが配布されましたが、どうやら本当にWiresharkなどのよくあるアナライザーでは開けないようです。HTTP通信や、Base64文字列がありましたがブラフでした。

flag?

if iknow goFlag cinema

バイナリエディタでいじったり、散々悩んだ挙げ句、たどり着いたのは。

Command

binwalk -D='.*' tkys_not_enough.pcap

Terminal log

DECIMAL       HEXADECIMAL     DESCRIPTION

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

535234        0x82AC2         gzip compressed data, from Unix, last modified: 1970-01-01 00:00:00 (null date)

537545        0x833C9         gzip compressed data, from Unix, last modified: 1970-01-01 00:00:00 (null date)

ZIPアーカイブが出てきました。

f:id:reinforchu:20210906173832p:plain

tkys_not_enough: binwalk

怪しそうな82AC2-0を82AC2-0.zipにリネームして展開してみます。OS標準アーカイバだとエラーになるので、7-Zipで普通にエラーを吐きながら展開してこじ開けます。82AC2-0というファイルが出てくるので、Notepadで開きます。

f:id:reinforchu:20210906174452p:plain

82AC2-0

おそらく想定解とは違うと思われます。

flag{netw0rk_shell_2000}

 

Web

全問回答しました。すぐに解ける問題ばかりで、特に難しい問題はなかったです。

Body

30pt問題。flagはHTMLソースコードにコメントアウトされていました。

f:id:reinforchu:20210906112950p:plain

web001

flag{Section_9}

50pt問題。flagはHTTPレスポンスヘッダーに記載されていました。

f:id:reinforchu:20210906113306p:plain

web002

flag{Just_a_whisper}

puni_puni

80pt問題。Punycode表記の文字列が渡さました。

xn--q6jaaaaaa08db0x8nc9t1b8fsviei84atb4i0lc
xn--q6jaaaaa03dpd4mb3jc5rpa0g9jpk07acadc.
xn--q6jylla3va3j6c8138a8eptvb303cxv4ft3o4ue63a
xn--v8ja6aj2a3cri3ag4a2r6cx2a1rkk1272c7j4ajd4bmf0kjhg6rb.
xn--q6j6gav1a0b2e1bh1ac2cl29ad7728kdjen6cz80dju6bqexchl9gel8b.

一つ一つIDNにデコードするのは面倒くさいので、ドメイン名なので.でつなげてCyberChefに投げました。

f:id:reinforchu:20210906114414p:plain

pui_pui: CyberChef

Input

xn--q6jaaaaaa08db0x8nc9t1b8fsviei84atb4i0lc.xn--q6jaaaaa03dpd4mb3jc5rpa0g9jpk07acadc.xn--q6jylla3va3j6c8138a8eptvb303cxv4ft3o4ue63a.xn--v8ja6aj2a3cri3ag4a2r6cx2a1rkk1272c7j4ajd4bmf0kjhg6rb.xn--q6j6gav1a0b2e1bh1ac2cl29ad7728kdjen6cz80dju6bqexchl9gel8b.

Output

フラグは、さん、さん、ピー、ユー、エヌ、ワイ、.シー、オー、ディー、イー、よん、よん、です.カタカナ表記は半角英小文字に、.ひらがな表記は半角数字にしたものがフラグです.なお、読点は区切り文字なので取り除いてください.

flag{33punycode44}

Mistake

100pt問題。ディレクトリインデックスが有効なので、そこをたどってflagが獲得できました。

トップページのHTMLのソースコードにはヒントが記載してありました。

/web003/

<p>特に指定がない限りフラグは flag{<!-- Webserver directory index? -->} という形式をとります。</p>

Webserver directory index?というヒントが貰えるので、/web003/images/にアクセスしてみる。

f:id:reinforchu:20210906115538p:plain

web003: Index of

pic_flag_is_here.txtが見えてるので、これを開く。

f:id:reinforchu:20210906115715p:plain

pic_flag_is_here.txt

flag{You_are_the_Laughing_Man,_aren't_you?}

tkys_royale

120pt問題。MySQLにSQLインジェクションするとadminのログイン認証を突破できflagが獲得できました。

/web005/

<form id="signup-form" method="post" action="#">
                            <!-- TEST ONLY user:pass123 -->
                            <input type="text" placeholder="username" name="username"/>
                            <input type="password" placeholder="password" name="password"/>
                            <input type="submit" value="Login">
</form>

user:pass123でログインすると「You need to be logged in as admin to find the flag.」と、adminでログインするとflagが獲得できるヒントが貰える。

オーソドックスな確認方法「'」を投げてみる。

POST body

username=admin&password='

f:id:reinforchu:20210906121101p:plain

MySQL Error

MySQLのエラーメッセージとクエリ文が出力されるという斬新なログインフォームで、SQLi問ということが確定。ここまで分かっていれば、コメントアウトしてしまえばいいです。

POST body

username=admin'#&password=

f:id:reinforchu:20210906121413p:plain

web005: flag

flag{SQLi_with_b1rds_in_a_b34utiful_landscape}

Estimated

120pt問題。漏洩していたflagを削除したが、それを見つけ出す問題でした。

f:id:reinforchu:20210906125540p:plain

web006

一見、普通のブログのようですが「昨日の記事について、掲載していた画像に公開すべきではない情報が含まれていたため当該記事を削除いたしました。」という記事を見つけられますが、そこにはflagはないです。該当記事は消されたのでした。

他の記事を見ると風景の写真を投稿しているので、イメージファイルのURLの規則性を見ます。

今日の景色(2021年7月10日)

/web006/images/20210710001b.jpg

つまり、ファイル名の命名規則はYYYYMMDD連番b.jpgという規則であることが推察できます。従って、2021年06月03日の昨日の日付のファイル名を命名規則に合わせて推定します。

推定されたイメージファイル名

/web006/images/20210602001b.jpg

f:id:reinforchu:20210906130916p:plain

20210602001b.jpg

🎯当たり。さて肝心のフラグは、MacBook Airの画面の中央の検索フォームにありました。拡大したものを掲載します。

f:id:reinforchu:20210906131307p:plain

web006: flag

flag{The_flag_wouldn't_like_to_end_up_in_other_peoples_photos}

Mx.Flag

150pt問題。隠されたflagを見つける問題でした。指定されたURLを開いてBurpを眺めていたら一瞬で見つかりました。

flagはfavicon.pngに隠されていました。

f:id:reinforchu:20210906131848p:plain

web007: flag

flag{Mr_Flag_hiding_in_the_favicon}

Redirect

150pt問題。隠されたURLを見つけ出し、リダイレクト中にQueryStringのパラメータの値を想定して変更しflagを獲得する問題でした。

ひとまずトップページのHTMLのソースコードを読むと、いかにも怪しいJavaScriptコードがありました。

/web004/

<script>!function(){var ref = document.referrer;var domain = ref.match(/^http([s]?):\/\/([a-zA-Z0-9-_\.]+)(:[0-9]+)?/)[2];if(domain == "www.google.com" || domain == "www.google.co.jp" ){location.href = atob('aHR0cHM6Ly9jdGYuc2V0b2Rhbm90ZS5uZXQvd2ViMDA0L2JXRnNhMmwwLmh0bWw=');}}();</script>

Base64の部分「aHR0cHM6Ly9jdGYuc2V0b2Rhbm90ZS5uZXQvd2ViMDA0L2JXRnNhMmwwLmh0bWw=」をデコードすると「https://ctf.setodanote.net/web004/bWFsa2l0.html」というURLが得られます。

f:id:reinforchu:20210906134144p:plain

web004: Base64

/web004/bWFsa2l0.htmlにアクセスします。

f:id:reinforchu:20210906134306p:plain

web004: Nice try!

それではBurpのProxyログを見てみましょう。

f:id:reinforchu:20210906134717p:plain

web004: Burp redirect log

各ログを眺めるとそれらしきJavaScriptコードを発見しました。

/web004/b25lLXR3by10aHJlZQ/?callback=wantFlag&data1=2045&data2=0907&data3=BiancoRoja&data4=1704067200

    <script>
      !function() {
        var params = new URL(window.location.href).searchParams;
        if (params.get('callback') == 'getFlag') {
}else{
          location.href = 'https://ctf.setodanote.net/web004/ZGFtbXlmbGFn/?' + params;
}
      }();
      </script>

上記のJavaScriptコードから、callbackパラメータの値がgetFlagの場合に画面遷移が分岐します。

callbackの値をwantFlagからgetFlagに書き換えて開いてみます。

/web004/b25lLXR3by10aHJlZQ/?callback=getFlag&data1=2045&data2=0907&data3=BiancoRoja&data4=1704067200

f:id:reinforchu:20210906140158p:plain

web004: getFlag

最終的にはnoisy-king-d0da.setodanote.netに飛ばされるようになりました。

f:id:reinforchu:20210906140308p:plain

web004: flag

flag{Analyz1ng_Bad_Red1rects}

OSINT

序盤の問題は易しかったが、最後の2問が本当に分からなかった。個人的にN-th_primeをOSINTとしてちゃんと解けたのは嬉しかったです。

tkys_with_love

30pt問題。コールサインC6DF6の乗り物の正式名称がflagであり、スペース文字がある場合はアンダースコアで繋ぐ問題でした。

「コールサイン C6DF6」でGoogle検索をします。

シンフォニーオブザシーズ / Symphony of the Seas - idyllicocean

がヒットするので、船名(英語表記)の項目を参照します。

f:id:reinforchu:20210906185656p:plain

tkys_with_love: C6DF6

Symphony of the Seasなのでflagは下記の通りです。

flag{Symphony_of_the_Seas}

Dorks

50pt問題。要約がややこしいので、問題文を下記に引用します。

あなたは組織が所有するドメインに関係するサイトの中で login.php が不用意に公開されていないかを Google を使って確認するように依頼を受けました。login.php が利用されているかどうかは、ある5文字の検索演算子をひとつ使えば調査することができそうです。

Google で login.php を URL に含むページを検索するための検索語句を検索演算子を含めてすべて小文字 でフラグ形式にして答えてください。

例えばファイルタイプを限定する filetype の検索演算子で pdf を検索するための検索語句を答える場合は flag{filetype:pdf} となります。

「Google 検索 演算子」でGoogle検索します。

support.google.com

特定の文字列をURLに含める検索演算子で5文字のものを探します。

f:id:reinforchu:20210906190545p:plain

Dorks: inurl

flag{inurl:login.php}

filter_op

50pt問題。要約がややこしいので、問題文を下記に引用します。

Twitter アカウント @cas_nisc が2017年5月15日にツイートした注意喚起に付与されている英字のハッシュタグをフラグ形式で答えてください。例えば付与されていたのが「#HashTag」であればフラグは flag{#HashTag} となります。

Twitter検索にはfrom: since: until:が使えることは知っていたので、そのとおりに検索しました。クエリは「from:cas_nisc since:2017 until:2017-5-16」です。URLにすると「https://twitter.com/search?q=from%3Acas_nisc%20since%3A2017%20until%3A2017-5-16&src=typed_query&f=live」です。

f:id:reinforchu:20210906192838p:plain

filters_op: Twitter

当該ツイートのURLはこちらです。

https://twitter.com/cas_nisc/status/864058208536543232

flag{#WannaCrypt}

MAC

50pt問題。要約がややこしいので、問題文を下記に引用します。

友人が簡単な暗号を作ったから意見を聞かせてほしいと言ってきました。公開情報に基づき解くことができるといいます。あなたは暗号文を解いてみることにしました。

00:03:93 = A
00:01:A9 = B
04:2A:E2 = C

上記の通り変換されるとき、以下の文字列はどうなるか。

flag{2C:C2:60_FC:EC:DA_00:02:B3_AC:44:F2_FC:4E:A4}

暗号文を解きフラグを得てください。

問題名がMACで:区切りのHEXで3つあるということは、MACアドレスのベンダー名で間違いないでしょう。例題も推測でき、Apple, Brocade, Ciscoの頭文字をとったものと思われます。

こちらのWebツールで参照しました。

uic.jp

一応、例題を確認しておきましょう。(めっちゃ気になるので。)

f:id:reinforchu:20210906193653p:plain

MAC: Example

BはBMWでしたか。失礼しました。ベンダー名を暗記している人いたらすごいな。それでは、flagを解きましょう。

Input

2C:C2:60
FC:EC:DA
00:02:B3
AC:44:F2
FC:4E:A4

f:id:reinforchu:20210906194056p:plain

MAC: flag

flag{O_U_I_Y_A}

tkys_eys_only

50pt問題。画像ファイルが配布されました。問題文には「所在地に最も関係する組織の名称を英語表記で答えてください。名称にスペースがある場合はアンダースコアに置換しフラグ形式で回答してください。」とありました。

f:id:reinforchu:20210906195338j:plain

screen.jpg

ある特定の位置の気象情報のスクリーンショットがノイジーですが、文字は見えるのでアドレスバーから緯度経度を読み取ります。

GEO

lat=40.749444, lon=-73.968056

あとはGoogle Mapに投げるだけです。

https://www.google.co.jp/maps/place/国際連合本部ビル/@40.749444,-73.968056,20z/data=!4m5!3m4!1s0x89c2591ce0874d11:0xc5fae28bdd3df635!8m2!3d40.7488758!4d-73.9680091

f:id:reinforchu:20210906200218p:plain

tkys_eys_only: Google Map

場所は国際連合本部ビルなので、正式な組織名は国際連合(United Nations)です。

ちなみにスクリーンショットの元のURLは下記だと思われます。

https://forecast.weather.gov/MapClick.php?lat=40.749444&lon=-73.968056&unit=0&lg=english&FcstType=graphical

flag{United_Nations}

MITRE

100pt問題。問題名からMITRE ATT&CK®に関連するものと推測され、下記の文字列が問題文にありました。

T1495T1152T1155T1144 T1130T1518 flag{T1170T1118T1099T1496T1212_T1531T1080T1127T1020T1081T1208_T1112T1098T1199T1159T1183T1220_T1111T1147T1220}

T数字で区切られた文字列ですが、これはMITRE ATT&CK®の共通識別子です。この最初の行だけで「FLAG IS」なんだろうな、ということが推測できました。

解法は、Google検索で「MITRE T0000」とひたすら検索しました。

最初の行

T1495:Firmware Corruption

T1152:Launchctl

T1155:AppleScript

T1144:Gatekeeper Bypass

 

T1130:Install Root Certificate

T1518:Software Discovery

各識別子タイトルの頭文字に注目し並べると「FLAG IS」となりました。これで解答にたどり着けるようになりました。今回、この問題に関してはログ(メモ)をとってなかったので各識別子の一覧は割愛しますが、最終的なflagは下記の通りでした。

flag{MITRE_ATTACK_MATLIX_THX}

Ropeway

120pt問題。配布された写真の場所を答える問題でした。問題文には「ロープウェイ名称を英小文字のフラグ形式で答えてください。例えばロープウェイの名前が「瀬戸田ロープウェイ」の場合、フラグは flag{setoda} となります。」とありました。

f:id:reinforchu:20210906202647j:plain

ropeway.jpg

普通に写真から読み取れるキーボードでGoogle検索をします。

「ロープウェイ 湖」

f:id:reinforchu:20210906202959p:plain

Ropeway: Google search

トップにヒットしたページを見てみます。

https://www.kanzanji-ropeway.jp/

f:id:reinforchu:20210906203050p:plain

Ropeway: www.kanzanji-ropeway.jp

ロープウェイ、湖、観覧車、建造物、すべてが合致しているのでこの場所で間違いないでしょう。正式名称はURLのドメイン名を参照しました。

flag{kanzanji}

N-th_prime

200pt問題。flagは72057594037927936番目の素数だという。

Google検索ではなくGitHubのリポジトリ検索をすれば良かったのでした。

github.com

この検索結果のnthprime.xを開きます。

github.com

f:id:reinforchu:20210906204102p:plain

N-th_prime: 72057594037927936th

72057594037927936th prime number

2991614170035124397

flag{2991614170035124397}

identify_the_source

250pt問題。謎のバイナリファイルが渡されました。そのファイルの配布元URLを特定してflagを得る問題でした。

f:id:reinforchu:20210906225133p:plain

tsuru

ひたすら「TSURU」が紛れ込んでいるファイルで、結局解けませんでした。

Incorrect

secret_operation

300pt問題。一つの画像ファイルが配布され、その情報からOSINTしてflagを獲得する問題でした。

f:id:reinforchu:20210906225520j:plain

operation-sculd.jpg

試行錯誤はしたものの、結局解けませんでした。

Incorrect

 

Crypto

なんだかんだ、一番熱狂したカテゴリだったと思います。最終問題のWEARECIAは競技終了30分前にflagを提出して白熱しました。全問回答しました!

base64

50pt問題。問題名の通りBase64文字列をデコードするだけでした。

base64

ZmxhZ3tJdCdzX2NhbGxlZF9iYXNlNjQhfQ==

f:id:reinforchu:20210906230128p:plain

base64: Decode

flag{It's_called_base64!}

ROT13

50pt問題。問題名の通りROT13するだけでした。

Cipher

synt{Rira_lbh_Oehghf?}

手前味噌ですが、自作のツールで解けました。

github.com

Plaintext

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}_?

Ciphertext

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm{}_?

Cipher

synt{Rira_lbh_Oehghf?}

Decrypted

flag{Even_you_Brutus?}

f:id:reinforchu:20210906232048p:plain

ROT13: flag

ところでROT13とは、ざっくり説明すると文字列表を13字ずらした暗号のことで、単一換字式暗号と呼ばれます。この単一換字式暗号を解説しツールをC#で開発した記事を書いたので、興味のある方はご覧ください。

www.hack.vet

flag{Even_you_Brutus?}

pui_pui

80pt問題。Hexの文字列が与えられました。

Hexdump

\x41\x3a\x44\x6f\x20\x79\x6f\x75\x20\x6b\x6e\x6f\x77\x20\x4d\x6f\x6c\x63\x61\x72\x3f\x0a\x0a\x42\x3a\x4f\x66\x20\x63\x6f\x75\x72\x73\x65\x21\x20\x49\x20\x6c\x6f\x76\x65\x20\x74\x68\x65\x20\x73\x63\x65\x6e\x65\x20\x77\x68\x65\x72\x65\x20\x68\x65\x20\x73\x69\x6e\x6b\x73\x20\x69\x6e\x74\x6f\x20\x74\x68\x65\x20\x62\x6c\x61\x73\x74\x20\x66\x75\x72\x6e\x61\x63\x65\x20\x77\x68\x69\x6c\x65\x20\x67\x69\x76\x69\x6e\x67\x20\x74\x68\x65\x20\x74\x68\x75\x6d\x62\x73\x20\x75\x70\x2e\x0a\x0a\x41\x3a\x2e\x2e\x2e\x20\x57\x68\x61\x74\x3f\x0a\x0a\x42\x3a\x62\x74\x77\x2c\x20\x74\x68\x65\x20\x66\x6c\x61\x67\x20\x69\x73\x20\x66\x6c\x61\x67\x7b\x48\x61\x76\x65\x5f\x79\x6f\x75\x5f\x65\x76\x65\x72\x5f\x68\x65\x61\x72\x64\x5f\x6f\x66\x5f\x48\x65\x78\x64\x75\x6d\x70\x3f\x7d\x2e\x0a

CyberChefでASCII文字列に変換しました。

f:id:reinforchu:20210906234305p:plain

pui_pui: CyberChef

Output

A:Do you know Molcar?

B:Of course! I love the scene where he sinks into the blast furnace while giving the thumbs up.

A:... What?

B:btw, the flag is flag{Have_you_ever_heard_of_Hexdump?}.

flag{Have_you_ever_heard_of_Hexdump?}

tkys_secret_service

120pt問題。意味不明な英字の羅列がこの問題の暗号文でした。

Cipher

Gur cevgrsgbvh vp Pvhgevyyrq Hhsynmmbpbrq Vhpvezngbvh (PHV) ermbqrhg bh hvhprqreny mlmgrzm nhq vetnhbfngbvhm bm vp cnenzvahg bzcvegnhsr gv prqreny ntrhsbrm nhq snh qbersgyl bzcnsg gur nobybgl vp gur prqreny tvirehzrhg gv massrmmpayyl svhqasg bgm rmmrhgbny zbmmbvhm nhq pahsgbvhm. Gubm caoybsngbvh cevibqrm ntrhsbrm jbgu ersvzzrhqrq mrsaebgl erdaberzrhgm pve cevgrsgbht gur svhpbqrhgbnybgl vp PHV jurh gur bhpvezngbvh bm ermbqrhg bh hvhprqreny mlmgrzm nhq vetnhbfngbvhm; jurh gur hvhprqreny vetnhbfngbvh bm hvg svyyrsgbht ve znbhgnbhbht bhpvezngbvh vh orunyp vp n prqreny ntrhsl ve ambht ve vcrengbht n mlmgrz vh orunyp vp nh ntrhsl; nhq jurer gurer ner hv mcrsbpbs mnprtaneqbht erdaberzrhgm pve cevgrsgbht gur svhpbqrhgbnybgl vp Synt bm pynt{cabcab_sne_vp_zvy} PHV cermseborq ol gur naguvebfbht ynj, ertayngbvh, ve tvirehzrhgjbqr cvybsl pve gur PHV sngrtvel ybmgrq bh gur PHV Ertbmgel. Gur erdaberzrhgm nccyl gv nyy svzcvhrhgm vp hvhprqreny mlmgrzm nhq vetnhbfngbvhm gung cevsrmm, mgver, nhq/ve genhmzbg PHV, ve gung cevibqr cevgrsgbvh pve masu svzcvhrhgm. Gur mrsaebgl erdaberzrhgm ner bhgrhqrq pve amr ol prqreny ntrhsbrm bh svhgensgany irubsyrm ve vgure nterrzrhgm rmgnoybmurq orgjrrh guvmr ntrhsbrm nhq hvhprqreny vetnhbfngbvhm.

分かち書き的に英文です。これも単一換字式暗号でしたが、今回ばかりは単純ではないようです。pyntはflagなど推測できるパターンと、英単語辞書を頼りに手作業で解読しました。

解読にあたっては下記のWebツールを使用しました。

Simple substitution cipher

換字ルールは下記の通りです。

f:id:reinforchu:20210906235908p:plain

tkys_secret_service: Key

Output

The protection of Fontrolled Nnclassified Onformation (FNO) resident in nonfederal systems and organizations is of paramount importance to federal agencies and can directly impact the ability of the federal government to successfully conduct its essential missions and functions. This publication provides agencies with recommended security requirements for protecting the confidentiality of FNO when the information is resident in nonfederal systems and organizations; when the nonfederal organization is not collecting or maintaining information on behalf of a federal agency or using or operating a system on behalf of an agency; and where there are no specific safeguarding requirements for protecting the confidentiality of Clag is flag{puipui_car_of_mol} FNO prescribed by the authorizing law, regulation, or governmentwide policy for the FNO category listed in the FNO Registry. The requirements apply to all components of nonfederal systems and organizations that process, store, and/or transmit FNO, or that provide protection for such components. The security requirements are intended for use by federal agencies in contractual vehicles or other agreements established between those agencies and nonfederal organizations.

合っているか少々不安ですが、flagは読めるので良しとしましょう。

flag{puipui_car_of_mol}

lets_bake

150pt問題。InputとRecipeが渡されました。これは問題名から使用するツールを特定しないと解くのは難しいでしょう。

Input

NzRmNDRiMWE0Y2M2ZGNiNzc3NTMyNTcwZjk0MTE4NTMyNTcxZjE1YTE1NTJkY2M0

Recipe

RnJvbV9CYXNlNjQoJ0EtWmEtejAtOSsvPScsdHJ1ZSkN]b2[sRnJvbV9IZXgoJ05vbmUnKQ0=]b2[sRm9yaygnJScsJ18nLGZhbHNlKQ0=]b2[sUkM0KHsnb3B0aW9uJzonVVRGOCcsJ3N0cmluZyc6J2NoZWYnfSwnTGF0aW4xJywnTGF0aW4xJyk=

「bake」で「Recipe」といえば、CyberChefですね!少しCyberChefのRecipeの解説が必要そうです。Recipeというのは、CyberChefのURLのアンカーリンクにRecipe情報がくっつくのですが、そのことを指します。CyberChefはローカル環境でも動かせますが、オンライン版で例えば次のURLが参考になります。

https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)&input=Wm14aFozdDk

URLの#以降のrecipeパラメータのFrom_Base64('A-Za-z0-9+/=',true)に注目してください。これが今回の問題のRecipeに該当する要素です。

では本題に戻りまして、問題を解いていきましょう。RecipeはBase64っぽいですが、明らかにおかしな記号「]」と「[」が混入していますし、]b2[ってなんだろうか、とりあえずデコードしてみました。

f:id:reinforchu:20210907064821p:plain

lets_bake: Recipe decode

やはり最初のFrom_Base64('A-Za-z0-9+/=',true)はRecipeとして読めますが、]b2[以降が読めないです。しかし、これまで散々Base64を脳内でデコードしてきたので、]b2[sというのがゴミデータと仮定して、各Base64エンコード部分毎に改行区切りでBurpでデコードしてみました。

Input

RnJvbV9CYXNlNjQoJ0EtWmEtejAtOSsvPScsdHJ1ZSkN
]b2[s
RnJvbV9IZXgoJ05vbmUnKQ0=
]b2[s
Rm9yaygnJScsJ18nLGZhbHNlKQ0=
]b2[s
UkM0KHsnb3B0aW9uJzonVVRGOCcsJ3N0cmluZyc6J2NoZWYnfSwnTGF0aW4xJywnTGF0aW4xJyk=

Output

From_Base64('A-Za-z0-9+/=',true)
]b2[s
From_Hex('None')
]b2[s
Fork('%','_',false)
]b2[s
RC4({'option':'UTF8','string':'chef'},'Latin1','Latin1')

f:id:reinforchu:20210907065316p:plain

lets_bake: Get Recipe!

お、読めました!🎯あたりです。]b2[sが一体何なのか分からずじまいですが、Recipeが読めたので良しとしましょう。それでは、このRecipeを使って問題文のInputの暗号文をLet's BAKE!

f:id:reinforchu:20210907065942p:plain

lets_bake: flag

flag{hello_baked_cipher}

vul_rsa_01

200pt問題。RSA暗号を解く問題でした。数値c, n, eが与えられました。

c

39119617768257067256541748412833564043113729163757164299687579984124653789492591457335

n

13373801376856352919495636794117610920860037770702465464324474778341963699665011787021257

e

65537

これはnの数の大きさに注目してください。nの値が小さくはありませんか。最近ではnが小さいと簡単に素因数分解ができます。RSA暗号の勉強には、こちらのスライドを参考にしました。

www.slideshare.net

さて、解法ですがコード書けば良いのに、なにぶん時間に追われてしまったので、RsaCtfToolというそのままの名前のPythonコードを流用しました。

github.com

Command

python3 ./RsaCtfTool.py -n 13373801376856352919495636794117610920860037770702465464324474778341963699665011787021257 -e 65537 --uncipher 39119617768257067256541748412833564043113729163757164299687579984124653789492591457335

Output

utf-8 : flag{weak_rsa_can_be_decrypted!}

STR : b'\x00\x00\x00\x00\x00flag{weak_rsa_can_be_decrypted!}'

flag{weak_rsa_can_be_decrypted!}

vul_rsa_02

250pt問題。RSA暗号を解く問題でした。数値c, n, eが与えられました。しかし、今回ばかりはわけが違うようです。

c

227982950403746746755552239763357058548502617805036635512868420433061892121830106966643649614593055827188324989309580260616202575703840597661315505385258421941843741681

n

314346410651148884346780415550080886403387714336281086088147022485674797846237037974025946383115524274834695323732173639559408484919557273975110018517586435379414584423

e

66936921908603214280018123951718024245768729741801173248810116559480507532472797061229726239246069153844944427944092809221289396952390359710880636835981794334459051137

各数値が大きいです、大きいということは。これはeの値に注目してください。eの値が大きすぎるとWiener's Attackが成立する可能性が高いです。Wiener's Attackについては次の記事を参考にしました。

sites.google.com

そして解法ですが、なにぶんまた時間に追われてしまったので、RsaCtfToolのPythonコードを流用しました。

Commnad

python3 ./RsaCtfTool.py -n 314346410651148884346780415550080886403387714336281086088147022485674797846237037974025946383115524274834695323732173639559408484919557273975110018517586435379414584423 -e 66936921908603214280018123951718024245768729741801173248810116559480507532472797061229726239246069153844944427944092809221289396952390359710880636835981794334459051137 --uncipher 227982950403746746755552239763357058548502617805036635512868420433061892121830106966643649614593055827188324989309580260616202575703840597661315505385258421941843741681

Output

utf-16 : Ȁ祭ﮦ璢堙苎⡆꥕쑮ᛜጣﰼᔴ鉹⻀릷ꏠ뢻r汦条ㅻ㜹䵟捩慨汥䩟坟敩敮彲㜶紳

STR : b'\x00\x02my\xa6\xfb\xa2t\x19X\xce\x82F(U\xa9n\xc4\xdc\x16#\x13<\xfc4\x15y\x92\x0b\xef\xc0.\xb7\xb9\xe0\xa3\xbb\xb8r\x00flag{197_Michael_J_Wiener_673}'

flag{197_Michael_J_Wiener_673}

WEARECIA

300pt問題。筆者の意向により、下記に問題文をそのまま引用します。

家に帰ると黒い封筒が郵便受けに入っていました。封筒の中身は英字が羅列されたメモが一枚。青銅色の紙に白いインクで書かれており右下には同じインクで WEARECIA と記載されています。どうやら暗号文のようです。暗号文を解析してメッセージを受け取る必要がありそうです。

以下の暗号文を解読し、隠されたメッセージを見つけてください。フラグは得られたメッセージを flag{} で囲んで回答してください。

EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFDRCDNKFRHHMKVLLTGBMFDUTMALDUMKYQTGLWLWCM

WEARECIAという問題名もヒントになっており、分かち書きすると、WE ARE CIAつまりCIAの暗号文ということです。CIAの暗号文といえば、あの有名なクリプトスです。なぜここまで断定できたかというと、与えられた暗号文の前半部分がクリプトスのK1と全く同じということに気づいたからです。

クリプトス K1

EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFD

ここまで分かってしまえば、暗号文を解読する鍵は既知なので、普通に解読するだけです。その前にクリプトス K1の暗号文について少し触れておきます。クリプトス K1の暗号文は、ヴィジュネル暗号(Vigenère cipher)が使われており、ヴィジュネル方陣と鍵が分かれば暗号文を解くことが可能です。

解読にあたっては、下記のWebツールを使用しました。(コードを書いても良かったのですが、競技終了ぎりぎりだったのでオンラインツールでしのぎました。)

Vigenère - CrypTool Portal

Encrypted text

EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFDRCDNKFRHHMKVLLTGBMFDUTMALDUMKYQTGLWLWCM

Key

PALIMPSEST

Alphabets(方陣)

KRYPTOSABCDEFGHIJLMNQUVWXZ

Plaintext

BETWEENSUBTLESHADINGANDTHEABSENCEOFLIGHTLIESTHENUANCEOFIQLUSIONFLAGISWEARETHENATIONSFIRSTLINEOFDEFENSE

f:id:reinforchu:20210907081038p:plain

WEARECIA: flag

flagは見えてますが、せっかくなので分かち書きして原文を見てみましょう。

Original message

BETWEEN SUBTLE SHADING AND THE ABSENCE OF LIGHT LIES THE NUANCE OF IQLUSION FLAG IS WE ARE THE NATIONS FIRST LINE OF DEFENSE

クリプトスおよびヴィジュネル暗号についての解読の勉強には、下記の記事を参考にしました。

nekonohige.minmike.com

Wikipediaにも載っていますが、クリプトス K1の鍵は、ヴィジュネル方陣がKRYPTOS、鍵がPALIMPSESTです。つまずきポイントは、ヴィジュネル方陣がKRYPTOSからはじまること、ヴィジュネル方陣に重複して同じ文字が出現しないこと([A-Z]の順番ですがSkipする)です。

flagはFLAGIS以降の文字列でした。

flag{WEARETHENATIONSFIRSTLINEOFDEFENSE}

 

Rev

鬼問題は出てないですが、ELFのリバースエンジニアリングがやっぱり苦手で苦労しました。意外にも全問回答できました。

Helloworld

50pt問題。PEの実行形式ファイルが配布されるので、そのPEを実行してflagを得る問題でした。

何も解析しませんでした。何も考えずに、第一引数にflagという文字列を渡せば通るんじゃないかな、というベタな発想でflagを獲得しました。

f:id:reinforchu:20210907131230p:plain

Helloworld: flag

Prompt log

C:\Users\reinforchu>C:\Users\reinforchu\Desktop\helloworld.exe flag flag{free_fair_and_secure_cyberspace}

flag{free_fair_and_secure_cyberspace}

ELF

80pt問題。バイナリファイルが配布されました。どうやらこれを実行するとflagを得ることができるそうです。

まずfileコマンドで何者か簡単に調べました。

Command

file elf

Terminal log

elf: data

問題名を汲み取ってバイナリエディタで開いてみます。

f:id:reinforchu:20210907132327p:plain

ELF: Hex

頭がXXXXで潰されていました。XXXXの箇所をELF(Executable and Linkable Format)のマジックナンバーに書き換えます。

Modify

58 58 58 58 -> 7F 45 4C 46

Linux(Ubuntu)で実行します。

f:id:reinforchu:20210907133600p:plain

ELF: flag

flag{run_makiba}

Passcode

120pt問題。ELF実行形式ファイルが配布されました。パスコードが合っていないとflagを出してくれない問題でした。

まずは実行形式してみます。

f:id:reinforchu:20210907134155p:plain

Passcode: Exec

パスコードを解析する必要性がありそうです。ここはIDA Freeで見てみましょう。まずはStringsでパスコードがハードコードされてないか分析します。

f:id:reinforchu:20210907134736p:plain

Passcode: Strings

20150109といういかにもパスコードっぽい文字列を発見しました。パスコードはこの文字列で試しました。

f:id:reinforchu:20210907135303p:plain

Passcode: flag

正解のようです。flagも通りました。

flag{20150109}

Passcode2

150pt問題。ELF実行形式ファイルが配布されました。パスコードが合っていないとflagを出してくれない問題でした。今度は手強いようです。

IDA Freeで開きStringsで解析しても目ぼしい情報は得られませんでした。フロー図で処理の流れを見てみました。

f:id:reinforchu:20210907135808p:plain

Passcode2: Flow chart

loc_1439:でflagの表示の分岐をしているようです。この他、分析すべき点はありますが、ソースコードを見たほうが早いです。main関数を選択して、Pseudocode(疑似コード)を生成してみます。

f:id:reinforchu:20210907140427p:plain

Passcode2: Pseudocode main()

IDA Freeが生成した疑似コードが出てきました。

Pseudocode-A

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  size_t v4; // rax
  size_t v5; // rax
  char v6[12]; // [rsp+4h] [rbp-11Ch] BYREF
  char s[8]; // [rsp+10h] [rbp-110h] BYREF
  __int64 v8; // [rsp+18h] [rbp-108h]
  __int64 v9; // [rsp+20h] [rbp-100h]
  __int64 v10; // [rsp+28h] [rbp-F8h]
  __int64 v11; // [rsp+30h] [rbp-F0h]
  __int64 v12; // [rsp+38h] [rbp-E8h]
  __int64 v13; // [rsp+40h] [rbp-E0h]
  __int64 v14; // [rsp+48h] [rbp-D8h]
  __int64 v15; // [rsp+50h] [rbp-D0h]
  __int64 v16; // [rsp+58h] [rbp-C8h]
  __int64 v17; // [rsp+60h] [rbp-C0h]
  __int64 v18; // [rsp+68h] [rbp-B8h]
  __int64 v19; // [rsp+70h] [rbp-B0h]
  __int64 v20; // [rsp+78h] [rbp-A8h]
  __int64 v21; // [rsp+80h] [rbp-A0h]
  __int64 v22; // [rsp+88h] [rbp-98h]
  __int64 v23; // [rsp+90h] [rbp-90h]
  __int64 v24; // [rsp+98h] [rbp-88h]
  __int64 v25; // [rsp+A0h] [rbp-80h]
  __int64 v26; // [rsp+A8h] [rbp-78h]
  __int64 v27; // [rsp+B0h] [rbp-70h]
  __int64 v28; // [rsp+B8h] [rbp-68h]
  __int64 v29; // [rsp+C0h] [rbp-60h]
  __int64 v30; // [rsp+C8h] [rbp-58h]
  __int64 v31; // [rsp+D0h] [rbp-50h]
  __int64 v32; // [rsp+D8h] [rbp-48h]
  __int64 v33; // [rsp+E0h] [rbp-40h]
  __int64 v34; // [rsp+E8h] [rbp-38h]
  __int64 v35; // [rsp+F0h] [rbp-30h]
  __int64 v36; // [rsp+F8h] [rbp-28h]
  __int64 v37; // [rsp+100h] [rbp-20h]
  __int64 v38; // [rsp+108h] [rbp-18h]
  unsigned __int64 i; // [rsp+118h] [rbp-8h]

  *(_QWORD *)s = 0LL;
  v8 = 0LL;
  v9 = 0LL;
  v10 = 0LL;
  v11 = 0LL;
  v12 = 0LL;
  v13 = 0LL;
  v14 = 0LL;
  v15 = 0LL;
  v16 = 0LL;
  v17 = 0LL;
  v18 = 0LL;
  v19 = 0LL;
  v20 = 0LL;
  v21 = 0LL;
  v22 = 0LL;
  v23 = 0LL;
  v24 = 0LL;
  v25 = 0LL;
  v26 = 0LL;
  v27 = 0LL;
  v28 = 0LL;
  v29 = 0LL;
  v30 = 0LL;
  v31 = 0LL;
  v32 = 0LL;
  v33 = 0LL;
  v34 = 0LL;
  v35 = 0LL;
  v36 = 0LL;
  v37 = 0LL;
  v38 = 0LL;
  v6[0] = 24;
  v6[1] = 31;
  v6[2] = 4;
  v6[3] = 121;
  v6[4] = 79;
  v6[5] = 90;
  v6[6] = 4;
  v6[7] = 24;
  v6[8] = 26;
  v6[9] = 27;
  v6[10] = 30;
  v6[11] = 0;
  printf("Enter the passcode: ");
  if ( (unsigned int)__isoc99_scanf("%255[^\n]%*[^\n]", s) == -1 )
    return 1LL;
  __isoc99_scanf("%*c", s);
  if ( !s[0] )
    goto LABEL_16;
  if ( strlen(s) > 0xA )
  {
    if ( strlen(s) > 0xB )
    {
      printf("Invalid passcode. Too long.");
      goto LABEL_17;
    }
    if ( strlen(s) == 11 )
    {
      for ( i = 0LL; ; ++i )
      {
        v4 = strlen(v6);
        if ( i >= v4 || s[i] != ((unsigned __int8)v6[i] ^ 0x2A) )
          break;
      }
      v5 = strlen(v6);
      if ( i == v5 )
      {
        puts("The passcode has been verified.\n");
        printf("Flag is : flag{%s}", s);
      }
      else
      {
        printf("Invalid passcode. Nice try.");
      }
      goto LABEL_17;
    }
LABEL_16:
    printf("Invalid passcode.");
    goto LABEL_17;
  }
  printf("Invalid passcode. Too short.");
LABEL_17:
  putchar(10);
  return 0LL;
}

さてここからが本番です。筆者は、少々C言語とELFには疎いので、この疑似コードを元にPEで実行できるようにVisual Stadio 2019でC++ .NETに書き換えて(移植)デバッグしていきます。

その前に、疑似コードから重要な処理ロジックを紐解きます。

パスコードの文字列の長さは11

if ( strlen(s) == 11 )

12文字分のchar型の数値が格納されている

  v6[0] = 24;
  v6[1] = 31;
  v6[2] = 4;
  v6[3] = 121;
  v6[4] = 79;
  v6[5] = 90;
  v6[6] = 4;
  v6[7] = 24;
  v6[8] = 26;
  v6[9] = 27;
  v6[10] = 30;
  v6[11] = 0;

最後はNULL文字なので11文字とみて良いでしょう。つまりこれがパスコードであることが推定できます。

for-loopでv6の変数を一つづつ取り出して0x2AでXOR(排他的論理和)をしている

      for ( i = 0LL; ; ++i )
      {
        v4 = strlen(v6);
        if ( i >= v4 || s[i] != ((unsigned __int8)v6[i] ^ 0x2A) )
          break;
      }

変数v6をXORした値がパスコードと推定することが出来ます。パスコードを確認するために、一文字ずつ取り出してprintf()するコードに書き換えます。

v6[i] ^ 0x2Aの確認

for (i = 0; i < 11 ; ++i)
{
int y = v6[i] ^ 0x2A;
printf("%c", y);
//if (i >= v4 || s[i] != ((unsigned __int8)v6[i] ^ 0x2A))

}
printf("\n");

様々修正してWindowsでデバッグできるようにしたソースコードが下記です。書き捨てで汚くてすみません。

passcode2_win.cpp

#include 

#pragma warning(disable : 4996) 

int main(void)
{
    size_t v4; // rax
    size_t v5; // rax
    char v6[12]; // [rsp+4h] [rbp-11Ch] BYREF
    char s[8]; // [rsp+10h] [rbp-110h] BYREF
    unsigned __int8 i; // [rsp+118h] [rbp-8h]

    v6[0] = 24;
    v6[1] = 31;
    v6[2] = 4;
    v6[3] = 121;
    v6[4] = 79;
    v6[5] = 90;
    v6[6] = 4;
    v6[7] = 24;
    v6[8] = 26;
    v6[9] = 27;
    v6[10] = 30;
    v6[11] = 0;
    printf("Enter the passcode: ");
    if ((unsigned int)scanf("%255[^\n]%*[^\n]", s) == -1)
        // return 1LL;
     scanf("%*c", s);
    if (!s[0])
        goto LABEL_16;
    if (strlen(s) > 0xA)
    {
       if (strlen(s) > 0xB)
        {
            printf("Invalid passcode. Too long.");
            goto LABEL_17;
        }
        if (strlen(s) == 11)
        {
            for (i = 0; i < 11 ; ++i)
            {
                int y = v6[i] ^ 0x2A;
                printf("%c", y);
               //if (i >= v4 || s[i] != ((unsigned __int8)v6[i] ^ 0x2A))

            }
            printf("\n");
            v5 = strlen(v6);
            if (i == v5)
            {
                puts("The passcode has been verified.\n");
                printf("Flag is : flag{%s}", s);
            }
            else
            {
                printf("Invalid passcode. Nice try.");
            }
            goto LABEL_17;
        }
    LABEL_16:
        printf("Invalid passcode.");
        goto LABEL_17;
    }
    printf("Invalid passcode. Too short.");
LABEL_17:
    putchar(10);
    // return 0LL;
}

それではビルドしてデバッグしていきます。最初のscanf()は適当に11文字を入れておきます。

f:id:reinforchu:20210907143123p:plain

Passcode2: Cracked

XORしている文字列が25.Sep.2014と判明しました。これがパスコードであり、flagであると推定できました。一応、オリジナルのELF版でも確認しておきます。

f:id:reinforchu:20210907143724p:plain

Passcode2: flag

正解のようです。flagも通りました。

flag{25.Sep.2014}

to_analyze

200pt問題。PEの実行形式ファイルが配布されました。しかし、問題文には「特定の環境で実行した場合のみ情報が表示される仕組みのようだが条件が特定できない。」と記載があり、特定の環境を解析してflagを得る必要性がありました。

まず、普通に実行してみます。

f:id:reinforchu:20210907150846p:plain

to_analyze: nice try!

nice try!匂いがしました。そう、.NET Frameworkの。

EXEをdnSpy(32 bit)に投げてデコンパイルしてソースコードを見ました。ソースコードが分かればこっちのものです。様々分析する箇所はありますが、A_0という変数が何かしらの文字列であることが分かりました。

f:id:reinforchu:20210907151257p:plain

to_analyze: Breakpoint

さらにflagを表示させるコード付近にDirectory.Exists(A_0)というディレクトリの存在を確認するメソッドが使われていました。ここにブレークポイントを置きデバッグしていきます。

f:id:reinforchu:20210907151935p:plain

to_analyze: A_0

A_0の正体がC:\Users\321txtということが分かりました。つまり、特定の環境というのはC:\Users\321txtのディレクトリが存在する場合に、flagを表示させるというロジックでした。では、実際にC:\Usersに321txtというディレクトリを作成し実行してみます。

Command

mkdir C:\Users\321txt

f:id:reinforchu:20210907152419p:plain

to_analyze: flag

これが特定の環境で、正解でした。

flag{Do_y0u_Kn0w_Ursnif?}

 

Forensics

力業で解いた問題が一つありましたが、最後に残ったTITLE問が解けなかったのが悔しかったです。

paint_flag

50pt問題。Wordドキュメント(.docx)が配布されました。加工されたflagが載っているそうです。

Wordドキュメントを開いてみます。

f:id:reinforchu:20210907154416p:plain

paint_flag.docx

確かにflagは加工されていました。このドキュメントは.docxです。アーカイブ形式でもあるので、アーカイバで展開してみます。

f:id:reinforchu:20210907154911p:plain

paint_flag: media

word\mediaに加工されていないflagのイメージファイルを見つけました。

f:id:reinforchu:20210907155104p:plain

flag.png

flag{What_m4tters_is_inside;)}

Mail

50pt問題。Thunderbirdのメールボックスがそのまま配布されました。メールにflagがないか調査する問題でした。

配布されたファイル群は以下の通りです。

f:id:reinforchu:20210907155705p:plain

Mail: IMAP

641KBのファイルサイズのあるSent-1が怪しそうです。従って、Thunderbirdのメールボックスに投げれば良いのですが、結局平文なのでNotepadで開きました。

f:id:reinforchu:20210907160045p:plain

Mail: Sent-1

kimitsu.zipというファイルがBase64でエンコードされた情報を発見しました。少々面倒ですが、CyberChefなどでデコードしてバイナリをそのままダウンロードして開きます。goodjob.pngというイメージファイルが出てくるので、それを開きます。

f:id:reinforchu:20210907160353p:plain

goodjob.png

flag{You've_clearly_done_a_good_job_there!!}

Deletedfile

80pt問題。重要なflagを削除されてしまったそうです。ディスクイメージファイルが配布されるので、削除されたファイルを復元し、flagを得る問題でした。

念の為、fileで確認しておきました。

Command log

reinforchu@ReinPro Downloads % file deletedfile.raw 

deletedfile.raw: DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system"; partition 1 : ID=0xee, start-CHS (0x0,0,2), end-CHS (0x0,254,63), startsector 1, 4294967295 sectors

OSFMountでrawディスクイメージを普通にマウントします。

f:id:reinforchu:20210907161828p:plain

Deletedfile: OSFMount

本当に適当なファイル復元ソフトを使います。今回はEaseUS Data Recovery Wizardを使いました。flagらしきイメージファイルを復元してみます。

f:id:reinforchu:20210907162022p:plain

Deletedfile: Recovery

ファイルの復元に成功しました。

f:id:reinforchu:20210907162440j:plain

Deletedfile: flag

flag{nosce_te_ipsum}

Timeline

100pt問題。Windowsのユーザープロファイルのディレクトリが配布された。ファイルを解析してflagを入手する問題でした。

ディレクトリ構成は下記の通りでした。

f:id:reinforchu:20210907163603p:plain

Timeline: C:\

どうやらActivitiesCache.dbを解析するものと思われます。Google検索をしたところ、WindowsTimeline parserというソフトウェアを使うと中身が見れそうです。

github.com

ActivitiesCache.dbを開いたところ、メモ帳で開いたファイル名の順番がflagになっていました。

f:id:reinforchu:20210907164343p:plain

Timeline: ActivitiesCache.db

このままでは見にくいので、Application Execution Listで絞り、更にnotepadを検索キーワードで絞ります。

f:id:reinforchu:20210907164905p:plain

Timeline: flag

ハイライトさせている部分のファイル名を上から順番につなげた文字列がflagでした。

flag{Th3_Fu7Ure_1s_N0w}

browser_db

100pt問題。SQLiteのDBがそのまま配布されました。この中からflagを見つけ出す問題でした。

個人的にDB Browser for SQLiteを使っているので、それで開きました。テーブルを探してデータ閲覧でflagを検索すれば良いです。flagはmoz_placesの中にありました。

f:id:reinforchu:20210907165749p:plain

browser_db: flag

flag{goosegoosego}

MFT

100pt問題。C_$MFTというファイルが配布されました。問題文をそのまま引用します。

内部告発によりある要員が極秘情報をファイルサーバからダウンロードしていることが判明しました。組織は要員の身柄を抑え、端末から証拠となるデータを抽出しました。今回のあなたの仕事は、端末から抽出したデータを解析し、ダウンロードされた極秘情報のファイル名を特定することです。組織からは極秘情報のダウンロードされた日時が 2021-07-18 18:30頃 であることと、ファイルサイズが 465030 であることのみが伝えられています。

添付ファイルを解析し、極秘情報のファイル名を特定してください。例えばファイル名が file.txtの場合は flag{file.txt} と回答してください。

$MFTとはNTFS上のMaster File Tableのことで、ファイルを管理する特殊なものという認識で良くて、解析にはMFTExplorerというソフトウェアを使用しました。

Eric Zimmerman's tools

f:id:reinforchu:20210907170810p:plain

MFT: C_$MFT

ダウンロードされた極秘情報ファイルなのでC:\Users\stella\Downloadsを見るとkimitsu.zipという怪しいファイル名を見つけました。ファイルサイズはぱっと見で分かりませんでしたが、ダウンロードされた日時が 2021-07-18 18:30頃であるという情報を元に、これがflagと推定しました。flagは通りました。

flag{kimitsu.zip}

tkys_another_day

100pt問題。tkys_another_day.pngというPNGイメージファイルが配布されました。ファイルを解析してflagを得る問題でした。

ファイルmacOSの標準のPreview.appで開きました。

f:id:reinforchu:20210907171904p:plain

tkys_another_day: flag

なるほどそういうことか、と思いました。flagはそのまま見えてしまっているので、そのまま文字列をつなげて提出しました。

flag{a_fake_illness_is_the_most_serious_disease_f5ab7}

TITLE

120pt問題。問題文をそのまま引用します。

仕事を終えて帰宅の途につくあなた。人通りの少ない住宅街を通り過ぎ、自宅のマンションにたどり着きます。ちょうど部屋のドアの前に立った時に手に持っていた携帯が鳴りメールを受信したことを伝えます。

件名:これが最後の警告だ

そのメールには画像が添付されていました。
 

添付されたファイルを解析し、フラグを得てください。

f:id:reinforchu:20210907172310j:plain

lo3rs1tkd.jpg

シュタインズ・ゲートだと思い、様々な手法で解析しましたが、結局解けませんでした。

“最後まで見ないといけない”

Incorrect

CSIRT_asks_you_01

150pt問題。Windowsのイベントログが配布されました。問題文をそのまま引用します。

組織内のインシデント対応部署から急ぎ解析してほしいとの依頼が舞い込みました。不正侵入が確認された端末の Windows イベントログの調査で、状況把握のために侵害に関する詳細な日時を確認してほしいということのようです。

今回のあなたの仕事は送られてきたファイルを解析し、不正な方法によってネットワーク経由のログインが成功したことを示している最初の記録日時(TimeCreated SystemTime) と Event ID を特定することです。

フラグは UTC での記録日時 を yyyy/mm/dd_hh:mm:ss 形式にし、最後に Event ID をアンダースコアでつなげた形で答えてください。例えば 記録日時 が 2020/01/10 7:05:13.9234567Z 、Event ID が 1234 の場合は flag{2020/01/10_07:05:13_1234} となります。記録日時は UTC+0 で回答することに注意してください。

配布されたイベントログをWindowsのイベントビュアーで開きます。ログをななめ読みすると、ログオンの失敗が大量にSecurityログに残っていました。この問題は、一番最初にネットワーク経由でログオンが成功した監査ログを手作業で調べました。特に楽なことはしませんでした。

f:id:reinforchu:20210907174136p:plain

CSIRT_asks_you_01: Suspicious logon

flagはUTC+0で回答する必要性があります。便利なことに詳細タブのXML表示で、TimeCreated要素がUTC+0の時刻表記なので、そのまま転記します。

f:id:reinforchu:20210907174602p:plain

CSIRT_asks_you_01: XML

flag{2021/07/18_20:09:21_4624}

unllocated_space

150pt問題。壊れているディスクイメージファイルが配布されました。この残されたデータの海からflagをサルベージする問題でした。

f:id:reinforchu:20210907175409p:plain

unallocated_space

バイナリをみてふと思った。Deletedfile問題で配布されたディスクイメージのバイナリの先頭部分を上書きして、むりやりパーティションを認識させればいいじゃないかと。

分かりやすいように、バイナリの先頭から下記の通りに書き換えます。

Modify

33C08ED0BC007C8EC08ED8BE007CBF0006B90002FCF3A450681C06CBFBB90400BDBE07807E00007C0B0F850E0183C510E2F1CD1888560055C6461105C6461000B441BBAA55CD135D720F81FB55AA7509F7C101007403FE46106660807E1000742666680000000066FF760868000068007C680100681000B4428A56008BF4CD139F83C4109EEB14B80102BB007C8A56008A76018A4E028A6E03CD136661731CFE4E11750C807E00800F848A00B280EB845532E48A5600CD135DEB9E813EFE7D55AA756EFF7600E88D007517FAB0D1E664E88300B0DFE660E87C00B0FFE664E87500FBB800BBCD1A6623C0753B6681FB54435041753281F90201722C666807BB00006668000200006668080000006653665366556668000000006668007C0000666168000007CD1A5A32F6EA007C0000CD18A0B707EB08A0B607EB03A0B50732E40500078BF0AC3C007409BB0700B40ECD10EBF2F4EBFD2BC9E464EB002402E0F82402C3496E76616C696420706172746974696F6E207461626C65004572726F72206C6F6164696E67206F7065726174696E672073797374656D004D697373696E67206F7065726174696E672073797374656D000000637B9ACC3F302300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -> 33C08ED0BC007C8EC08ED8BE007CBF0006B90002FCF3A450681C06CBFBB90400BDBE07807E00007C0B0F850E0183C510E2F1CD1888560055C6461105C6461000B441BBAA55CD135D720F81FB55AA7509F7C101007403FE46106660807E1000742666680000000066FF760868000068007C680100681000B4428A56008BF4CD139F83C4109EEB14B80102BB007C8A56008A76018A4E028A6E03CD136661731CFE4E11750C807E00800F848A00B280EB845532E48A5600CD135DEB9E813EFE7D55AA756EFF7600E88D007517FAB0D1E664E88300B0DFE660E87C00B0FFE664E87500FBB800BBCD1A6623C0753B6681FB54435041753281F90201722C666807BB00006668000200006668080000006653665366556668000000006668007C0000666168000007CD1A5A32F6EA007C0000CD18A0B707EB08A0B607EB03A0B50732E40500078BF0AC3C007409BB0700B40ECD10EBF2F4EBFD2BC9E464EB002402E0F82402C3496E76616C696420706172746974696F6E207461626C65004572726F72206C6F6164696E67206F7065726174696E672073797374656D004D697373696E67206F7065726174696E672073797374656D000000637B9A00000000000000000200EEFE3F0001000000FFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055AA4546492050415254000001005C00000083467916000000000100000000000000FF4F0000000000002200000000000000DE4F000000000000D372FC251A7D064EAEF8B8308416B796020000000000000080000000800000009DBECC57000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2A0D0EBE5B9334487C068B6B72699C76345103608A8E9409A393558E5F20E4480000000000000007F4000000000000000000000000000004200610073006900630020006400610074006100200070006100720074006900740069006F006E

私の定番のOSFMountでマウントしてみます。

f:id:reinforchu:20210907181922p:plain

unallocated_space: OSFMount

Unknownなパーティションが見えました。実はこれでいいのだ。次のダイアログに[Yes]と答えればよいのです。

f:id:reinforchu:20210907182046p:plain

unallocated_space: Yes!

パーティションサイズがおかしいので自動的に計算しますか?というような内容を聞いてきます。

f:id:reinforchu:20210907182316p:plain

unallocated_space: mnt

無事、E:\にドライブレターが割り当てられ認識しました。

f:id:reinforchu:20210907182447p:plain

unallocated_space: root

中身もちゃんと見えるようになっていました。さっそく、flag.mp4の動画ファイルを見てみましょう。

f:id:reinforchu:20210907182810p:plain

unallocated_space: flag

flag{file_carving_gogo}

CSIRT_asks_you_02

200pt問題。Windowsのアカウント情報を握っている、SAM, SYSTEM, SECURITYファイルが配布されました。問題文はそのまま引用します。

組織内のインシデント対応部署から引き続き急ぎ解析してほしいとの依頼を受けています。

一つ目の解析依頼(CSIRT_asks_you_01)の結果と別の証拠などから、あるアカウントのパスワードが脆弱である可能性が示唆されています。添付されたファイルを解析し、そのパスワードを特定してください。

フラグはアカウント名とパスワード(平文)をアンダースコアでつないで回答してください。例えばアカウント名が user 、パスワードが pass の場合は flag{user_pass} と回答します。

これだけファイルが揃っていれば、MimikatzでNTLMハッシュ値を割り出して、レインボーテーブルで総当りすれば良いと考えました。

Command

mimikatz # lsadump::sam /system:C:\Users\reinforchu\Desktop\csirt_asks_you_02_efe7331ca21b21725da73405987bc9c9ad0d6787\SYSTEM /sam:C:\Users\reinforchu\Desktop\csirt_asks_you_02_efe7331ca21b21725da73405987bc9c9ad0d6787\SAM

f:id:reinforchu:20210907192256p:plain

CSIRT_asks_you_02: test NTLM Hash

欲しい情報はアカウント名testのNTLMハッシュ値なので、3c99b8901b00758369f18b9df72012c8というハッシュ値を得れた。
あとはophcrackに投げてみるのも良かったが、ふとこのハッシュ値をGoogle検索してみようと思いついた。

f:id:reinforchu:20210907192701p:plain

CSIRT_asks_you_02: 3c99b8901b00758369f18b9df72012c8

それっぽい情報がヒットしました。3c99b8901b00758369f18b9df72012c8はtesttestという可能性があります。

従って、このtestというアカウント名のパスワードはtesttestでflagを提出してみました。通りました。

flag{test_testtest}

 

Programing

易しい問題でしたが、Web shellを使うインタラクティブに解答する問題に関しては、過去のCTF記事のコードをめちゃくちゃ参考したので、自分の頭で解いた感がなく、ちゃんと考えればよかったな、と反省です。全問回答しました。

ZZZIPPP

80pt問題。flagが格納されたZIPアーカイブは配布されますが、どうやら1000回の入れ子になっているようです。

試しにmacOS標準のアーカイブユーティリティ.appで展開すると、再帰的にZIPアーカイブ内のZIPアーカイブも展開してしまう仕様のようで、キャンセルが利かず5分くらい待っていたら最後のZIPアーカイブが展開され、フラグが出てきました。プログラミングさせてくれませんでした……

f:id:reinforchu:20210907084807p:plain

flag.txt

flag{loop-zip-1989-zip-loop}

echo_me

120pt問題。この問題はWeb shellを使います。ncで繋ぐと出現された文字列をそのまま入力して渡していく作業を永遠とするとflag獲得でした。

解法については下記のnkhrlabさんの記事を参考にしました。コードに手は加えましたが、似たようなコードを出すのも野暮なので、コードの公開は差し控えさせていただきます。

nkhrlab.hatenablog.com

Terminal log

user@9945bf5d19a0:~$ ruby echo.rb 10.1.1.10 12020

==========

echo me: 54659447

54659447

==========

Correct!

中略

==========

echo me: 28348600

28348600

==========

Correct!

 

==========

echo me: 55286592

55286592

==========

Correct!

 

==========

echo me: 33981959

33981959

==========

Correct!

 

==========

echo me: 65257979

65257979

==========

Correct!

 

==========

echo me: 65883185

65883185

==========

Correct!

 

==========

echo me: 24121266

24121266

==========

Correct!

 

flag{Hellow_yamabiko_Yoo-hoo!}

flag{Hellow_yamabiko_Yoo-hoo!}

EZZZIPPP

150pt問題。1000回入れ子ZIPアーカイブの再来です。こんどはすべてにランダムなパスワードがかかっていました。どうにかしてこじ開けてflagを獲得する必要性がありました。

私はシェルスクリプト(zsh)で解きました。

ezip.sh

for i in {1000..1}; do pass="head -n 1 pass.txt"; unzip -o -P `$pass` "/Users/reinforchu/Desktop/ezip/flag$i.zip"; done

ZIPアーカイブのファイルパスは絶対パスになってますので、適宜変更してください。

配布されたZIPアーカイブを展開すると、flag1000.zipとpass.txtが出てきます。pass.txtは改行文字入りでパスワードが記載されていました。よって、for-loopで1000回、headでpass.txtの一行目を変数に入れながら、unzipで減算しつつパスワード付きZIPアーカイブを展開していきます。pass.txtは保持する必要性が無いので、-oオプションで上書きさせています。

注意点があり、rmで古いZIPアーカイブを消してないので、これを実行するとZIPアーカイブがやまほど残ってしまいます。

flagは最後のunzipが終わったあと、flag.txtが出てくるので開きます。

f:id:reinforchu:20210907091123p:plain

flag.txt

flag{bdf574f15645df736df13daef06128b8}

deep_thought

250pt問題。今回は計算勝負です。数式が出力され、答えが合っていれば次の問題が出力されるのを50問挑戦し、全て解答するとflagが得られました。

解法についてはecho_me問題に記載したnkhrlabさんの記事を参考にしました。やはり野暮なので、コードの公開は差し控えさせていただきます。

Terminal log

user@9945bf5d19a0:~$ ruby deep.rb 10.1.1.10 12010

[ Q1 ]

3 + 1

4

Correct!

 

[ Q2 ]

6 - 4

2

Correct!

中略

[ Q42 ]

1167 + 941

2108

Correct!

 

[ Q43 ]

1000 + 1647

2647

Correct!

 

[ Q44 ]

1422 - 1042

380

Correct!

 

[ Q45 ]

753 + 1722

2475

Correct!

 

[ Q46 ]

822 - 1792

-970

Correct!

 

[ Q47 ]

1014 + 973

1987

Correct!

 

[ Q48 ]

1293 + 1496

2789

Correct!

 

[ Q49 ]

2078 - 1656

422

Correct!

 

[ Q50 ]

866 + 983

1849

Correct!

 

flag{__42__}

Answer to the Ultimate Question of Life, the Universe, and Everything

flag{__42__}

 

Pwn

オーソドックスな問題だと思われますが、やはりPwnは苦手分野だったので、後回しした結果、最初の1問のみ解けた結果となりました。

tkys_let_die

100pt問題。Input文字列を"open"にする必要がある。ソースコードとそのバイナリが配布されました。

gate.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void printFlag(void) {
system("/bin/cat ./flag");
}

int main(void) {
char gate[6]="close";
char name[16]="..";
printf("\n");
printf(" {} {}\n");
printf(" ! ! ! II II ! ! !\n");
printf(" ! I__I__I_II II_I__I__I !\n");
printf(" I_/|__|__|_|| ||_|__|__|\\_I\n");
printf(" ! /|_/| | | || || | | |\\_|\\ !\n");
printf(" .--. I//| | | | || || | | | |\\\\I .--.\n");
printf(" /- \\ ! /|/ | | | | || || | | | | \\|\\ ! /= \\\n");
printf(" \\=__ / I//| | | | | || || | | | | |\\\\I \\-__ /\n");
printf(" } { ! /|/ | | | | | || || | | | | | \\|\\ ! } {\n");
printf(" {____} I//| | | | | | || || | | | | | |\\\\I {____}\n");
printf(" _!__!__|= |=/|/ | | | | | | || || | | | | | | \\|\\=| |__!__!_\n");
printf(" _I__I__| ||/|__|__|__|__|__|__|_|| ||_|__|__|__|__|__|__|\\||- |__I__I_\n");
printf(" -|--|--|- ||-|--|--|--|--|--|--|-|| ||-|--|--|--|--|--|--|-||= |--|--|-\n");
printf(" | | | || | | | | | | | || || | | | | | | | || | | |\n");
printf(" | | |= || | | | | | | | || || | | | | | | | ||= | | |\n");
printf(" | | |- || | | | | | | | || || | | | | | | | ||= | | |\n");
printf(" | | |- || | | | | | | | || || | | | | | | | ||- | | |\n");
printf(" _|__|__| ||_|__|__|__|__|__|__|_|| ||_|__|__|__|__|__|__|_|| |__|__|_\n");
printf(" -|--|--|= ||-|--|--|--|--|--|--|-|| ||-|--|--|--|--|--|--|-||- |--|--|-\n");
printf(" | | |- || | | | | | | | || || | | | | | | | ||= | | |\n");
printf(" ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~\n");
printf("\n");
printf("You'll need permission to pass. What's your name?\n> ");
scanf("%32[^\n]", name);
if (strcmp(gate,"open")==0) {
printFlag();
}else{
printf("Gate is %s.\n", gate);
printf("Goodbay %s.\n", name);
}
return 0;
}

あんまり深く考えることではなくて、入力値name変数をオーバーフローさせてgate変数にopenを入れればよさそう。適度に長い文字列を投げて見て様子を見よう。ncでつないでやってみる。

f:id:reinforchu:20210906105440p:plain

tkys_let_die: Terminal log

Input

00000000000000000000000000000open

Output

Gate is 000ope.

上記の結果から、30文字目からオーバーフローしてそうなので、入力値の0の文字数を減らし下記の入力値でflagが得られた。

Input

00000000000000000000000000open

Output

 =============================

     GREAT! GATE IS OPEN!!

 >> Flag is flag{Alohomora} <<

    *-*-*-*-*-*-*-*-*-*-*-*   

 =============================

flag{Alohomora}

1989

200pt問題。ある脆弱性が内在しており、その脆弱性を応用してflagを獲得する問題でした。

f:id:reinforchu:20210906105209p:plain

1989: Terminal log

メッセージがCWE-134なので書式文字列攻撃(Format string attack)ということは分かっており、色々な記事を読みコードを書いて投げてみましたが一向に通らなかったです。

https://jvndb.jvn.jp/ja/cwe/CWE-134.html

Incorrect

Shellcode

300pt問題。Shellcodeを刺す問題ということはタイトルから推定できました。ncでアクセスすらしませんでした。

Incorrect