setodaNote CTF Writeup (Misc)
この記事は setodaNote CTFのMiscジャンルのWriteup記事です。
- Thank_you_for_playing(0pts, 12solves)
- Welcome (20pts, 523solves)
- morse_one (30pts, 365solves)
- Hash (50pts, 378solves)
- F (80pts, 292solves)
- magic_number (80pts, 335solves)
- Stegoanography (100pts, 239solves)
- morse_zero (100pts, 202solves)
- ransom_note (100pts, 185solves)
- Nothing (120pts, 187solves)
- i_knew_it (120pts, 124solves)
- Redacted (150pts, 211solves)
- strong password (250pts, 83solves)
Thank_you_for_playing(0pts, 12solves)
全問正解すると現れる問題。YouTubeのリンクが張ってある。
リンク先は作問者による早送りWriteup動画。動画の最後にFLAGが浮かび上がってくる。
FLAG
flag{setodaNote_CTF}
Welcome (20pts, 523solves)
指示とおりに競技サーバに用意されているWebブラウザからアクセスできるLinuxターミナルにアクセスして、welcome.txtを表示するだけ。参加者用にLinuxのターミナルを用意するのすごい。
flag{Enjoy_y0ur_time_here!}
morse_one (30pts, 365solves)
以下のようなテキストが問題ファイルとして配られる。
DDDBSDDSBDDDSDBDSBBBSDBBDSDBDDSDSBDDB
問題名からしてモールス信号だが、普通のモールス信号の形ではない。
D=Dot(.
)、 B=Bar(-
)、S=Space()と予想して、文字を置換して復号する。今回はCyberChefを使った。
出力された値を問題文で指定されたとおり、flag{}
で囲んだものがFLAG
flag{VIBROPLEX}
Hash (50pts, 378solves)
問題ファイルを開くと90個のテキストファイルが含まれている。この中から以下のハッシュ値のファイルを見つけろという問題。
aff02d6ad353ebf547f3b1f8ecd21efd7931e356f3930ab5ee502a391c5802d7
8428f87e4dbbf1e95dba566b2095d989f5068a5465ebce96dcdf0b487edb8ecb
e82f6ff15ddc9d67fc28c4b2c575adf7252d6e829af55c2b7ac1615b304d8962
ハッシュの種類は64桁あるのでsha256。
もちろんこれを一つずつ見ていくのは非効率なので、ワイルドカードですべてのファイルのハッシュ値を出力して、grep
で該当のハッシュ値のファイルを調べる。
$ sha256sum * | grep -e aff02d6ad353ebf547f3b1f8ecd21efd7931e356f3930ab5ee502a391c5802d7 -e 8428f87e4dbbf1e95dba566b2095d989f5068a5465ebce96dcdf0b487edb8ecb -e e82f6ff15ddc9d67fc28c4b2c575adf7252d6e829af55c2b7ac1615b304d8962 aff02d6ad353ebf547f3b1f8ecd21efd7931e356f3930ab5ee502a391c5802d7 pass024.txt 8428f87e4dbbf1e95dba566b2095d989f5068a5465ebce96dcdf0b487edb8ecb pass034.txt e82f6ff15ddc9d67fc28c4b2c575adf7252d6e829af55c2b7ac1615b304d8962 pass079.txt
該当ファイルをファイル名が小さい順から cat
したものがFLAGになる。
$ cat pass024.txt pass034.txt pass079.txt | tr -d '\n' flag{hardest_logic_puzzle}
F (80pts, 292solves)
以下のテキストを解析する問題。
+++++++[->++++++++++>+++++++++++>+++++++++>++++++++++<<<<]>.>-.>++.>+.>++++++++[>++++<-]>.>+++++[->+++++++++++++++++++++>+++++++++++++++++++++++<<]>.>.>++++++++[>++++<-]>.>++++++++++[->++++++++++>++++++++++>++++++++++>++++++++++>++++++++++++<<<<<]>++.>++++++++.>---.>+++.>+++.>++++++++[>++++++++<-]>++++.>+++++++++++[>++++++++++>++++++++++<<-]>+.>.>++++[>++++++++++<-]>-.>+++[->+++++[->++++++++<]<]>>----.>++++++++++[->++++++++++>+++++++++>++++++++++++>++++++++++>+++++++++<<<<<]>-----.>-----.>-----.>+.>+++++.>++++++++++++++++++++[>++++++>+++++>+++++>+++++>+++>++<<<<<<-]>----.>++++.>+.>-----.>++++++++++.>+++++.>++++++++++[->+++++++++>+++++++++++>+++++++++++>++++++++++<<<<]>---.>+.>++++.>.>+++[->+++++++++++<]>..>+++++[->+++++[->+++++<]<]>>.
テキストに含まれてる文字の種類と"F"という問題名から、Brainf*uckであることがわかるので、インタプリタを用いてプログラムを実行する。
http://www.usamimi.info/~ide/programe/brainfuck/brainfuck.html
flag{Don't_Use_the_F-Word!!}
magic_number (80pts, 335solves)
様々な拡張子がついたファイルが含まれる問題ファイルが渡され、以下が示す3つのファイルを探せという問題。
[89 50 4e 47]
[52 61 72 21]
[ff d8 ff e0]
3つともファイルを識別するためのマジックナンバーのバイト列で、1つ目がPNG、2つ目がRAR、3つ目がJPGである。
いずれのマジックナンバーにも対応した拡張子のファイルがあるが、拡張子がファイルの本当の種類を表す訳ではないので、以下のようなスクリプトを書いてバイト列が含まれているファイルを探した。
#! /bin/bash for file in *;do hexdump -C $file | grep -e "89 50 4e 47" -e "52 61 72 21" -e "ff d8 ff e0" && echo $file done
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60 |......JFIF.....`| light.jpg 00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR| post.png 00000000 52 61 72 21 1a 07 01 00 33 92 b5 e5 0a 01 05 06 |Rar!....3.......| rar.rar
FLAGは問題文に書かれているとおり、該当するファイル名を flag{[89 50 4e 47]_[52 61 72 21]_[ff d8 ff e0]}
の順番にアンダースコアでつないだものになる。
flag{post_rar_light}
Stegoanography (100pts, 239solves)
解析する画像は以下のとおり。(元の画像が大きかったので少し解像度を変えてます)
すでに 1s_cReA73d_by
というFLAGの一部ぽい文字列が見える。
問題名がステガノグラフィーなので、ステガノグラフィー用のツールであるStegSolveを使っていろいろ条件を変えてみる。
Red plane 4 のとき、左上に flag{Re4l17y
という文字が見える。
また、Blue plane4 のとき、右下に _7h3_m1nd_rA9}
という文字が見える。
見つけた文字列をつなげたものがFLAG。
flag{Re4l17y_1s_cReA73d_by_7h3_m1nd_rA9}
ちなみに問題で配布された画像は、2048 x 1536と解像度が少し高い画像だった。
自分は4Kのディスプレイを持っていたので StegSolveを画面全体に見ることが出来たので何とか見つけられたが、多くの人が使っているであろうFull HD以下のディスプレイだと全体を表示できないため、FLAGの断片を見つけられなかった人がいたかもしれない。
意図してかはわからないが、もう少し解像度が低い画像で出題して欲しかった…(自分で解像度いじれば良いけれど
morse_zero (100pts, 202solves)
問題ファイルとして、morese_zero.txt
というファイルを渡されるので、とりあえずテキストエディタで開いてみる。
問題名的にこれもモールス信号だが、こんな Z
しか書いてないファイルで何をしろと…
いろいろ試行錯誤してる途中に、CyberChefに投げ込むと奇妙なことに気づく。Z
しかないはずなのに、間に何か入っている。
そのまま"To Hex"を使って16進数で見てみると、Zを表す 5a
以外にも、e2 80 8c
というデータとe2 80 8b
というデータが入っている。e2 80 8b
と ex 80 8c
を調べると、UTF-8の ZERO WIDTH~ というものらしい。それで何も見えなかったのか。
https://www.utf8-chartable.de/unicode-utf8-table.pl?start=8192&number=128
このデータをモールス信号に変換していく。
データの数的に 5a
が空白に対応しているのはわかるが、e2 80 8b
と ex 80 8c
がどう .
と-
に対応しているかはぱっと見てわからない。最初の 5a
までのデータが e2 80 8c e2 80 8c e2 80 8b e2 80 8b
なので、考えうるパターンは --..
か..--
だが、..--
は英字の対応表にない。よって、 e2 80 8c
が -
、e2 80 8b
が .
になる。
これもCyberChefを使って復号した。
これも flag{}
で出力された文字列を囲ったものがFLAGになる。
flag{ZER0_W1DTH_SPACE}
ransom_note (100pts, 185solves)
問題ファイルを開くと、ランサムウェアの脅迫文と暗号化されたファイルが含まれている。脅迫文を読むと、GANDCRAB V5.0.3 の文字が。
ランサムウェアのいくつかは解析されて復号ツールが提供されており、GANDCRAB V5.0.3 は復号ツールの対象である。
https://www.bitdefender.com/blog/labs/gandcrab-ransomware-decryption-tool-available-for-free/
https://www.nomoreransom.org/ja/decryption-tools.html
このツールを使うと暗号化されたデータが復号できる。
flag{unlock1ng_y0ur_d1gital_life_with0ut_paying;)}
Nothing (120pts, 187solves)
とりあえず与えられたファイルをメモ帳で開いてみてる。何も見えない。
そういえば、空白やタブだけで書くプログラミング言語Whitespaceがあったなと思い、"Whitespace 実行" というキーワードでググってオンラインで実行できる環境調べていると、以下のサイトで実行できそう。
実行してみるとFLAGが出力された。
flag{And_Then_There_Were_None}
i_knew_it (120pts, 124solves)
IDAの画像が提供されて、使われている暗号方式を特定せよという問題。
loc_11E1
の処理でループしてXORしてるしRC4か?と思って、勘でSubmitしたら通った。普段からマルウェア解析してる人だったら即答出来たに違いない…
flag{RC4}
Redacted (150pts, 211solves)
以下のように文章の一部が黒塗りされたPDFが配布される。
該当の文章のコピー&ペーストはできない。
いろいろ調べると、LibreOfficeでPDFを開けばオブジェクトの移動ができそうだったのでLibreOfficeで開いてみる。黒い部分のオブジェクトを動かせて、FLAGが見えた。
flag{weather_balloon}
strong password (250pts, 83solves)
問題ファイルを開くと、パスワード付きZIPファイルと「情報セキュリティガイドライン」というファイル名のPDFファイルが含まれている。
zipinfoでTopSecret.zipの情報を見てみる。TopSecret.txtというファイルが入っており、圧縮はされていない。unzipしようとすると、もちろんパスワードを聞かれる。
$ zipinfo TopSecret.zip Archive: TopSecret.zip Zip file size: 245 bytes, number of entries: 1 -rw-a-- 6.3 fat 73 Bx stor 21-Jul-14 18:22 TopSecret.txt 1 file, 73 bytes uncompressed, 73 bytes compressed: 0.0% $ unzip TopSecret.zip Archive: TopSecret.zip [TopSecret.zip] TopSecret.txt password:
情報セキュリティガイドラインに書いてあるのは以下のような内容だった。
- 発行日は 2020年04月01日
- パスワードの規則を定めるドキュメント
- パスワードは13桁
- 使用可能な文字種類
- 英大文字 A~Z
- 英小文字 a~z
- 数字 0~9
- 記号6 種(@、#、$、%、!、-)
- パスワードの形式は、
[案件コード] + [記号1] + [年月日] + [記号2]
- 各要素の規則
- 案件コード:案件を示す英字3 文字。大文字小文字は任意。
- 年月日:年月日を表す数字8 桁(利用日に合わせ都度変更すること)。
- 記号1:記号1 字を入れる。
- 記号2:記号1 字を入れる。
- 例:Abc#20200401$
ここでポイントなのが、パスワードの長さが13桁固定なのと、発行日が2020年04月01日であること。
パスワードの長さが何桁か調べないといけないのでその分時間がかかるが今回は固定なのでかなり楽。(つまりパスワードは長ければ良いってものではない)
発行日が2020年04月01日でファイルの更新日時が2021年07月14日なので、恐らくパスワードの年月日の部分は20200401-20210712に絞られる。
ZIPパスワードのクラックには、hashcatを使える。今回は一通りツールが揃っているKali Linuxで実行した。
(参考)https://blog.amedama.jp/entry/zip-password-gpu-brute-force
まず、zip2johnでZIPファイルからパスワードハッシュを生成する。
zip2john TopSecret.zip | cut -d ":" -f 2 > TopSecret.zip.hash
次に生成したパスワードハッシュをhashcatでクラックする。
hashcatの基本的な使い方は以下のとおり。
hashcat [options] hash|hashfile|hccapxfile [dictionary|mask|directory]
オプションは以下のものを指定
-a
: アタックモード。bruteforceは3
。-m
: クラックするhashの種類。今回は圧縮されてないPKZIPなので17210
-1
,-2
,-3
,-4
: パスワードのカスタムcharsetを定義する。(後述)
bruteforceを行う場合は、パスワードのパターンを定義したmaskをhashfileを指定した後に指定する必要がある。
hashcatにはBuilt-inされているcharasetがいくつかあり、これを使ってBruteforceを行うパスワードのパターンが定義できる。
?l
= abcdefghijklmnopqrstuvwxyz?u
= ABCDEFGHIJKLMNOPQRSTUVWXYZ?d
= 0123456789?h
= 0123456789abcdef?H
= 0123456789ABCDEF?s
= «space»!"#$%&'()*+,-./:;<=>?@[]^_`{|}~?a
= ?l?u?d?s?b
= 0x00 - 0xff
https://hashcat.net/wiki/doku.php?id=mask_attack
しかし、上記の文字列セットだけでは可能性があるパスワードのパターンを表現できないので、カスタムのcharsetを定義してパターンを定義した。
?1
= ?l?u: 英大小文字?2
= @#$%!- : 記号6種?3
= 01: 年の4桁目、月の1桁目?4
= 0123: 日の1桁目
可能性のあるパスワードは正規表現で表すと以下の通りである。(20200000や20211231など、今回考えられる年月日ではないパターンやそもそも年月日ではないパターンも含まれるが許容する) (2021年09月12日更新:正規表現が間違えてたので修正しました)
[a-zA-Z]{3}[@#$%!-]202[01][01][0-9][0123][0-9][@#$%!-]
これをBuilt-in charsetと上記のカスタムcharsetを使って表すと以下のようになる。
?1?1?1?2202?3?3?d?4?d?2
したがって、実行するhashcatのコマンドは以下のようになる。
hashcat -a 3 -m 17210 -1 ?l?u -2 '@#$%!-' -3 01 -4 0123 TopSecret.zip.hash ?1?1?1?2202?3?3?d?4?d?2
hashcatを実行すると、私の環境では3分程度でパスワード qYL%20210228!
が見つかった。(途中でstatusを表示すると見積もり時間を確認できるが全部のパターンを試しても7分程度だった
見つかったパスワードを用いてZIPを展開するとFLAGが見れる
flag{And_n0w_h3re_is_my_s3cre7}
FLAGファイルに書いてあるとおり「このパスワードが安全なはずがない。」意外とこういう運用をしている組織はあると思うので、「こういう運用は脆弱だぞ」というメッセージを伝えることができる良い問題だったと思う。