← レッドチーム / 攻撃技術
LFI  ·  ■ 本来の機能   ■ 悪用のされ方

便利な機能が、
チェックを怠った瞬間
入り口になる

ファイルを取り込む include は本来まったく普通の機能です。それが LFI という攻撃に化ける境目はどこなのか、機能の側から順に追っていきます。

ポイント 「本来は便利な機能が、入力チェックを怠ると攻撃の入り口になる」—— Web 脆弱性の多くに共通する構図。
1 前提

そもそも include とは

include = 「別のファイルの中身を、その場所に取り込む(差し込む)」命令

プログラムを全部 1 つのファイルに書くと巨大で管理しづらいので、共通部分を別ファイルに分けておき、必要な場所で「あのファイルをここに差し込んで」と指示します。

身近なたとえ

Web サイトでは、ヘッダー(ロゴ・メニュー)とフッター(著作権表示)は全ページ共通です。毎ページにコピペするとメニューを 1 つ変えるだけで全ページ直す羽目になるので、共通部分を外だしして include します。

include("header.php");   // ここに header.php の中身が差し込まれる

// このページ独自の内容

include("footer.php");   // ここに footer.php の中身が差し込まれる

ヘッダーを直したいときは header.php 1 ファイルだけ直せば全ページに反映されます。これが include 本来の便利な使い方です。

PHP の include が特殊な点

PHP の include「差し込んだファイルの中に PHP コードが書いてあったら、それを実行する」 という動作をします。

つまり単なる「テキストの貼り付け」ではなく、「そのファイルを PHP プログラムとして取り込んで動かす」命令です。この性質が、LFI が RCE に発展しうる鍵になります。

2 攻撃の成立

LFI(Local File Inclusion)とは

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 で読み込ませると実行につながる(ログポイズニングなど)

「ファイルを読めるだけ」で終わらず、条件が揃うとサーバー乗っ取りまで発展しうるのが怖い点です。

3 区別

RFI との違い

4 防御

対策の考え方

根本は「ユーザー入力をそのままファイルパスに使わない」ことです。

もう少し踏み込むなら php://filter を使ったソースコード読み出し/ログポイズニングによる RCE への発展。研修の Web アプリ診断で実際に手を動かすと理解が一気に進む。