Skip to main content

Fetch the Flag CTF 2022 解説:Logster

feature ctf logster

2022年11月10日

0 分で読めます

Fetchに参加してくれてありがとう! 参加してくれた数千人のプレイヤーの皆さん、Fetch the Flag CTFにご参加いただき、おめでとうございます。また、チャレンジを作成し、テストし、解説記事を書いてくれたSnykerの皆さんにも心から感謝します!

Snykの2022年Fetch the Flagに参加し、Logsterチャレンジの答えを探しているなら、ここがぴったりです。一緒に解決策を見ていきましょう!

まずは偵察フェーズから

このフェーズでは、攻撃者が脆弱な標的を特定し、悪用方法を探ります。今回提示されているのは、あるWebサイトへのリンクです。開始するために必要なのは、侵入経路が1つだけです。

Jnioromousシェル用のLogster 500検索ツール。logster.cctf-snyk.ioへのリンク

まずリンクを確認し、http://logster.c.ctf-snyk.io/にアクセスします。これはWebサイトをスキャンできるサイトです。

アドレス入力欄、「More」ボタンと「Scan」ボタン、データが表示されていない「Raw Headers」パネルを備えたWebサイトスキャナーのインターフェース

https://www.cnn.com/を試してみましょう。ヘッダーが表示されます。

URL欄にhttps://www.cnn.com/が表示され、HTTP 200ステータスの生ヘッダーログが表示されたWebサイトスキャナー

そこから、チャレンジの説明(lookup)とプログラミング言語(Java)を手がかりに、Log4Shellを扱っていると推測できます。

トンネリングを始めましょう!

まず、カスタムヘッダーを設定するExpress Webサーバーを作成し、ngrokトンネルを使ってサーバーをローカルで実行してから、外部に公開します。その後、スキャンして何が起きるか確認しましょう!

Expressサーバーの設定方法がわからない場合は、この手順に公式ドキュメントが役立ちます。

ダークテーマのコードエディターに、ルートパスで「Hello World!」を返し、ポート3000でリッスンするExpress.jsサーバーが表示されています。

ポート3000でリクエストを処理するExpressサーバーを作成し、('PWN', 'pwn')でカスタムヘッダーを設定します。

次のコマンドで実行します。node express.js:

Fetch-The-FlagのNode.js Expressサンプルアプリがポート3000で待ち受けているターミナル

次に、ngrok http 3000コマンドでngrokトンネルを作成します。マシンでの設定方法は、ngrokの公式ドキュメントを参照してください。

localhost:3000へのパブリックHTTPS URLの転送、接続統計、検査用URLを表示した、オンラインのngrokセッションを示すターミナル。

