PHP はなかなか自由な機能があり、これを組み合わせると危険な脆弱性を埋め込むこともできます。例えば evel 関数を用いずともリモートプログラムが任意実行可能な脆弱性を作れます。その例を紹介します。
使うのは include です。これは指定された PHP ファイルを読み込んで実行する制御構造です。例では include を扱いますが、include_once, require, require_onceのいずれでも同様のことが可能です。
PHP: include – Manual
この include 機能は設定を緩くするとリモートのファイルを読み込むこともでき、これを使います。緩くする設定はallow_url_include
です。
PHP: 実行時設定 – Manual
これを次の様に php.ini で 1 にすると include でリモートファイルを読み込めます。
# ファイル全般をURLで呼べるようにする設定 # これはないと不便な時が多いので PHP デフォルトで 1 に設定されています allow_url_fopen = 1 # include で URL を使うことを許す設定 # ↑の allow_url_fopen も 1 でないと有効化されない allow_url_include = 1
この状態で次の様に include 先を外部から自由に指定できる様にすればリモート実行の脆弱性完成です。
<?php $page = $_GET['page'] ?? ''; if($page) { // GET パラメータで表示するページを変えたいコード include $page; } else { echo 'ページがありませんでした。'; }
この状態になると次の様に任意のページを開け、PHPスクリプトを実行させることもできるようになります。単にリモートのPHPをインクルードするのみでは、リモートに配置された PHP がリモートサーバーの側で実行させられますので、リモートで実行された PHP によっていきなりローカルのディスク内がいじくりまわさわれることはありません。とはいえ XSS を実行する echo などを始めとしてろくなことが起きないので立派に脆弱性です。
余談ですが例の $_GET で include するコードではディレクトリトラバーサルとしてもシャレにならない脆弱性を持ちます(?page=../../etc/hogehoge など色々見られます)。妙な include 機構を作るよりも composer の様な問題がない、あるいは見つかっていないオートローダーに頼った方が無難です。