ファイルを取り込む include は本来まったく普通の機能です。それが LFI という攻撃に化ける境目はどこなのか、機能の側から順に追っていきます。
include = 「別のファイルの中身を、その場所に取り込む(差し込む)」命令。
プログラムを全部 1 つのファイルに書くと巨大で管理しづらいので、共通部分を別ファイルに分けておき、必要な場所で「あのファイルをここに差し込んで」と指示します。
Web サイトでは、ヘッダー(ロゴ・メニュー)とフッター(著作権表示)は全ページ共通です。毎ページにコピペするとメニューを 1 つ変えるだけで全ページ直す羽目になるので、共通部分を外だしして include します。
include("header.php"); // ここに header.php の中身が差し込まれる
// このページ独自の内容
include("footer.php"); // ここに footer.php の中身が差し込まれる
ヘッダーを直したいときは header.php 1 ファイルだけ直せば全ページに反映されます。これが include 本来の便利な使い方です。
PHP の include は 「差し込んだファイルの中に PHP コードが書いてあったら、それを実行する」 という動作をします。
つまり単なる「テキストの貼り付け」ではなく、「そのファイルを PHP プログラムとして取り込んで動かす」命令です。この性質が、LFI が RCE に発展しうる鍵になります。
Web アプリの「ファイルを読み込む仕組み」を悪用して、本来見せるつもりのないサーバー内のファイルを読み出させる攻撃です。
URL のパラメータで「どのファイルを表示するか」を指定する作りのとき——
http://example.com/page.php?file=about.html
サーバー側はだいたいこうなっています。
include($_GET['file']); // file パラメータの中身をそのまま読み込む
問題は file の中身をチェックせずにそのまま使っている点です。開発者が header.php のように固定のファイル名を書くべきところを、ユーザーが自由に指定できるパラメータにしてしまっています。
../ は「1 つ上のディレクトリへ」の意味です。並べると Web 公開フォルダを抜け出して、システムの奥のファイルに到達できます。
http://example.com/page.php?file=../../../../etc/passwd
/etc/passwd は Linux のユーザー情報ファイルで、「読めてしまった=脆弱性あり」の定番確認先です。
| 影響 | 内容 |
|---|---|
| 情報漏洩 | 設定ファイルから DB パスワードや API キーが読めることがある |
| RCE(任意コード実行)への発展 | ログファイルに攻撃コードを仕込み、それを LFI で読み込ませると実行につながる(ログポイズニングなど) |
「ファイルを読めるだけ」で終わらず、条件が揃うとサーバー乗っ取りまで発展しうるのが怖い点です。
http://攻撃者のサーバー/evil.txt など)根本は「ユーザー入力をそのままファイルパスに使わない」ことです。
../ などを除去・無効化するphp://filter を使ったソースコード読み出し/ログポイズニングによる RCE への発展。研修の Web アプリ診断で実際に手を動かすと理解が一気に進む。