転送用リンクをコピーしてWebサイトに貼り付け、スキャンします。ngrokコンソール(http://localhost:4040/)を見ると、express.jsファイルで指定したヘッダーがそのまま返されていることがわかります

200 OKのレスポンスと詳細なHTTPヘッダーを含むGETリクエストの一覧を表示したngrok Inspectコンソール

Log4Shell形式のペイロードヘッダーを設定してみましょう。express.jsファイルに戻り、ヘッダーを('${java:version}', 'pwn')に変更します。

Express.jsアプリが表示された暗色のコードエディター。ルートルートで「Hello World!」を返し、ポート3000でリッスンしています

サーバーを再起動し、Webサイトをもう一度スキャンします。500 Internal Server Errorが発生します。ログを見ると、ヘッダー名は有効なHTTPトークンでなければならないとわかります。

500 Internal Server Errorと無効なHTTPトークンのメッセージが表示された、選択中のGETリクエストを示すサーバーリクエストモニター

Expressでは無効なヘッダーは使えません。$や{}は有効な文字ではありません。そのため、これを回避する必要があります。接続のたびにカスタムレスポンスを返すソケットサーバーを作成すれば回避できます。

ソケットサーバーは次のようになります。ソケットで待ち受け、接続ごとにレスポンスを書き戻します。この場合はJavaのバージョンも含めます。このカスタムヘッダーを挿入し、評価されるか確認します。

index.js内のJavaScriptコード。ネットワークサーバーを作成し、HTTP 200レスポンスを返してポート3000で待ち受ける

node index.jsコマンドでサーバーを起動し、ngrok tcp 3000コマンドでngrokトンネルをTCPトンネルに変更します。TCPトンネル機能を使うには、ngrokのアカウントが必要です。

オンラインのngrokセッションで、TCPトラフィックを0.tcp.eu.ngrok.io:14584からlocalhost:3000に転送しているターミナル。

Forwardingリンクをコピーします。TCP部分は含めずにWebサイトに貼り付け、先頭にhttps://を追加してからスキャンします。カスタムヘッダーが評価されていることがわかります。lookupが実行され、Javaのバージョンが返されました。lookupが機能することが確認できました。

URL入力欄、「More」ボタンと「Scan」ボタン、ステータス200を含む生のヘッダー結果が表示されたWebサイトスキャン画面。

次はLog4Shellエクスプロイトを設定します。

Log4Shellとは?

CVE-2021-44228(Log4Shellとも呼ばれます)は、Apache Log4j 2のほぼすべてのバージョンに影響する、認証不要のリモートコード実行(RCE)脆弱性です。2021年12月9日、このゼロデイ脆弱性のニュースは、公開されていた概念実証(POC)とともに、情報セキュリティコミュニティに広まりました。

Log4Shellの脆弱性について詳しく知りたい方は、Snyk Learnの無料レッスンをご覧ください。

POC

次の手順では、この公開されているPOCを使います。このリポジトリには、攻撃の実行に必要なものがすべて含まれています。

プロジェクトをGit cloneし、Evil.javaクラスに移動します。このチャレンジで使う実際のペイロードを作成するため、内容を変更する必要があります。ルートディレクトリ内のすべてのファイルを一覧表示します。Fileオブジェクトを作成してファイル一覧を取得し、各ファイル名を出力します。

Evil.javaを表示したダークテーマのコードエディター。ルートディレクトリ内のファイル一覧を取得し、「You have been pwned!」を返すJavaのObjectFactory

次のコマンドでDockerイメージをビルドします。

docker build -t log4shell-vulnerable-server-exploit .

次のコマンドでngrok TCPサーバーを起動します。

ngrok tcp 9999
localhost:9999への転送先としてtcp://7.tcp.eu.ngrok.io:18771を表示する、オンラインセッション中のngrokターミナル

次のコマンドでngrok HTTPサーバーを起動します。ngrok http 8888

ngrokのターミナル画面。オンラインセッションで、公開HTTPS URLをhttp://localhost:8888に転送している

次のコマンドでDockerコンテナをリモートで実行します。

ポートマッピングとHTTPサーバーのホストを指定してDockerコンテナを実行し、Log4Shellの脆弱性テストを行うターミナルコマンド

ただし、その前にLDAPサーバーの接続先を正しいForwardingリンクに設定する必要があります。ポート8888で動作しているHTTPサーバーのリンクをコピーして貼り付けます

ポート9999で動作しているTCPサーバーのアドレスも、ソケットファイルindex.jsに含める必要があります。ここでは、実際のLog4Shellペイロードを含むヘッダーを送信します。先ほど変更したEvilクラスを配信しています。

ngrokのTCPアドレスと「Evil」というテキストを含むサーバーレスポンスを示すJavaScriptコード。その後に「hello」と表示されている。

次のコマンドでソケットサーバーを再起動します。node index.js

もう一度、このコマンドを実行します。

ポート8888と9999を公開した、Log4Shellの脆弱性があるサーバーを実行するDockerコマンドが表示されたターミナルのスクリーンショット。

ターミナルに同じ出力が表示されるはずです。

LDAPサーバーとHTTPサーバーがそれぞれポート9999と8888で待ち受ける、脆弱なサーバーを悪用するDockerコマンドを表示したターミナル。

Webサイトに戻ると、ルートディレクトリ内のファイル一覧が表示され、フラグがあることを確認できます!

「Raw Headers」というタイトルのスクリーンショット。package.jsonやnode_modulesなど、サーバーのディレクトリとファイルを列挙したデバッグ出力が表示されています。

フラグを表示するため、最後にもう一度ペイロードを変更します。Evilクラスに戻ります。このコードを使うと、フラグを読み込んでファイルの内容を出力できます。

ダークテーマのコードエディターに表示されたEvil.java。/flagを読み取り、「you have been pwned!」を返すJavaのObjectFactory

変更を反映するには、Dockerコンテナを再実行する必要があります。もう一度スキャンすると、フラグファイルの内容が表示されます!

デバッグログと強調表示されたSNYKトークン文字列が見える、生のヘッダーのスクリーンショット。

Logsterのまとめ

このエクスプロイトは単純で、ライブラリも広く使われていたため、脆弱性の公表後、セキュリティ担当者は対応に追われました。当初、Log4Shellの緩和策として推奨されていたのはバージョン2.16へのアップグレードでしたが、残念ながら、このバージョンにもサービス拒否攻撃につながる脆弱性が見つかりました。現在推奨されているのは、バージョン2.17へのアップグレードです。

修正に関する推奨事項を詳しく知りたい方は、Log4Shell修正チートシートをご覧ください。新しい情報が入り次第、継続的に更新しています。

LogsterやCTFの他のチャレンジを楽しんでいただけたなら幸いです :) 他のフラグをどう見つけたか知りたいですか?Fetch the Flagの解答ページで、解き方をご覧ください。

続きを読む

Blog

フロンティアモデルは脆弱性を発見した。攻撃者だけがエクスプロイトチェーンを見つけた。

静的解析で欠陥は見つかりましたが、ライブ攻撃テストで侵害につながる連鎖を実証できたのは唯一でした。Evo COS、Claude Security、Claude Code Securityを比較します。

feature insights context
Blog

自律型攻撃はすでに始まっている。防御もそのスピードに追いつかなければならない。

自律型攻撃者によって、防御に使える時間は短くなっています。継続的な検出、修復、検証、予防で、セキュリティチームが攻撃に歩調を合わせる方法をご紹介します。

Blog

AIコーディングエージェントが不適切なアクセス制御を繰り返し実装する理由

AIコーディングエージェントは、コンパイルが通りレビューも通過する一方で、あるテナントのデータを別のテナントに公開してしまう認可ロジックを生成することがあります。不適切なアクセス制御が検出しにくい理由と、その防止策をご紹介します。