Disable Functions Bypass - dl Function

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をサポートする

dl() は PHP に実行時に共有拡張をロードさせます。攻撃者が制御するモジュールをロードさせられれば、内部で execvesystem、その他のネイティブプリミティブを呼ぶ新しい PHP 関数を登録でき、結果として disable_functions をバイパスできます。

これは実在するプリミティブですが、現代のターゲットでは古い解説が示唆するほど一般的ではありません。

なぜこのバイパスは今日では稀なのか

主な障害は次のとおりです:

  • dl() が存在し、無効化されていないこと
  • enable_dl が動的ロードを許可していること
  • 対象の SAPI が dl() をサポートしていること
  • ペイロードは同一のターゲット ABI向けにコンパイルされた有効な PHP 拡張であること
  • 拡張は設定された extension_dir から到達可能であること

公式の PHP マニュアルが最も重要な現実確認です:dl() は CLI と embed SAPIs、そしてコマンドラインから実行される CGI SAPI のみで利用可能です。つまりこの手法は 通常の PHP-FPM/mod_php を介したウェブリクエストでは利用できない ことが多く、ペイロードの作成に時間を費やす前に SAPI を確認してください。

また、enable_dlINI_SYSTEM 設定であり、PHP 8.3.0 以降は PHP がこれを deprecated(非推奨) として文書化しているため、通常は攻撃者が制御する PHP コードから実行時にこれを変更することはできません。

もし dl() が利用できない場合は、より広い一覧の module/version dependent bypasses に戻ってください。

フットホールドからの迅速なトリアージ

何かを作る前に、モジュールが一致する必要がある正確なパラメータを収集してください:

<?php
phpinfo();
echo "PHP_VERSION=" . PHP_VERSION . PHP_EOL;
echo "PHP_SAPI=" . php_sapi_name() . PHP_EOL;
echo "ZTS=" . (PHP_ZTS ? "yes" : "no") . PHP_EOL;
echo "INT_BITS=" . (PHP_INT_SIZE * 8) . PHP_EOL;
echo "enable_dl=" . ini_get("enable_dl") . PHP_EOL;
echo "extension_dir=" . ini_get("extension_dir") . PHP_EOL;
echo "disabled=" . ini_get("disable_functions") . PHP_EOL;
?>

What you care about:

  • PHP_SAPI: if this is fpm-fcgi or apache2handler, dl() is usually a dead end for web exploitation
  • extension_dir: the payload must be loaded from here
  • PHP Version, architecture, debug/non-debug, and ZTS/non-ZTS: your module must match them
  • disable_functions: confirm whether dl is absent because it is disabled or because the SAPI does not support it

Practical exploitation constraints

1. You normally need write access to extension_dir

これは最大のボトルネックです。

dl()extension filename を受け取り、PHP はそれを extension_dir から読み込みます。実務では、/var/www/html/uploads のような通常の任意ファイルアップロードだけでは不十分で、PHP が実際に拡張を読み込む場所に .so/.dll を配置できるパスが必要です。

現実的に悪用が可能になる状況:

  • CTFs や意図的に弱く作られたラボで extension_dir が書き込み可能な場合
  • Shared-hosting やコンテナのミスで書き込み可能な extension パスが露出している場合
  • 既に extension_dir に到達できる別の任意ファイル書き込みプリミティブがある場合
  • そこにファイルを置けるまでに権限昇格した post-exploitation シナリオ

2. The module must match the target build

単に PHP_VERSION が一致するだけでは不十分です。拡張は次も満たしている必要があります:

  • OS と CPU アーキテクチャ
  • libc/toolchain の期待値
  • ZEND_MODULE_API_NO
  • debug ビルドか non-debug ビルドか
  • ZTS vs NTS

これらが一致しないと、dl() は失敗するかプロセスをクラッシュさせます。

3. open_basedir is not the main defense here

一度 extension_dir にモジュールを置き dl() を呼べれば、拡張コードは PHP プロセス内で実行されます。その時点での主要な障壁は open_basedir ではなく、拡張読み込みパスに有効な共有オブジェクトを配置できるかどうかでした。

Building the malicious extension

古典的な手順は今でも有効です:

  1. 被害者のビルドをできるだけ忠実に再現する
  2. phpize./configuremake を使って共有拡張をビルドする
  3. ネイティブのコマンド実行をラップする bypass_exec($cmd) のような PHP 関数をエクスポートする
  4. コンパイルしたモジュールを extension_dir にアップロードする
  5. dl() で読み込み、エクスポートされた関数を呼び出す

攻撃自体は古いですが、PHP 8.x の changelog にも dl() 固有のクラッシュ修正が継続して含まれているため、プリミティブ自体は残っています。難しいのは、それが到達可能でかつ一致するモジュールを配置できるデプロイ箇所を見つけることです。

Minimal workflow

On the attacker box

mkdir bypass && cd bypass
phpize
./configure
make

生成された共有オブジェクトは通常 modules/ の下にあります。

もし target と異なる環境でビルドしている場合、ABI が victim と一致することを確認するまでは生成されたファイルを下書きとして扱ってください。

Loading and using the extension

もし target が本当に dl() をサポートしており、モジュールが extension_dir の中にあるなら、ランタイム側は簡単です:

<?php
if (!extension_loaded('bypass')) {
dl('bypass.so'); // use the correct filename for the target platform
}
echo bypass_exec($_GET['cmd']);
?>

Windowsではファイル名は通常.dllになり、Unix系ターゲットでは通常.soになります。

攻撃者向けメモ

  • 文書や古い解説で function_exists("dl") が true を返しているからといってリモートで動作すると仮定しないこと; 実際の SAPI を検証する
  • dl() の試行が失敗すると、モジュールが互換性がない場合に PHP worker が停止する可能性がある
  • PHP 8 以降、disabled functions は関数テーブルから削除されるため、ユーザーランドの列挙は古い投稿と異なる場合がある
  • もし extension_dir に書き込めない場合、この手法は通常、FPM/FastCGI、LD_PRELOAD、または本節ですでに扱ったモジュール固有のバイパスより実用的でない

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をサポートする