最近网站老是被攻击,sql注入,他NND,搞死滴人,就是找不到注入的入口,90个表,开始也没当回事,一个表一个表的去替换注入sql,现在知道问题大了,隔个把月来一次,暂时还没找到解决办法,只能兵来将挡水来土掩,写个sql,批量解决,下面是sql语句,
很简单,只要你熟悉系统表结构关系就很容易搞定,这个问题只需要两个系统表关联即可,sys.sysobjects和sys.syscolumns,关联字段:id
第一步:筛选特定数据库,只需要在第一句加上
use 数据库名称
go
第二步:找到数据库下所有用户表
select * from sys.sysobjects where xtype='u'
第三步:找到表下面的所有字段(对于sql注入,一般都是指字符串字段)
select * from sys.syscolumns where id=@table_id and (xtype=167 or xtype=231)
方法一:
后面的步骤就不多说了,只是记录日志,不是写文章,代码贴出来,方便以后用。希望也能给各位朋友带来方便
Code
USE [BusinessSend]
GO
/****** 对象: StoredProcedure [dbo].[CleanSqlInject] 脚本日期: 04/13/2009 17:51:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE proc [dbo].[CleanSqlInject]
@errorMsg varchar(300) --要替换的错误字符串
as
declare @table_count int,@index int,@table_name varchar(50),@table_id int --表数量、表索引、表名称、表id
set @index=1
-------------------循环当前数据库,所有表记录--------------------
select @table_count = count(*) from sys.sysobjects where xtype='u'
while(@table_count>0)
begin
select @table_id=(select id from ( select row_number() over (order by id) row,id from sys.sysobjects where xtype='u')tb where row=@index)
select @table_name = name from sys.sysobjects where id=@table_id
print '@table_name : '+@table_name
print '@table_index : '+convert(varchar(10),@index)
-------------------循环当前表,所有字段,执行批量替换--------------------
declare @column_count int,@row int,@column_name varchar(50),@sql_str varchar(5000) --字段数量、字段索引、字段名称、拼接的字符串(update语句set后面的字符串)
set @row=1
set @sql_str = ''
select @column_count = count(*) from sys.syscolumns where id=@table_id and (xtype=167 or xtype=231 or xtype=35)
print '@column_count : '+ convert(varchar(10),@column_count)
while(@column_count>0)
begin
declare @type int
select @type = xtype from ( select row_number() over (order by name) row,xtype from sys.syscolumns where id=@table_id and (xtype=167 or xtype=231 or xtype=35))tb where row=@row
select @column_name = name from ( select row_number() over (order by name) row,name from sys.syscolumns where id=@table_id and (xtype=167 or xtype=231 or xtype=35))tb where row=@row
print '@column_name'+convert(varchar(10),@row)+' : '+@column_name
--处理text字段类型
if @type=35
begin
set @sql_str = @sql_str + @column_name +' = replace(cast('+ @column_name +' as varchar(max)),'''+ @errorMsg +''',''''),'
end
--处理varchar、nvarchar字段类型
else
begin
set @sql_str = @sql_str + @column_name +' = replace('+ @column_name +','''+ @errorMsg +''',''''),'
end
set @column_count=@column_count - 1
set @row = @row + 1
end
if len(@sql_str)>0
begin
set @sql_str = substring(@sql_str,0,len(@sql_str))
print '@sql_str : update ' + @table_name + ' set '+@sql_str
exec('update ' + @table_name + ' set '+@sql_str)
end
else
begin
print 'no records'
end
set @table_count=@table_count - 1
set @index = @index + 1
print ''
end
存在的问题:
执行改存储过程,数据表每个字段都会去替换,不管有没有被注入,效率不咋滴。希望大家能继续完善
执行结果展示:
方法二:
最近在网上看到了一个更好的办法,通过游标:
Code
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+']=replace(Rtrim(Convert(Varchar(8000),['+@C+'])),''<script src=http://3b3.org/c.js></script>'','''')')
Fetch Next From Table_Cursor Into @T,@C
End
Close Table_Cursor
Deallocate Table_Cursor