PHP - Deserialization + Autoload Classes
İlk olarak, Otomatik Yükleme Sınıfları'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 edebilirsinizBunun 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:{}
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.
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.
Ş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:
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.
Last updated