はじめに
本コースは、Web アプリケーションにおいて最も一般的な問題の一つであるファイルインクルージョン脆弱性に焦点を当てた、初心者向けの Web アプリケーション脆弱性に関する入門コースへようこそ。
このモジュールでは、まず Web アプリケーションの文脈における「ファイルインクルージョン」の概念を解剖します。次に、その基礎の上に構築し、「ファイルインクルージョン脆弱性」とは何かを明確にします。最後に、ファイルインクルージョン脆弱性の主要な 2 つのカテゴリについて掘り下げます。
このモジュールの次のセクションでは、「ローカルファイルインクルージョン脆弱性 (Local File Inclusion Vulnerabilities)」と「リモートファイルインクルージョン脆弱性 (Remote File Inclusion Vulnerabilities)」についてさらに深く掘り下げ、これらの重要なセキュリティ問題について包括的な理解を提供します。
主な学習成果
- Web アプリケーションにおけるファイルインクルージョンの基本概念を理解する。
- ファイルインクルージョン脆弱性の根本原理を把握する。
- ローカル (Local) とリモート (Remote) というファイルインクルージョン脆弱性の 2 つの主要なタイプについて学ぶ。
ファイルインクルージョンの理解
ここでは、「ファイルインクルージョン」の概念と、特に初心者向けに特化したその潜在的な脆弱性について掘り下げていきましょう。
ファイルインクルージョンは、特にコードの再利用性の観点から、プログラミングにおいて一般的な手法です。開発者は、頻繁に使用される関数やモジュールを別個のファイルにカプセル化することがよくあります。これらの関数やモジュールが必要な場合、コード内でこれらのファイルをインクルードするだけで、同じコードを繰り返し記述する必要がなくなります。
PHP には、ファイルインクルージョンのための主要な 4 つの関数があります。
include()require()include_once()require_once()
それぞれの簡単な概要は以下の通りです。
include(): この関数は、呼び出されたときにファイルをインクルードします。ファイルが見つからない場合、PHP は警告を発しますが、スクリプトの実行は継続されます。require(): この関数は、スクリプトの実行開始前にファイルをインクルードします。ファイルが見つからない場合、PHP は致命的なエラーを発行し、スクリプトを停止します。include_once()およびrequire_once(): これらの関数はinclude()およびrequire()と同様に機能しますが、関数が複数回呼び出された場合でも、ファイルが一度だけインクルードされることを保証します。
ファイルインクルージョンの方法は、大きく分けて 2 つのタイプに分類できます。
- 静的インクルージョン (Static inclusion)
- 動的インクルージョン (Dynamic inclusion)
これら 2 つのタイプの違いは、次のセクションの例で明確になります。
本実験では、/home/labex/project/ ディレクトリにある 3 つの .php ファイルを調査します。これらは以下の通りです。
lfi_static.phplfi_dynamic.phpecho.php
各ファイルが何をするかを理解しましょう。
lfi_static.php: このファイルはecho.phpファイルを静的にインクルードします。つまり、echo.phpファイルへのパスはハードコードされており、変更されません。この方法は安全であり、脆弱性を露呈することはありません。<?php include("./echo.php"); ?>lfi_dynamic.php: このファイルは、URL 内の 'file' パラメータに基づいて他のファイルをインクルードします。このパラメータが提供されていない場合、単に使用方法のヒントを提供します。しかし、このパラメータが攻撃者によって制御されている場合、この方法は危険になる可能性があります。<?php if (isset($_GET['file'])) { include($_GET['file']); } else{ echo "You can use the 'file' parameter to include files"; } ?>echo.php: このファイルは、インクルードされると単に成功メッセージを出力します。<?php echo 'Great, now you have successfully included the content of echo.php!' ?>
lfi テスト用のイメージを準備するために、ターミナルで以下のコマンドを使用します。
cd ~/projects
docker build -t lfi-image .
イメージのビルドが完了したら、そのイメージを使用してコンテナを起動し、lfi 脆弱性をテストできます。
docker run -d --name lfi -p 80:80 lfi-image
これで、ブラウザでこれらのファイルをテストできます。例えば、lfi_static.php ファイルにアクセスするには、以下の URL を入力します。
http://127.0.0.1/LFI/lfi_static.php
lfi_static.php ファイルが echo.php の内容を正常にインクルードしていることがわかります。この静的なファイルインクルージョン方法は安全であることを覚えておいてください。
次に、lfi_dynamic.php ファイルを見てみましょう。この URL を使用してアクセスします。
http://127.0.0.1/LFI/lfi_dynamic.php
'file' パラメータを使用するように促すプロンプトが表示されます。それを行い、echo.php をインクルードしてみましょう。
http://127.0.0.1/LFI/lfi_dynamic.php?file=./echo.php
echo.php が正常にインクルードされたことがわかります。これはファイルインクルージョンがどのように機能するかを示す例です。これは PHP の例ですが、使用される特定の関数は異なる場合があるものの、その原則は他のプログラミング言語にも適用されることを覚えておくことが重要です。
ファイルインクルージョン脆弱性の理解
先ほど、lfi_dynamic.php の file パラメータを使用して echo.php ファイルをインクルードする方法を学びました。しかし、ここで疑問が生じます。
file パラメータを使用して他のファイルをインクルードすることは可能でしょうか?
答えは、間違いなく「はい」です!
もし Web 開発者が file パラメータの検証を怠ると、サーバー上に存在する機密ファイルをインクルードするために悪用される可能性があります。
いくつかの例を挙げます。
- Linux システムでは、
/etc/passwdファイルをインクルードできる可能性があります。 - Windows システムでは、
C:\Windows\System32\drivers\etc\hostsファイルをインクルードできる可能性があります。
これを例で説明しましょう。file パラメータを /etc/passwd に設定すると仮定します。
http://127.0.0.1/LFI/lfi_dynamic.php?file=/etc/passwd
ブラウザでその URL を開くと、/etc/passwd ファイルの内容を正常にインクルードし、表示できたことがわかります。これは、深刻なセキュリティ問題であるローカルファイルインクルージョン (LFI) 脆弱性の存在を示しています。
これらの脆弱性を理解することが、それらを防止するための第一歩であることを忘れないでください。Web アプリケーションでは、常にすべてのユーザー入力を検証し、サニタイズ(無害化)するようにしてください。
ファイルインクルージョン脆弱性の種類
Web セキュリティにおける重大な問題であるファイルインクルージョン脆弱性は、主に次の 2 つの主要なタイプに分類されます。
ローカルファイルインクルージョン (LFI): このタイプの脆弱性は、対象サーバー上のローカルファイルがインクルードされる場合に発生します。
リモートファイルインクルージョン (RFI): このタイプの脆弱性は、別のリモートサーバー上にあるファイルがインクルードされる場合に発生します。
以前議論した例で、ローカルの /etc/passwd ファイルをインクルードしたことは、ローカルファイルインクルージョン (LFI) 脆弱性の典型的な事例です。これら 2 種類の脆弱性の違いを理解することは、Web アプリケーションを効果的に保護するために極めて重要です。
まとめ
この実験(Lab)では、ファイルインクルージョン機能を通じて攻撃を開始する方法とプロセスを学びました。このセクションで取り上げた重要なポイントを復習しましょう。
- ファイルインクルージョンとは何か?
- ファイルインクルージョン脆弱性とは何か?
- ファイルインクルージョン脆弱性の 2 つのタイプは何か?