ディレクトリトラバーサル (「パストラバーサル」とも呼ばれ、CWE-22 として特定されています) は、基盤のファイルシステムに保存された意図しないファイルに攻撃者がアクセスするのを可能にする Web アプリケーションの脆弱性です。トラバーサルが発生する場所と方法によっては Web サーバーで任意のファイルの読み込みや書き込みが可能になり、攻撃者はアプ リケーションデータを変更したり、Web サーバーを完全にコントロールしたりすることができます。
通常トラバーサルの脆弱性は、ファイルの読み込みまたは書き込みを可能にするかどうかに基づいて説明されます。以下のセクションでは、それぞれの影響についてご紹介します。
ユーザーが写真を保存できるアプリケーションで、保存した写真に後でアクセスするのに、ファイルネームのパラメーターを使って取得するファイルを指定する GET リクエストが使用されるケースを見てみましょう。アプリケーションにパストラバーサル対策が施されておらず、提供されるファイルネームのパラメーターを使用するファイルパスが構築される場合、基盤の Web サーバーから任意のファイルを取得することが可能になります。図1は、このプロセスのシーケ ンスを表しています。
アプリケーションが上の図で示されるようなトラバーサルに対して脆弱であっても、アプリケーションの許可などの制限が存在する点を考慮する必要があります。例えば、Web サーバー上でアプリケーションのアクセスを制限する最小権限モデルが適用されている場合、与えられた許可によって、攻撃者がこの脆弱性を利用してアクセスできるファイルが限られる可能性があります。これは、トラバーサルのペイロードで use/etc/passwd がターゲットとしてよく使用される理由のひとつです。ファイルがすべてのユーザーによって読み込み可能でなければなりません。防止対策に関するセクションで、サンドボックスを使用してアプリケーションアクセスを制限するその他の方法について詳しくご説明します。
上述の写真を保存するアプリケーションで、保存する各写真にユーザーが名前を付けることができると想定します。ファイルをディスクに保存する際、アプリケーションは提供された名前を使用して写真ファイルのファイルパスを構築します。十分な保護対策が施されていない場合、攻撃者は提供された名前にトラバーサルシーケンス (../ など) を追加し、ファイルがどのディレクトリに保存されるかをコントロールすることができます。
これは写真の保存先の話なので無害のように思われるかもしれません。しかし、悪用を発展させる方法は常に存在するものです。ファイルタイプが確認されない場合 (JPEG や PNG など)、任意のタイプのファイルをアップロードし、以下を含む複数のさまざまな悪用のシナリオが可能になります。
攻撃者の公開キーをユーザーの authorized_keys ファイル (/root/.ssh/authorized_keys など) に追加して永続的なアクセスを得る
アプリケーションファイルを上書きしてアプリケーションの動作を変更する
Web ルート内に Web シェルをアップロードする
必要なシステムファイルを上書きしてサービス妨害攻撃を引き起こす
実行可能なファイル (マルウェアやランサムウェアなど) をアップロードする
アプリケーションのアクセスレベルによっては、ディレクトリトラバーサルによる任意のファイルの書き込みは、破壊的な影響をもたらす可能性があります。
ディレクトリトラバーサルの基本を押さえたところで、最近実際に発生したこの脆弱性の悪用をいくつか見てみましょう。
Gitlab のバージョン 16.0.0 には、任意のファイルの読み込みを可能にするディレクトリトラバーサルの脆弱性 が存在します。デフォルトの Gitlab インストレーションで Issue にファイルを添付ファイルとしてアップロードすると、以下のように10階層下のディレクトリに Gitlab がファイルを保存するように仕向けることができます。
/var/opt/gitlab/gitlab-rails/uploads/@hashed/<directory>/<directory>/<directory>/<directory>/``**<filename>**
またアップロード後、以下にアップロードされたファイルを取得するエンドポイントが Gitlab によって提供されます。
/<repo-name>/uploads/<file-id>/``**<filename>**
エンドポイントへのリクエストにおいて Gitlab はファイル名パラメーターのサニタイズや検証を行わないため、ディレクトリトラバーサル攻撃を許してしまいます。トラバーサルの脆弱性を悪用するには、リポジトリが少なくとも5つのグループ内にネストされている必要があります。グループの数はこの脆弱性を使用してトラバースできるディレクトリの数に直接関係します。
これは、標準的なインストレーション において、ファイルシステムのルートに到達するには、リポジトリを11個のグループにネストする必要があることを意味します。このシナリオでは、/etc/passwd ファイルを取得する攻撃ペイロードは以下のようになります。
GET /Group-1/Group-2/Group-3/Group-4/Group-5/Group-6/Group-7/Group-8/Group-9/Group-10/Group-11/<repo-name>/uploads/<file-id>/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd
認証されていない攻撃者は、パブリックリポジトリがネストされたグループの要件を満たしている場合にのみ、この脆弱性を悪用できます。この可能性は高くありません。むしろ、ネストされたグループとリポジトリを作成する権利を持つ認証されたユーザーが悪用の要件を満たして脆弱性を悪用する可能性の方が高くなります。完全なエクスプロイトチェーンでは、まず必要なグループとリポジトリを作成し、ファイルをアップロードしてからトラバーサル脆弱性を悪用して任意のファイルを読み込みます。詳しくはundefinedこちらの PoC をご確認ください。
ManageEngine Desktop Central の 10.1.2127.1 より前のビルドでは、ファイルアップロードの機能にディレクトリトラバーサルの脆弱性 が存在し、「computerName」パラメーターなどの操作による任意のファイルの書き込みでトラバーサルシーケンスを含む ことが可能でした。
この問題が発見された当時、この脆弱性は活発に悪用されており、認証バイパスの脆弱性 (CVE-2021-44515) と組み合わせることでリモートコードの実行が可能でした。説明を簡潔にする目的で、ここではこの悪用のパストラバーサルの部分に焦点を当てます。これによりファイルの書き込みが可能になり、緩い検証がバイパスされます。
Desktop Central の「doPost」と呼ばれる関数では、ファイルアップロードの一環として「computerName」や「filename」などを含む複数のパラメーターが処理されます。この関数によって、ファイルの書き込みを可能にするディレクトリトラバーサルの実行につながるふたつの脆弱性が生じます。
filename のみがトラバーサルシーケンスを特定するのに確認されます。「domainName」や「computerName」、「customerId」など、他のパラメーターはファイルの絶対パスを構築するのに使用され、トラバーサルシーケンスに関して確認されません。「computerName」は連 結文字列で使用される最後のパラメーターであり、他のコンテンツが追加されることがないので、トラバーサルシーケンスを挿入するのに最適な場所です。
ファイルアップロードは zip、7z、gz の拡張子を持つファイルを許可します。これは一見安全に見えるかもしれません。しかし、Desktop Central は Java アプリケーションであり、JAR ファイルは zip 形式で構築されているので、リモートコードの実行が可能になります。zip ファイルを C:\Program Files\DesktopCentral_Server\lib
ディレクトリにアップロードし、リスタートを強制することで、プロの攻撃者はアプリケーションのクラスファイルを上書きし、任意のコードを挿入してコードを実行することができます。
この脆弱性は、トラバーサル脆弱性によって起こり得る深刻な影響を浮き彫りにすると同時に、不完全な防止対策によって意図せずにディレクトリトラバーサルを許してしまう可能性があることを示しています。
2023年第2四半期に観測された データに基づく Fastly の「ネットワークインテリジェンスに見る脅威レポート」でも指摘されているように、ディレクトリトラバーサルは最もよく観測される攻撃手法のひとつです。
この背景には、攻撃が成功した場合の影響の大きさ、攻撃者やスキャナーが使用できるペイロードリストのサイズなど複数の理由が存在します。例えば以下のように、PayloadsAllTheThings ディレクトリトラバーサルのリスト のひとつから取得したスニペットでは、以下のように同じファイルを異なる深さのトラバーサルで読み込もうとする試みが確認できます。
../../../../../../../../../etc/passwd
../../../../../../../../etc/passwd
../../../../../../../etc/passwd
../../../../../../etc/passwd
../../../../../etc/passwd
../../../../etc/passwd
../../../etc/passwd
ほとんどのケースで、攻撃者はトラバーサル脆弱性を求めてテストする際、アプリケーションがファイルシステムのどこにあるのかを把握していない可能性が高いです。しかし、アプリケーションはシステムルート (/) を超えることがないため、攻撃者は「../」の長いシーケンスを使用してルートに到達するようにすると同時に、長いシーケンスがブロックされたり、アプリケーションの機能に不具合が生じたりする場合に備えて短いシーケンスも含むようにしています。
クロスサイトスクリプティング (XSS) など他の種類の攻撃は、複数の手法が単一のペイロードに統合されたペイロードのポリグロットを使用することができます。つまり、攻撃者やスキャナーはトラバーサルのテストにおいて、XSS のテストよりもはるかに多くのペイロードを送信することになります。例として使用している PayloadsAllTheThings のファイルは140のペイロードを含んでいます。一方、XSS_Polyglots ファイル に含まれるペイロードの数はわずか16です。PayloadsAllTheThings における最も大きなトラバーサルのペイロードファイルは21,000以上のエントリ を含んでいるのに対し、XSS の最大ファイルでは600以上、SQLi では400以上 (データベースの種類が未知の場合は複数の種類をテストする必要があるので、実際の数はこれよりも多くなることが予想されます)、OS コマンドインジェクションでは400以上 です。
このようにトラバーサル攻撃の手法が広く観測されている理由はトラバーサルのペイロードリストのサイズにあるというひとつの仮説が成り立ちます。一方、上記の CVE-2022-48362 に関する説明でも触れたように、攻撃の影響の大きさも、この手法が他よりも頻繁に使用される理由のひとつとして考えられます。この脆弱性はリモートコードの実行を可能にし、発見時にはすでに悪用されていたことが知られています。
トラバーサル脆弱性を回避するために利用できる戦略がいくつかあります。これにはユーザー入力によるファイルパスの構築を妨げるためのデザイン変更や入力の厳格な検証、パスの正規化、アプリケーションアクセスの制限が含まれます。以下ではこれらの戦略についてひとつずつ解説します。
ユーザー入力を使用してファイルパスを構築する代わりに、対応するファイル ID やファイル名を使用してファイルを参照することを検討します。次に、ファイル ID を対応するストレージパスにマッピングします。ユーザーがこのファイルをリクエストしたり、ファイルをアップロードしたりすると、ユーザーがコントロールできるのはファイルの ID のみとなり、ファイルパスを構築するのに使用されたコンテンツにユーザーがアクセスするのを防ぐことができます。こうすることで、取得されるファイルのフ ァイルパスの構築にユーザー入力が使用されることがなくなり、トラバーサルの可能性を完全に排除できます。
厳格な検証はサニタイズとは異なります。トラバーサルシーケンス (../ など) を排除しようとすることで入力をサニタイズする代わりに (これはさまざまな方法でバイパスされる可能性があります)、期待されるコンテンツのみがユーザー入力に含まれていることを検証し、この厳格な検証にパスしないものをすべて拒否するようにします。以下は、ディレクトリトラバーサルを防ぐのに役立つ検証方法の例です。
英数字の値のみがファイルネームに含まれていることを検証する
提供されたファイル名に「.」がひとつのみ使用されていることを検証する
提供された入力に望ましくない文字 (/ や \ など) が含まれていないことを検証する
(簡単にバイパスされる拡張子の確認以外の方法で) アップロードされたファイルのファイルタイプ を検証する
基本的にパスの正規化によってファイルパスが実際のパスに短縮されます。具体的にはシンボリックリンクや「../」シーケンスなどのシンボリックコンテンツが排除されます。正規のパスを取得したら、そのパスが期待されるベースディクショナリのコンテンツ (uploads/photos/ など) で始まっているかどうかを検証します。以下に、正規のパスを取得する関数の例をいくつか挙げます。
Java : getCanonicalPath
PHP : realpath
C : realpath
ASP.NET : GetFullPath
一般的にアプリケーションは、正常に機能するためにアクセスする必要があるファイルとディレクトリのみにアクセスすべきです。これにより、ディレクトリトラバーサルの脆弱性が発見されてもその影響を制限し、攻撃を緩和できる場合があります。例えば Web アプリケーションはルートユーザーとして実行されるべきではなく、アプリケーションの配信に必要なファイルへのアクセスのみに制限するのが理想です。
ディレクトリトラバーサル (別名「パストラバーサル」) は、基盤のファイルシステムに保存された意図しないファイルに攻撃者がアクセスするのを可能にする Web アプリケーションの脆弱性です。トラバーサル脆弱性によっては、攻撃者による機密性の高いデータやファイルの読み込み、アプリケーションデータの変更、Web サーバーの完全なコントロールが可能になります。深刻な影響を及ぼす可能性があるトラバーサル脆弱性は、実際の攻撃例や Next-Gen WAF のデータが示すように 最も一般的な攻撃ベクトルのひとつです。しかし、このセクションでご紹介したソリューションに従うことで、アプリケーションはパストラバーサルの脆弱性を回避することができます。ディレクトリトラバーサルの防止に苦労している方や、過去にこの脆弱性の被害を受けたプロダクトを使用している方は、ディレクトリトラバーサル攻撃を含むさまざまな脅威からの保護を可能にする Fastly の Next-Gen WAF をお試しください。