eFront 3.6.15: Steal your professors password


eFront

Today, we present our analysis results for eFront, the open-source edition of the thriving e-learning platform eFrontPro. The platform is used by hundreds of organizations world-wide and consists of over 700,000 lines of PHP code, rendering manual security analysis ineffective at best. We will analyze two SQL injections that can be used to leak sensitive data and demonstrate two related RIPS features for detection.

RIPS Analysis

Our SAST tool RIPS analyzed the whole application in only 1m 32s and uncovered many severe security issues. Most of them are straight-forward SQL Injections that can be used to extract confidential user data, such as passwords, private messages, course results, and personal information. Also, a code evaluation vulnerability was detected but luckily for the users, the affected user-defined function is not in use. Still, we added it to our demo report.

Case Study

Example 1: SQL Injection and Context Tab

The first example is a SQL Injection vulnerability that can be exploited by any registered student. A student account is easily attainable due to the nature of the platform and no other obstacles have to be bypassed. The following code lines trigger the vulnerability.

libraries/includes/social.php


$id = $_GET['id'];
eF_getTableData("lessons_timeline_topics_data", "*", "id=" . $id);

libraries/database.php


function eF_getTableData($table, $fields = "*", $where = "", $order = "", $group = "", $limit = "") {
    $sql = prepareGetTableData($table, $fields, $where, $order, $group, $limit);
    $GLOBALS['db']->GetAll($sql);

Here, the GET parameter id is concatenated directly into the third parameter $where of the eF_getTableData() function without any input sanitization or validation. Then, this parameter is passed to the prepareGetTableData() function in order to built a SQL query.

libraries/database.php


function prepareGetTableData($table, $fields = "*", $where = "", $order = "", $group = "", $limit = "") {
    ⋮
    $sql = "SELECT ".$fields." FROM ".$table;
    if ($where != "") {
        $sql .= " WHERE ".$where;
    }

In prepareGetTableData(), the $where variable is appended to the SQL query in line 401, as shown in the code summary above. As a result, the susceptible SQL query is executed within the GetAll() method. An attacker can inject arbitrary SQL commands into the where clause and alter the SQL query result, such that sensitive information are retrieved from the database instead of the intended topics data. For example, the attacker is able to retrieve the professors’ passwords or to read all private messages. The vulnerability can be patched by casting the GET parameter id to integer: $id = (int)$_GET['id']. This way, only numeric values can be used as id in the WHERE clause and no SQL commands can be injected.

RIPS is able to follow the data flow throughout the function and method calls and detects the tainted data in the SQL query that is finally executed. The cool thing is that RIPS is also able to reconstruct the full SQL query that is built. This eases the verification of a vulnerability drastically, specifically for large data flow traces. In the context tab of RIPS, the fully reconstructed SQL query and the injection point of tainted user input is presented:


SELECT * FROM G_DBPREFIXlessons_timeline_topics_data WHERE id=$_GET['id']

Example 2: SQL Injection and Array Analysis

Our second example shows a SQL injection that is very similar to the first one, which is the case for almost all SQL injections within the application.

libraries/database.php


foreach ($_POST as $key => $value) {
    $fields[$key] = $value;
}
⋮
$fields['users_LOGIN'] = $_SESSION['s_login'];
⋮
unset($fields['objectives']);
⋮
eF_getTableData("scorm_data_2004", "total_time,id", "content_ID=" . $fields['content_ID'] . " AND users_LOGIN='" . $fields['users_LOGIN'] . "'");

libraries/includes/lms_commit.php


function eF_getTableData($table, $fields = "*", $where = "", $order = "", $group = "", $limit = "") {
    $sql = prepareGetTableData($table, $fields, $where, $order, $group, $limit);
    $GLOBALS['db']->GetAll($sql);

Here, all data within the superglobal $_POST variable is propagated to the $fields array (lines 10-12). Then, the keys content_ID and users_LOGIN are concatenated unsanitized to the SQL query via the $where parameter of the eF_getTableData() function.

From the static code analysis point of view, this example is interesting because it requires a highly precise analysis of data flow through arrays and its keys. First, the propagation of arbitrary tainted data to arbitrary array keys in the foreach loop has to be detected. Then again, the tainted data in specific array keys are overwritten (users_LOGIN) or unset (objectives), effectively eliminating the possibility for exploitation for these specific keys. In the end, the analysis must decide which array keys can be tainted by a malicious user, and which array keys cannot and would lead to false positive reports.

Time Line

DateWhat
2016/09/28First contact with vendor
2016/09/28Vendor publicly declares EOL for open-source edition

Summary

In this post, we covered two SQL injection vulnerabilities. While the issues seem easy to spot from our code summaries, they were hidden in 700,000 lines of code. With the help of our code analysis solution RIPS the issues were automatically and precisely detected.

The vendor reacted quickly to our submission and, surprisingly, declared the end-of-life for the open-source edition. For the plenty of users of this version there are currently no patches available. Hopefully, the community will be able to address some of these problems, for example by introducing prepared statements to the code base. We did not perform an analysis of the professional edition.


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

APAV Time Table

DateAuthorTitle
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 3.0.0.5: 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 2.1.26.8: 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: php, security, efront, apav, sql injection,

Comments

comments powered by Disqus