文章目錄
- SQL注入的定義
- SQL注入為什么會成功?
- 為什么發生SQL注入?
- SQL注入的分析
- SQL的注入流程
- 判斷SQL注入點
- 判斷注入類型
- SQL注入的通常方法
- 防止SQL注入
SQL注入的定義
SQL注入是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。比如先前的很多影視網站泄露VIP會員密碼大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL注入式攻擊。當應用程序使用輸入內容來構造動態sql語句以訪問數據庫時,會發生sql注入攻擊。
如果代碼使用存儲過程,而這些存儲過程作為包含未篩選的用戶輸入的字符串來傳遞,也會發生sql注入。
理解:
現代的注入手法,其實就是利用現成的表格數據來執行非常規指令。簡單的說,利用非該段執行文本數據,代替正常數據做運算從而得到正確解。能夠實現這種操作的技術就叫做sql注入。
SQL注入為什么會成功?
Sql注入攻擊是利用是指利用設計上的漏洞,在目標服務器上運行Sql語句以及進行其他方式的攻擊,動態生成Sql語句時沒有對用戶輸入的數據進行驗證是Sql注入攻擊得逞的主要原因。
為什么發生SQL注入?
程序員在編寫代碼的時候,沒有對用戶輸入數據的合法性進行判斷,使應用程序存在安全隱患
用戶可以提交一段數據庫查詢代碼,根據程序返回的結果,獲得某些他想得知的數據或進行數據庫操作
當應用程序使用輸入內容來構造動態sql語句以訪問數據庫時,會發生sql注入攻擊。如果代碼使用存儲過程,而這些存儲過程作為包含未篩選的用戶輸入的字符串來傳遞,也會發生sql注入。
sql注入可能導致攻擊者使用應用程序登陸在數據庫中執行命令。
如果應用程序使用特權過高的帳戶連接到數據庫,這種問題會變得很嚴重。在某些表單中,用戶輸入的內容直接用來構造(或者影響)動態sql命令,或者作為存儲過程的輸入參數,這些表單特別容易受到sql注入的攻擊。而許多網站程序在編寫時,沒有對用戶輸入的合法性進行判斷或者程序中本身的變量處理不當,使應用程序存在安全隱患。這樣,用戶就可以提交一段數據庫查詢的代碼,根據程序返回的結果,獲得一些敏感的信息或者控制整個服務器,于是sql注入就發生了。
SQL注入的分析
對于Java數據庫連接JDBC而言,SQL注入攻擊只對Statement有效,對PreparedStatement是無效的,這是因為PreparedStatement不允許在不同的插入時間改變查詢的邏輯結構。
如驗證用戶是否存在的SQL語句為:用戶名'and password='密碼'
如果在用戶名字段中輸入: 'or 1=1'或是在密碼字段中輸入:'or 1=1'
將繞過驗證,但這種手段只對只對Statement有效,對PreparedStatement無效。相對Statement有以下優點:
1.防注入攻擊
2.多次運行速度快
3.防止數據庫緩沖區溢出
4.代碼的可讀性可維護性好
這四點使得PreparedStatement成為訪問數據庫的語句對象的首選,缺點是靈活性不夠好,有些場合還是必須使用Statement。
SQL的注入流程
判斷SQL注入點
找注入點是最關鍵,也最基礎的一個環節
本質原理:
找一個需要后臺處理后提交給數據的點,所有的輸入只要和數據庫進行交互的,都有可能觸發SQL注入
一般分為三大類:
Get參數觸發SQL注入
POST參數觸發SQL注入
Cookie觸發SQL注入
例如:
在常規的鏈接的參數中(鏈接?參數)找形如?id=num的搜索框
而驗證是否存在注入點方法有很多種
最常規也是最簡單的方法,引入單引號判斷是否注入點
http://host/test.php?id=100;返回錯誤說明有可能注入
http://host/test.php?id=100 and 1=1 返回正常
http://host/test.php?id=100 and 1=2 返回錯誤
判斷注入類型
數字型注入點
http://host/test.php?id=100 and 1=1
SELECT first_name, last_name FROM users WHERE user_id = '1' or '1'='1'
字符型注入點
http://host/test.php?name=man' and '1'='1
select * from student where sname='張三' or 1=1 -- and password='123'
"select id from users where username = ''+username +"'" and password = '' + password +"'"
在表單中username的輸入框中輸入’ or 1=1-- ,password的表單中隨便輸入一些東西,假如這里輸入123.此時我們所要執行的sql語句就變成了select id from users where username = ’ ’ or 1=1-- and password = ‘123’,我們來看一下這個sql,因為1=1是true,后面 and password = '123’被注釋掉了。
搜索型注入點 — 目前常見的
http://host//test.php?keyword=python%' and 1=1 and '%'='
內聯式SQL注入 –常用
在 SQL語句中, AND的優先級是大于 OR的
先計算 AND,然后計算 OR,所以這里我們的語句會被 OR分為兩段 SQL語句
SELECT * FROM admin WHER username=''or''='' AND password ='fuzz'SELECT * FROM admin WHER username='fuzz' AND password =''or''=''SELECT * FROM admin WHER username='fuzz' AND password =''or''=''這里我們第一句是返回失敗的,但是我們的第二句''=''是返回成功的,OR邏輯是有一個是成功就返回成功,于是我們的整個語句就會返回成功
SQL注入的通常方法
SQL注入主要分兩種方式:
一是直接將代碼插入到與SQL命令串聯在一起并使得其以執行的用戶輸入變量。上面筆者舉的例子就是采用了這種方法。由于其直接與SQL語句捆綁,故也被稱為直接注入式攻擊法。
二是一種間接的攻擊方法,它將惡意代碼注入要在表中存儲或者作為原書據存儲的字符串。在存儲的字符串中會連接到一個動態的SQL命令中,以執行一些惡意的SQL代碼。注入過程的工作方式是提前終止文本字符串,然后追加一個新的命令。如以直接注入式攻擊為例。就是在用戶輸入變量的時候,先用一個分號結束當前的語句。然后再插入一個惡意SQL語句即可。由于插入的命令可能在執行前追加其他字符串,因此攻擊者常常用注釋標記“—”來終止注入的字符串。執行時,系統會認為此后語句位注釋,故后續的文本將被忽略,不背編譯與執行。
注入大致方法:
先猜表名 And (Select count(*) from 表名)<>0
猜列名 And (Select count(列名) from 表名)<>0
或者也可以這樣
and exists (select * from 表名)
and exists (select 列名 from 表名)
返回正確的,那么寫的表名或列名就是正確
這里要注意的是,exists這個不能應用于猜內容上,例如and exists (select len(user) from admin)>3
這樣是不行的
防止SQL注入
防止SQL注入,我們需要注意以下幾個要點:
1.永遠不要信任用戶的輸入。對用戶的輸入進行校驗,可以通過正則表達式,或限制長度;對單引號和 雙"-"進行轉換等。
2.永遠不要使用動態拼裝sql,可以使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
3.永遠不要使用管理員權限的數據庫連接,為每個應用使用單獨的權限有限的數據庫連接。
4.不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。
5.應用的異常信息應該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝
6.sql注入的檢測方法一般采取輔助軟件或網站平臺來檢測,軟件一般采用sql注入檢測工具jsky,網站平臺就有億思網站安全平臺檢測工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻擊等。
數據庫操作,是觸發技術使用的關鍵。
圍繞這一點,可以想到許多系統層面的防護。
第一點就是,避免使用普適性的名詞去做主要關鍵詞,可以做適當的修改變形。sql注入其實也是技術門檻比較高的,它需要破解者對于項目網站本身就有一定的了解。
第二點可以考慮加強過濾手段,通過對于主要關鍵詞周邊風險詞的限制降低風險。根據理論模型來看,這種語句過濾可以極大程度防范技術侵入。
更多相關一
更多相關二