我正在寻找一个SQL查询来清理被黑客入侵的SQL Server数据库。我有一些基本的SQL知识,但我不知道如何解决以下问题。
对于我们的某个网站,我们有一个最近被黑客入侵的SQL Server数据库。成千上万的记录充满了隐藏的div,包含各种狡猾的引用。我们的ISP说数据库的内容不是他们的责任,他们不知道如何帮助我们清理数据库。没有可用的干净备份。手动浏览所有记录太过分了。
所以我现在拼命想找到一个SQL查询来从数据库中删除这些隐藏文本块。
两个有用的信息:
所有垃圾内容都包含在div标签中。标签之间的信息在每个实例中都是不同的,但它们都使用div标签打开和关闭。
我们的原始数据将包含一些HTML内容,但绝不会包含div标签。因此,如果我们能找到一种方法来删除从起始div到包括结束div的所有内容,那么我们将进行排序。
非常感谢这里的任何帮助。谢谢你的时间。
答案 0 :(得分:2)
试试这个;只有在你的假设是正确的情况下才会有用。黑客的另一个假设是没有添加嵌套的DIV。是的,在运行更新之前彻底测试它。并在运行更新之前备份您的数据。
CREATE TABLE #temp(id INT IDENTITY, html VARCHAR(MAX));
INSERT #temp(html)
VALUES('<p>Some text</p><strong>other text</strong><div>added by hacker</div>')
,('<p>Some text</p><strong>other text<div>added by hacker within html tag</div></strong>')
,('<p>Some text</p><div>some other text added by <a href="http://google.com">hack</a></div><strong>other text</strong>');
SELECT html
, CHARINDEX('<div',html) AS startPos
, CHARINDEX('</div>',html) AS endPos
, (CHARINDEX('</div>',html)+6)-(CHARINDEX('<div',html)) AS stringLenToRemove
, SUBSTRING(html, CHARINDEX('<div',html), (CHARINDEX('</div>',html)+6)-(CHARINDEX('<div',html))) AS HtmlAddedByHack
,REPLACE(html,SUBSTRING(html, CHARINDEX('<div',html), (CHARINDEX('</div>',html)+6)-(CHARINDEX('<div',html))), '') AS sanitizedHtml
FROM #temp;
--UPDATE #temp
--SET html = REPLACE(html,SUBSTRING(html, CHARINDEX('<div',html), (CHARINDEX('</div>',html)+6)-(CHARINDEX('<div',html))), '');
--SELECT *
--FROM #temp;
答案 1 :(得分:1)
使用PATINDEX
的UDF可能会这样做。
假设
<DIV>...</DIV>
部分<DIV>...</DIV>
个部分
首先使用此UDF进行模式替换,来自here:
CREATE FUNCTION dbo.PatternReplace
(
@InputString VARCHAR(4000),
@Pattern VARCHAR(100),
@ReplaceText VARCHAR(4000)
)
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE @Result VARCHAR(4000) SET @Result = ''
-- First character in a match
DECLARE @First INT
-- Next character to start search on
DECLARE @Next INT SET @Next = 1
-- Length of the total string -- 8001 if @InputString is NULL
DECLARE @Len INT SET @Len = COALESCE(LEN(@InputString), 8001)
-- End of a pattern
DECLARE @EndPattern INT
WHILE (@Next <= @Len)
BEGIN
SET @First = PATINDEX('%' + @Pattern + '%', SUBSTRING(@InputString, @Next, @Len))
IF COALESCE(@First, 0) = 0 --no match - return
BEGIN
SET @Result = @Result +
CASE --return NULL, just like REPLACE, if inputs are NULL
WHEN @InputString IS NULL
OR @Pattern IS NULL
OR @ReplaceText IS NULL THEN NULL
ELSE SUBSTRING(@InputString, @Next, @Len)
END
BREAK
END
ELSE
BEGIN
-- Concatenate characters before the match to the result
SET @Result = @Result + SUBSTRING(@InputString, @Next, @First - 1)
SET @Next = @Next + @First - 1
SET @EndPattern = 1
-- Find start of end pattern range
WHILE PATINDEX(@Pattern, SUBSTRING(@InputString, @Next, @EndPattern)) = 0
SET @EndPattern = @EndPattern + 1
-- Find end of pattern range
WHILE PATINDEX(@Pattern, SUBSTRING(@InputString, @Next, @EndPattern)) > 0
AND @Len >= (@Next + @EndPattern - 1)
SET @EndPattern = @EndPattern + 1
--Either at the end of the pattern or @Next + @EndPattern = @Len
SET @Result = @Result + @ReplaceText
SET @Next = @Next + @EndPattern - 1
END
END
RETURN(@Result)
END
然后,使用UDF:
UPDATE ContentTable SET ContentColumn=dbo.PatternReplace('<DIV>%</DIV>', '')
答案 2 :(得分:1)
也许像这样的光标......
Declare @ColumnName sysname , @TableName sysname
,@Schema sysname , @Sql Nvarchar(MAX);
Declare Cur CURSOR FOR
Select c.name , t.name , s.name
from sys.columns c
inner join sys.tables t on c.object_id = t.object_id
inner join sys.types p on p.user_type_id = c.user_type_id
inner join sys.schemas s on t.schema_id = s.schema_id
where t.is_ms_shipped = 0
and p.name in ('varchar','nvarchar', 'char', 'nchar')
OPEN Cur
FETCH NEXT FROM Cur INTO @ColumnName , @TableName , @Schema
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Sql = N'UPDATE '+ QUOTENAME(@Schema) +'.' + QUOTENAME(@TableName)
+ N' SET ' + QUOTENAME(@ColumnName) + N' = '
+ N'LEFT(' + QUOTENAME(@ColumnName) + N', CHARINDEX(''<div>'',
' + QUOTENAME(@ColumnName) + N') - 1)
+ SUBSTRING(' + QUOTENAME(@ColumnName) + N',
CHARINDEX(''</div>'', ' + QUOTENAME(@ColumnName) + N') + 6
, LEN(' + QUOTENAME(@ColumnName) + N'))
Where ' + QUOTENAME(@ColumnName) + N' IS NOT NULL
AND LEN(' + QUOTENAME(@ColumnName) + N') > 6'
Exec sp_executesql @Sql
FETCH NEXT FROM Cur INTO @ColumnName , @TableName , @Schema
END
CLOSE Cur
DEALLOCATE Cur
注意强>
游标遍历所有表并选择具有varchar , nvarchar, char ,nchar
数据类型的列,然后创建一个更新语句以去除<div> </div>
标记之间的任何字符串(如果存在),否则保留列为它是。
警告
在对实时数据库实际运行脚本之前测试脚本。