CVE-2024-7349 LifterLMS <= 7.7.5 - Authenticated SQL Injection


Introduction
LifterLMS is a secure easy-to-use WordPress LMS plugin packed with features to easily create & sell courses online. With over 10,000 websites set up, there are more than 8.3 million enrollments.

Exploit Title: LifterLMS <= 7.7.5 - Authenticated (Admin+) SQL Injection
Exploit Author: Furkan Karaarslan
Category: Webapps
CVE : CVE-2024-7349
Remotely Exploitable: Yes
Authentication Required: Yes
Vendor URL: https://lifterlms.com/
CVSSv3.1 Score: AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H

Technical Details
The vulnerability I discovered is due to the order parameter being taken into a variable without filtering. When exporting data, we sort the list in ASC or DESC order. During this sorting process, we could escape the query with a `,` and inject our own query.

Vulnerable Code

lifterlms/includes/abstracts/abstract.llms.database.query.php

    protected function sql_orderby() {

        $sql = '';

        $sort = $this->get( 'sort' );
        if ( $sort ) {

            $sql = 'ORDER BY';

            $comma = false;

            foreach ( $sort as $orderby => $order ) {
                $pre   = ( $comma ) ? ', ' : ' ';
                $sql  .= $pre . "{$orderby} {$order}";
                $comma = true;
            }
        }

        if ( $this->get( 'suppress_filters' ) ) {
            return $sql;
        }

          @since
         
          @param string              
          @param LLMS_Database_Query
         
        return apply_filters( "llms_{$this->id}_query_orderby", $sql, $this );

    }

The line highlighted in red above creates a variable for sorting but has not undergone any filtering, which means it could allow for interference with the query.

The code change made by LifterLMS to address the vulnerability issue is as follows:

                $sql  .= $pre . "{$orderby} {$order}";
                $sql  .= $pre . sanitize_sql_orderby( "{$orderby} {$order}" );

We have filtered the existing parameters using sanitize_sql_orderby().
sanitize_sql_orderby() filters special characters according to a regex.

Exploitation / Poc 

I see that the order parameters are used during export, and I was able to poc with , `,sleep(15)` payload.


SQLMAP: