Guest Post: Vtiger 6.5.0 - SQL Injection


The Vtiger CRM is an open source Customer Relationship Management software developed by Vtiger. With more than 4.5 million downloads on SourceForge it enjoys great popularity. Some weeks ago, I had the chance to play with RIPS and test its features - and was invited as guest author to write this post. As I did some manual research of the Vtiger CRM before and already found several vulnerabilities, I decided to use it for my first experiments with RIPS.

RIPS Analysis

RIPS analyzed the 27,371 files with around 650,000 lines of code in only 6 minutes. Due to the nature of a CRM system, it is necessary to have a valid user account to access any of the provided features. Nevertheless, the discovered issues allowed low-privileged users to access highly sensitive data.

The truncated analysis results are available in our RIPS demo application. Please note that we limited the results to the issues described in this post in order to ensure a fix is available.

Case Study

RIPS detected multiple issues, including a previously unknown SQL injection vulnerability in the Calendar module, which will be explained in the following.

Example: SQL Injection

RIPS Screenshot 1

One great feature of RIPS is to show the chain of calling functions and the exact context of the vulnerability. In this case, it showed that the request parameter contactidlist was directly passed to a query string without any sanitizing.

RIPS Screenshot 2

Taking a closer look at the source code revealed that contactidlist is expected to be a semi-colon separated list of IDs, inserted into the vtiger_cntactivityrel table to create a reference to the currently edited calendar entry.


if(isset($_REQUEST['contactidlist']) && $_REQUEST['contactidlist'] != '') {
    $adb->pquery('DELETE from vtiger_cntactivityrel WHERE activityid = ?', array($recordId));
        $contactIdsList = explode (';', $_REQUEST['contactidlist']);
        $count = count($contactIdsList);
        $sql = 'INSERT INTO vtiger_cntactivityrel VALUES ';
        for($i=0; $i<$count; $i++) {
            $sql .= " ($contactIdsList[$i], $recordId)";
            if ($i != $count - 1) {
                $sql .= ',';
        $adb->pquery($sql, array());

As the injection could only be abused within an INSERT statement, it was necessary to further inspect the database structure in order to determine which kind of data and how many bytes might be used as payload.

Due to the fact that vtiger_cntactivityrel is meant to be a connection table for many-to-many relations between contacts and activities, both values are of the type "integer" with the additional limit of displaying at most 19 digits.

In order to exemplarily extract values of the user table, it was necessary to use several MySQL functions to crop the read value, transform it to its hex representation and convert it to an integer (basis 10). With the given limit, it was possible to store 4 characters per entry. The fact that contactidlist might contain multiple, semi-colon separated values could be abused to insert multiple entries at once and thus significantly increase the performance.

We were now able to insert (limited) arbitrary content to the database, but needed a way to obtain the data somehow. Further analyzing the HTML response of the calendar detail view, yielded the database value being reflected as record parameter of the links to the related contact entries.


<label class="muted pull-right marginRight10px">Contact Name</label>
<td class="fieldValue medium" id="Events_detailView_fieldValue_contact_id">
    <span class="value" data-field-type="multireference">
    <a href='index.php?module=Contacts&view=Detail&record=1633971561' title='Contacts'></a><br>

Converting the integer back to hex and then ASCII, finally resulted in the first 4 characters of the user name "admin":

>>> binascii.unhexlify(format(1633971561, 'x'))

Time Line

2016/09/15Initial vendor contact
2016/09/15Vendor reponse
2016/09/15Sent security advisory to vendor
2016/09/23Vendor pushed a fix to repository
2016/10/21Asked about official release
2016/10/25Vendor will release new version in Q1 2017


Sometimes it is necessary to perform multiple steps on different endpoints to gain any advantage of a supposedly harmless operation. Finding such issues is difficult with classical webapplication scanners or manual audits. By using automated static code analysis and data flow inspection, one gets multiple possible entry points within seconds to focus on. It was a great experience and a lot of fun to work with RIPS. Even if manual inspection is still necessary to verify a possible finding, it revelead a practically exploitable SQL injection vulnerability I did not find in any previous analysis.

Follow us on Twitter to be notified when the next gift of our advent calendar is opened!

APAV Time Table

19 Feb 2019Simon ScannellWordPress 5.0.0 Remote Code Execution
29 Jan 2019Simon ScannellCTF Writeup: Complex Drupal POP Chain
15 Jan 2019Simon ScannellLearnings from WordPress Security Month
24 Dec 2016Johannes DahseWhat we learned from our Advent Calendar
23 Dec 2016Hendrik Buchwalde107 2.1.2: SQL Injection through Object Injection
22 Dec 2016Daniel PeerenSecurity Compliance with Static Code Analysis
21 Dec 2016Martin BednorzAbanteCart 1.2.8 - Multiple SQL Injections
20 Dec 2016Martin BednorzKliqqi From Cross-Site Request Forgery to Code Execution
19 Dec 2016Robin PeraglieosClass 3.6.1: Remote Code Execution via Image File
18 Dec 2016Daniel PeerenContinuous Integration - Jenkins at your service
17 Dec 2016Johannes DahseOpenConf 5.30 - Multi-Step Remote Command Execution
16 Dec 2016Robin PeraglieRedaxo 5.2.0: Remote Code Execution via CSRF
15 Dec 2016Dennis DeteringGuest Post: Vtiger 6.5.0 - SQL Injection
14 Dec 2016Hendrik BuchwaldThe State of Wordpress Security
13 Dec 2016Johannes DahsephpBB 2.0.23 - From Variable Tampering to SQL Injection
12 Dec 2016Martin BednorzTeampass Unauthenticated SQL Injection
11 Dec 2016Daniel PeerenRescanning Applications with RIPS
10 Dec 2016Hendrik BuchwaldNon-Exploitable Security Issues
9 Dec 2016Hendrik BuchwaldPrecurio 2.1: Remote Command Execution via Xinha Plugin
8 Dec 2016Martin BednorzPHPKit 1.6.6: Code Execution for Privileged Users
7 Dec 2016Hendrik BuchwaldSerendipity 2.0.3: From File Upload to Code Execution
6 Dec 2016Robin PeraglieRoundcube 1.2.2: Command Execution via Email
5 Dec 2016Hendrik BuchwaldExpression Engine 3.4.2: Code Reuse Attack
4 Dec 2016Johannes DahseIntroducing the RIPS analysis engine
3 Dec 2016Martin BednorzeFront 3.6.15: Steal your professors password
2 Dec 2016Martin BednorzCoppermine 1.5.42: Second-Order Command Execution
1 Dec 2016Hendrik BuchwaldFreePBX 13: From Cross-Site Scripting to Remote Command Execution
25 Nov 2016Martin BednorzAnnouncing the Advent of PHP Application Vulnerabilities

Disclaimer: The information provided here is for educational purposes only. It is your responsibility to obey all applicable local, state and federal laws. RIPS Technologies GmbH assumes no liability and is not responsible for any misuse or damages caused by direct or indirect use of the information provided.

Tags: dennis detering, php, security, vtiger, sql injection,

Author: Dennis Detering

IT Security Consultant / Penetration Tester

Dennis has a Master's degree of IT security from the Ruhr-University Bochum and works as a penetration tester at the CSPi GmbH in Cologne. He has an avid interest in web, network and industrial security and loves to research together with the RIPS team and software.

Is your application secure?  Scan Your Code

Related Posts


comments powered by Disqus