技术资讯   > 技术文章 > 对数据库被挂马时的script和iframe进行清理替换
[发表时间: 2009-09-01 03:57 ]

前几天,有个朋友和我谈到了一个问题,他在处理数据库中木马<script>时,想清理MSSQL数据中的那些代码,在SQL查询分析器直接用命令replace时,但就遇到了"...函数replace的参数1的数据类型ntext无效"的问题,这里我就不详细说了。网上也有一些说用UPDATETEXT之类的方法,但小的不怎么会,哈哈,唯有写了一个程序给他用。相信有一些朋友会用得到,所以在这里我贴出给大家了。多多指教!

这里要注意啊,这个是对scrip块t和iframe块通杀的,不分站内或外站链接的。

一般情况挂木马都是带有http外站链接的,所以你可以把

代码:

new_content = RegReplace(RegReplace(Rs_1("Contents"),"<SCRIPT[^<]*</SCRIPT>",""),"<IFRAME[^<]*</IFRAME>","")

改成

代码:

new_content = RegReplace(RegReplace(Rs_1("Contents"),"<SCRIPT[^<]*http</SCRIPT>",""),"<IFRAME[^<]*http</IFRAME>","")

这样就保证自己的JS不被杀了。

我就喜欢通杀了,因为我不会在内容上添加这些代码。

请大家在自己本机上测试再用到真正的运用上。

对于数据多的朋友,以下这句也可能会造成ASP超时的,你们自己可以在这个程序上作出一些优化,我就暂时不写了。

代码:

sql = "select Count("& data_id &") as CountNum from "& data_tbl &" where "& data_name &" like '%"& keyword &"%'"

程序代码:

代码:

<!--#include file="conn.asp"-->

<%

'==========================================================================

'==================对数据库的script和iframe进行清理替换======================

'==========================================================================

'Author:Niky|秋风

'Email:ec365@163.com

'QQ:35550507

'==========================================================================

'没有加入程序的页面界面,人啊,就是懒,没办法,嘻嘻!!

'使用方法:直接运行文件链接就行了.如:http://www.domain.com/replace_pro.asp

'==========================================================================

'****************************************************

'函数名:RegReplace

'作  用:对str 进行正则替换

'参  数:Str,PatternStr,RepStr

'****************************************************

Function RegReplace(Str,PatternStr,RepStr)

    Dim NewStr,regEx

    NewStr = Str

    if isnull(NewStr) then

        RegReplace = ""

        exit Function

    End if

    Set regEx = New RegExp

    regEx.IgnoreCase = True

    regEx.Global = True

    regEx.Pattern=PatternStr

    NewStr = regEx.Replace(NewStr,RepStr)

    RegReplace = NewStr

End Function

'****************************************************

'*********************设置相关参数********************

'****************************************************

'为防止ASP超时,这里可以设置每次最多处理的数据条数

'如果你的中马的数据大于max_num,那么需要你运行(总数据/max_num)相除出来的次数了

'如果设max_num为0,则处理所有带script和iframe的数据,注意可能会造成超时

'****************************************************

max_num = 20

'****************************************************

'设置数据库表名

'****************************************************

data_tbl = "table"

'****************************************************

'设置数据的ID编号名 如:id 或 newid ...

'****************************************************

data_id = "id"

'****************************************************

'设置查找和替换数据列名--修改此项必须也要修改rs_2("***")

'****************************************************

data_name = "contents"

'*******************程序查找替换开始******************

For i_time = 1 To 2

    '检测关键字

    Select Case i_time

        Case 1    keyword = "<script"

        Case 2    keyword = "<iframe"

    End Select

    '首先是检查有没存在相关要替换的关键字的数据

    Set Rs=server.createobject("adodb.recordset")

    sql = "select Count("& data_id &") as CountNum from "& data_tbl &" where "& data_name &" like '%"& keyword &"%'"

    Rs.Open Sql,Conn,1,1

    '如果有的话就计算出总数是多少

    If not Rs.eof then

        '读取总数

        CountNum=Cstr(Rs("CountNum"))

        If CountNum > 0 then

            '初始化记录条数

            rec_num = 0

            ii = 1

            If max_num <> 0 And max_num > 0 then

                '每次限制处理的数据

                If CountNum > max_num Then CountNum = max_num

            End If

            

            '然后一个一个地读出来替换数据

            '开始循环

            Do While ii < CountNum +1

                

                ii = ii + 1

                

                Set Rs_1=server.createobject("adodb.recordset")

                sql_1 = "select top 1 "& data_id &" as temp_id,"& data_name &" as Contents from "& data_tbl &" where "& data_name &" like '%"& keyword &"%'"

                Rs_1.Open Sql_1,Conn,1,1

                If Rs_1.eof Then '如果没有了记录就退出Do块,防止无用的循环

                    Exit Do

                End If

                '记录处理的条数

                rec_num = rec_num + 1

                

                '读取ID和内容

                id = Rs_1("temp_id")

                '利用正则替换内容

                new_content = RegReplace(RegReplace(Rs_1("Contents"),"<SCRIPT[^<]*</SCRIPT>",""),"<IFRAME[^<]*</IFRAME>","")

                    '更新内容

                    Set rs_2 = Server.CreateObject("ADODB.Recordset")

                    sql_2="select * from "& data_tbl &" where "& data_id &"="& id

                    rs_2.open sql_2,conn,1,3

                    

                    '+++++++++++++++++++++rs_2("***")中的***修改成你的数据字段++++++++++++++++++++

                    rs_2("contents") = new_content

                    '+++++++++++++++++++++rs_2("***")中的***修改成你的数据字段+++++++++++++++++++++

                    rs_2.update

                    rs_2.close

                    set rs_2 = Nothing

                    Response.write "数据ID:"& id &"已经处理完毕!"&"<br />"

                rs_1.close

                set rs_1 = nothing

            Loop

            Response.write ("<script>alert('带"& keyword &"关键字的全部"&rec_num&"个数据已经处理完毕!')</script>")

        else

            Response.write ("<script>alert('没有带"& keyword &"关键字的数据可处理!')</script>")

        End If

    End If

Next

rs.close

set rs = Nothing

%>

实现思路二:

  首先备份数据库,以防不必要的损失。而后对所有被挂马的小于8000字符的varchar字段执行

SQL Code

update 表名 set 字段名=replace(字段名,'<Script Src=http://xxx.cn/css/c.js></Script>','')  

其中<Script Src=http://xxxx.com/css/c.js></Script>为挂马字段。执行后挂马字段被清除。但是有部分字段,比如内容字段等大于8000字符的varchar字段则需要执行

SQL Code

update 表名 set 表项=replace(cast(表项 as varchar(8000)),’<Script Src=http://xxx.com/css/c.js> </Script> ’,’’)   

来更新被挂马字段,而房产网由于内容比较多,执行以上语句的时候会发生假死现象,于是加个区间分两次进行,一次处理15000条得以解决。

SQL Code

update 表名 set 表项=replace(cast(表项 as varchar(8000)),’<Script Src=http://xxxx.com/css/c.js> </Script> ’,’’) where id>1 and id<15000  

这是在查询分析器中执行的,不必通过iis了,提高效率。