1. 程式人生 > >sql注入的實用應對措施

sql注入的實用應對措施

關於sql注入大家可能或多或少有所瞭解,這篇文章介紹得很詳細,大家可以看下:

總結了下最主要的原理就是利用sql語句中的註釋漏洞--

sql = "select * from user_table where username='" & userName & "' and password='" & password & "'"

例如上面的拼接語句,通常我們輸入賬號admin密碼123456,那麼拼接後的sql語句是:

select * from user_table where username='admin' and password='123456'

但是,如果黑客會在前臺表單的使用者名稱那兒填寫' or 1=1 --那麼會發生什麼神奇的結果呢?看下面拼接的結果:

select * from user_table where username='' or 1=1 --' and password=''

大家會發現,竟然通過驗證了!是不是很難受?

上面的案例再調整下讓你更難受,假如輸入admin' or 1=1 --現在我們再來看看:

select * from user_table where username='admin' or 1=1 --' and password=''

你是不是想握了棵草?

根據上面博文介紹的還有更絕的,利用sql語句的;表示一句間隔來執行sql語句,想幹嘛就幹嘛,簡直為所欲為!!!

輸入';DROP TABLE user_table --拼接結果:

select * from user_table where username='';DROP TABLE user_table --' and password=''

 這真是要命呀。

根據上面的規律,我們好像只要對sql語句整體處理下替換掉--就行了是吧。那麼用admin' or '1'='1來試試:

select * from user_table where username='admin' or '1'='1' and password=''

是不是防不勝防啊?! 有人會說這樣不對,後面的password他沒法猜中的。其實本來兩個欄位驗證現在變成了一個欄位驗證了,只要password滿足即可,現在的人很多用弱口令,比如12345,那我只要密碼滿足就驗證通過就能進入後臺了,對於一個使用者數量如果比較多的系統隨便輸入個123456、888888等簡單密碼總會撞上的,有了後臺到時就更好進一步突破了。

總結了下無非這些情況:

'’or 1 = 1 -- and password='’
"or "a"="a
admin' or '1'='1
' or ''='
 ')or('a'='a
or 1=1--
'or 1=1--
a'or' 1=1--
"or 1=1--
'or'a'='a
"or"="a'='a
'or''='
'or'='or'
1 or '1'='1'=1
1 or '1'='1' or 1=1
 'OR 1=1%00

那麼下面我們可以想對策了。

1.根據規律,我們首先要檢測是否含有--,因為正常的表示式中不可能含有註釋符號的,只要包含就認為此條sql語句非法。

2.檢測是否含有;因為正常的表示式中不可能含有分號的,只要包含就認為此條sql語句非法。

3.接著我們檢測是否包含恆等式,例如上面的1=1或者1='1'或者'abc'='abc'以及其他各種字元,我們得想個通用的策略。處理步驟:

(1).為了避免單引號的干擾,我們將所有非數字字母等號之外的字元都替換為空格,可以用正則表示式:[^\da-zA-Z\r\n=],替換後得到:

  or 1 = 1    and password=  
 or  a = a
admin  or  1 = 1
  or   = 
   or  a = a
or 1=1  
 or 1=1  
a or  1=1  
 or 1=1  
 or a = a
 or = a = a
 or  = 
 or = or 
1 or  1 = 1 =1
1 or  1 = 1  or 1=1
  OR 1=1 00

(2).開始判斷是否包含恆等式,同樣用正則表示式:\s([^\s]+?)\s*=\s*(\1)\s*,我們嘗試匹配到的結果:

1.1 = 1	所在行: 1
(1).1 (2).1
2.a = a	所在行: 2
(1).a (2).a
3.1 = 1	所在行: 3
(1).1 (2).1
4.or   = 
   or	所在行: 4
(1).or (2).or
5.a = a	所在行: 5
(1).a (2).a
6.1=1	所在行: 6
(1).1 (2).1
7.1=1	所在行: 7
(1).1 (2).1
8.1=1	所在行: 8
(1).1 (2).1
9.1=1	所在行: 9
(1).1 (2).1
10.a = a	所在行: 10
(1).a (2).a
11.a = a	所在行: 11
(1).a (2).a
12.or  = 
 or	所在行: 12
(1).or (2).or
13.1 = 1	所在行: 14
(1).1 (2).1
14.1 = 1	所在行: 15
(1).1 (2).1
15.1=1	所在行: 15
(1).1 (2).1
16.1=1	所在行: 16
(1).1 (2).1

全部匹配到了,只要能匹配的都認為這條sql語句有問題,那麼選擇不執行。這樣就避免了sql注入。

這裡有個特殊的注入程式碼' or ''='替換後是  or   = ,我們會發現這不會被上面的匹配到,因為等號前後是空的。所以我們還要再來一步將所有空格替換掉,然後判斷是否包含or=,包含就認為非法。

總結就是:

1.判斷是否包含--

2.判斷是否包含;

3.判斷是否包含恆等式

4.其他特殊的,例如不能含有or=

包含就認定sql語句非法,拒不執行。網上通常的辦法的對每個欄位的值進行過濾一大堆關鍵字特殊字元,個人覺得比較繁瑣,經過我這4步後就將注入的問題拒之門外了。

asp中實現的辦法:

'檢測整個sql語句是否非法,如果非法將整個sql設定為空
function checkSql(byval strSql)
	dim s,strMsg
	s=strSql
	if instr(s,"--")=0 and instr(s,";")=0 then '不能包含--和;有就函式返回空
		s=replaceReg(s,"[^\da-zA-Z\r\n=]"," ")
		if not regTest(s,"\s([^\s]+?)\s*=\s*(\1)\s*") then '不能存在恆等式
			s=replace(s," ","")
			if instr(lcase(s),"or=")=0 then'不能含有or=,這裡主要都轉小寫進行比較
				checkSql=strSql
				exit function
			end if
		else
			strMsg="存在恆等式 " & s & "<br>" & getMatch1(s,"\b([^\s]+?)\b\s*=\s*\b(\1)\b")
		end if
	else
		strMsg="含有--或;"
	end if
	checkSql=strMsg
end function

function replaceReg(str1,strPattern,strNewString)
    Set reg = CreateObject("vbscript.regExp")
    reg.Global = True
    reg.IgnoreCase = True
    reg.MultiLine = True
    reg.Pattern = strPattern
    replaceReg= reg.Replace(str1, strNewString)
	set reg=nothing
End function

function regTest(str1,strPattern)
    Set reg = CreateObject("vbscript.regExp")
    reg.Global = True
    reg.IgnoreCase = True
    reg.MultiLine = True
    reg.Pattern = strPattern
    regTest= reg.test(str1)
	set reg=nothing
End function

function getMatch1Sub1(strData,strPattern)
	Set reg = CreateObject("vbscript.regExp")
	reg.Global = True
	reg.IgnoreCase = True
	reg.MultiLine = True
	reg.Pattern = strPattern'"====\r\n([^\r\n]*)\r\n[\s\S]*?2431682927627455"
	Set matchs = reg.Execute(strData)
	if matchs.Count>0 then getMatch1Sub1=matchs(0).SubMatches(0)
End function

以上為原創,個人考慮難免有不全面之處,如果有人發現有這4條之外還可能存在漏洞的,麻煩在下面留言告之,不勝感激涕零!!!