← レッドチーム / 攻撃技術
LINUX NOTES  ·  ■ 攻撃の手順   ■ 仕組みの理解

「PHP じゃないのに
読めてしまう」のは、
include の仕様

演習や書籍で出てきた Linux・シェル周りの小ネタを溜めるページ。中心は php://filter でソースを抜く手順と、なぜそれが成立するのかという include の挙動です。

1 LFI × php://filter

LFI と php://filter によるソース奪取

前提となる脆弱性

command などのパラメータで受け取った値を、そのままファイルとして読み込む作りになっていると LFI が成立します。

<?php
    $filename = $_GET['command'];
    include($filename);
?>

この evil.php は、?command= に渡した任意のファイルを include してしまいます。

include の本当の挙動(重要)

include は必ず PHP として実行される」は誤解です。実際は次の 3 ステップ。

  1. ファイルの中身を読み込む
  2. 中身を そのまま出力する(HTML でもテキストでも何でも)
  3. ただし <?php ... ?> で囲まれた部分だけ を PHP コードとして実行する

つまり include は「基本はテキストを垂れ流し、<?php タグを見つけたときだけ実行モードに切り替わる」。通常の .php ファイルで、タグの外に書いた HTML がそのまま表示されるのと同じルールです。

だから普通のファイルは丸見えになる

.bashrc/etc/passwd には <?php タグが一切ありません。よって全部が「ただのテキスト」として出力され、中身が丸見えになります。これが LFI でファイルを読める理由です。

curl $URL/secret/evil.php?command=/home/mowree/.bashrc
Note 「PHP じゃないファイルが読めてしまう」のは例外ではなく、include の本来の挙動そのもの。むしろ <?php を含むファイルだけが「実行されてしまって読めない」特殊ケース。

.php 自身だけは素直に読めない

command=evil.php を渡すと、evil.phpevil.php を include します。中身に <?php ... ?> があるので、テキスト出力されず 実行されてしまう。実行しても出力処理が無ければ、ソースは画面に出ません。

解決策:php://filter で実行させずに抜く

PHP の特殊ラッパー php://filter を使い、読み込む時点で中身を Base64 エンコードさせます。

php://filter/convert.base64-encode/resource=evil.php

Base64 化されると <?php というタグが PD9waHAK... という ただの文字列に化けます。PHP は「これは実行すべきコードではない、ただのテキストだ」と判断してそのまま出力します。

# 1. filter経由でリクエスト(中身がBase64で返る)
curl "$URL/secret/evil.php?command=php://filter/convert.base64-encode/resource=evil.php"
# → PD9waHAKICAgICRmaWxlbmFtZSA9ICR...FtZSk7Cj8+Cg==

# 2. 手元でデコード
echo 'PD9waHAK...Cj8+Cg==' | base64 -d
# → 元のソースが復元される

PD9waHAK<?php\n の Base64(PD9w = <?p)です。

読むファイル<?php タグinclude の挙動結果
.bashrc / /etc/passwd 無し 全部テキスト出力 中身が丸見え ✓
evil.php(素直に) 有り 実行される ソース見えない ✗
evil.php(filter 経由) Base64 化され無効 テキスト出力 デコードで丸見え ✓
Tip resource=config.php などに変えれば、DB パスワードが書かれた設定ファイルを抜く攻撃に繋がる。php://filter と並んで data://expect:// などのラッパーも押さえておく。
2 ドットファイル

.bashrc とは

bash(シェル)を起動するたびに自動で実行される設定ファイル。ホームディレクトリ /home/ユーザー名/ に置かれます。ターミナルを開いて新しいシェルが立ち上がるとき、bash は .bashrc を読んで実行してからプロンプトを出します。

典型的な中身

alias ll='ls -la'
alias gs='git status'
export PATH="$HOME/bin:$PATH"

名前について

ペンテスト / IR での狙われ方

ユーザーのホームにあるドットファイルは情報の宝庫です。

.bashrc 自体は決定打になりにくいですが、「そのパスにファイルが実在する=ユーザーが存在する」の確認や、次に読むべきファイル(.ssh/ など)の当たりをつける足がかりになります。

Warning 書き込みできる状況なら、.bashrc に悪意あるコマンドを仕込み「そのユーザーが次にログインした瞬間に実行させる」永続化(persistence)に使われる。IR 演習で侵害ホストを調べる際は、.bashrc.bash_history の改ざんや不審なエントリが定番チェックポイント。
3 小ネタ

補足:view-source:

ブラウザのアドレスバーで URL の前に view-source: を付けると、レンダリングせずサーバーが返した生の HTML ソースをテキスト表示します。JS は実行されないので、DOM 変更前の状態が見えます。アドレスバー手入力のみ有効(リンク/JS 遷移はブロック)。Safari は非対応。