
Authentifizierte Remote-Codeausführung in in VTiger Open Source CRM v7.5
Authentifizierte Remote-Code-Ausführung in VTiger Open Source CRM v7.5
Eine Schwachstelle existiert im Benutzermodul der aktuellen Version von VTiger CRM Open Source v7.5.0, die es einem authentifizierten Angreifer ermöglicht, beliebigen PHP-Code in config.inc.php zu schreiben und auszuführen.
Wenn ein Benutzer normalerweise in VTiger authentifiziert ist, überprüft es seinen Setup-Status, um zu sehen, ob dies ein neuer Benutzer ist, der noch nicht vollständig konfiguriert ist. Es überprüft auch, ob dies der erste Benutzer ist, also ein Admin, der bestimmte globale Eigenschaften konfigurieren sollte. Wenn ja, wird er zu einer UserSetup-Aktion im Benutzermodul umgeleitet.
$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, line 112
In dieser Aktion gibt es eine Überprüfung, ob der Benutzer eine globale Währungseinstellung (standardmäßig "USA, Dollars") übergeben hat, und speichert sie mit der Funktion 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, line 28
In der Funktion updateBaseCurrency wird der übergebene Wert als globale Währungseinstellung für das gesamte System in der Datenbank gesetzt, und sie ruft auch die Funktion updateConfigFile auf, die die Konfigurationsdatei öffnet und PHP str_replace verwendet, um den vorhandenen Wert durch den übergebenen zu ersetzen.
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, line 148
Die Benutzereinrichtungsaktion in der aktuellen Version von VTiger CRM überprüft nicht, ob der Benutzer tatsächlich eingerichtet ist oder nicht, oder ob er die Berechtigung zum Ändern globaler Variablen hat. Es wird nur angenommen, dass wenn Sie auf diese Seite zugreifen, Sie die Person sind, die sie konfigurieren sollte. Durch die Verwendung eines vorhandenen Sitzungscookies und eines CSRF-Tokens, das von einer beliebigen authentifizierten Seitenladung stammt, kann ein böswilliger Benutzer einen Währungswert wie folgt POSTen:
USA, Dollars';@passthru($_GET['cmd']);//
Dieser Wert wird dann blind in die Datei config.inc.php geschrieben als:
//Master currency name
$currency_name = 'USA, Dollars';@passthru($_GET['cmd']);//';
Da die Konfigurationsdatei auf jeder Seite geladen wird, kann ein böswilliger Benutzer einfach einen Unix-Befehl als Parameter cmd übergeben und die Ausgabe oben auf der Seite sehen.

Dieses Problem wurde in diesem Commit behoben, wo eine zusätzliche Validierung hinzugefügt wurde, um sicherzustellen, dass böswillige Währungsnamen nicht von Benutzern eingegeben werden können, und stattdessen der Wert aus der Datenbanktabelle gezogen wird.
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);
}