轉自CSDN,作者hellochenlu/網(wǎng)易號,云計算那些事
互聯(lián)網(wǎng)的攻擊形式千萬種,威脅最大的獨一份,就是SQL注入了!由于它的危害之大,它也成為了每一個運維工程師為客戶部署業(yè)務系統(tǒng)前必做的防御。
問題來了,對接我們的客戶大多數(shù)技術鉆研不是很”深刻“,我們經(jīng)常因為跟客戶的技術溝通而抓狂!接下來我們可以了解一下關于SQL注入攻擊的內容!
SQL是結構化查詢語言(Structured Query Language)的簡稱,是一種數(shù)據(jù)庫查詢和程序設計語言,用于存取數(shù)據(jù)以及查詢、更新和管理關系數(shù)據(jù)庫系統(tǒng)。說的直白一些,就是工程師與數(shù)據(jù)庫進行溝通和交流的一種語言。
SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執(zhí)行惡意的SQL命令。
當應用程序使用輸入內容來構造動態(tài)SQL語句以訪問數(shù)據(jù)庫時,會發(fā)生注入攻擊。如果代碼使用存儲過程,而這些存儲過程作為包含未篩選的用戶輸入的字符串來傳遞,也會發(fā)生SQL注入。
黑客通過SQL注入攻擊可以拿到網(wǎng)站數(shù)據(jù)庫的訪問權限,之后他們就可以拿到網(wǎng)站數(shù)據(jù)庫中所有的數(shù)據(jù),惡意的黑客可以通過SQL注入功能篡改數(shù)據(jù)庫中的數(shù)據(jù)甚至會把數(shù)據(jù)庫中的數(shù)據(jù)毀壞掉。
最常見的比如:我們上網(wǎng)經(jīng)常會看到一些免費或者超低價格的各大視頻網(wǎng)站的會員賬戶和密碼,這些賬戶和密碼怎么來的呢?
大部分都是通過WEB表單遞交查詢字符暴出來的。大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL注入式攻擊。
目標服務器上運行SQL語句以及進行其他方式的攻擊,動態(tài)生成SQL語句時沒有對用戶輸入的數(shù)據(jù)進行驗證是SQL注入攻擊得逞的主要原因。
對于Java數(shù)據(jù)庫連接JDBC而言,SQL注入攻擊只對Statement有效,對PreparedStatement是無效的,這是因為PreparedStatement不允許在不同的插入時間改變查詢的邏輯結構。
下面我們來說一下SQL注入原理,以使讀者對SQL注入攻擊有一個感性的認識,至于其他攻擊,原理是一致的。
SQL注射能使攻擊者繞過認證機制,完全控制遠程服務器上的數(shù)據(jù)庫。SQL是結構化查詢語言的簡稱,它是訪問數(shù)據(jù)庫的事實標準。
SQL注入式攻擊的主要形式有兩種。一是直接將代碼插入到與SQL命令串聯(lián)在一起并使得其以執(zhí)行的用戶輸入變量。由于其直接與SQL語句捆綁,故也被稱為直接注入式攻擊法。
二是一種間接的攻擊方法,它將惡意代碼注入要在表中存儲或者作為原書據(jù)存儲的字符串。在存儲的字符串中會連接到一個動態(tài)的SQL命令中,以執(zhí)行一些惡意的SQL代碼。注入過程的工作方式是提前終止文本字符串,然后追加一個新的命令。
如以直接注入式攻擊為例。就是在用戶輸入變量的時候,先用一個分號結束當前的語句。然后再插入一個惡意SQL語句即可。
由于插入的命令可能在執(zhí)行前追加其他字符串,因此攻擊者常常用注釋標記“—”來終止注入的字符串。執(zhí)行時,系統(tǒng)會認為此后語句位注釋,故后續(xù)的文本將被忽略,不背編譯與執(zhí)行。
如驗證用戶是否存在的SQL語句為:
用戶名'and pswd='密碼'如果在用戶名字段中輸入: 'or 1=1或是在密碼字段中輸入:'or 1=1
將繞過驗證,
但這種手段只對只對Statement有效,對PreparedStatement無效。相對Statement有以下優(yōu)點:
1.防注入攻擊
2.多次運行速度快
3.防止數(shù)據(jù)庫緩沖區(qū)溢出
4.代碼的可讀性可維護性好
這四點使得PreparedStatement成為訪問數(shù)據(jù)庫的語句對象的首選,缺點是靈活性不夠好,有些場合還是必須使用Statement。
我們再來舉個形象的例子~
一天,你代表你的老板去銀行辦理業(yè)務。你的老板給了你一個信封,上面寫著收銀員的指示。
現(xiàn)在,信件內容是:
在這張紙上寫下A號賬戶的余額。同時將500元從A號賬戶轉到另一個B賬戶。
簽名:Boss
出納員檢查你的身份,確認你是相關賬戶的授權人員,便按照信函中的說明進行操作。
結果Boss被“偷了”500元!
在這個過程中:
你的老板是合法的程序代碼;
你是將SQL代碼傳遞到數(shù)據(jù)庫的程序代碼和數(shù)據(jù)庫驅動程序;
信函內容是傳遞給數(shù)據(jù)庫的SQL代碼;
小偷是襲擊者,俗稱“黑客”;
出納員是數(shù)據(jù)庫;
身份標識通常是數(shù)據(jù)庫的登錄名和密碼。
SQL 注入漏洞已成為互聯(lián)網(wǎng)最常見也是影響非常廣泛的漏洞,那么:
1. 采用預編譯語句集
出納員在處理信函內容的時候,只處理賬戶和金額,對轉賬動作不處理。
2. 檢查數(shù)據(jù)類型和格式
出納員在處理信函內容的時候,會去查驗小偷添加內容的類型和格式,是否符合規(guī)定。
a:驗證所有輸入
始終通過測試類型、長度、格式和范圍來驗證用戶輸入。實現(xiàn)對惡意輸入的預防時,請注意應用程序的體系結構和部署方案。請注意,設計為在安全環(huán)境中運行的程序可能會被復制到不安全的環(huán)境中。
對應用程序接收的數(shù)據(jù)不做任何有關大小、類型或內容的假設:
如果一個用戶在需要郵政編碼的位置無意中或惡意地輸入了一個 10 MB 的 MPEG 文件,應用程序會做出什么反應?如果在文本字段中嵌入了一個 DROP TABLE 語句,應用程序會做出什么反應?
b:使用存儲過程來驗證用戶輸入。
在多層環(huán)境中,所有數(shù)據(jù)都應該在驗證之后才允許進入可信區(qū)域。未通過驗證過程的數(shù)據(jù)應被拒絕,并向前一層返回一個錯誤。
c:實現(xiàn)多層驗證。
對無目的的惡意用戶采取的預防措施對堅定的攻擊者可能無效。更好的做法是在用戶界面和所有跨信任邊界的后續(xù)點上驗證輸入。
例如,在客戶端應用程序中驗證數(shù)據(jù)可以防止簡單的腳本注入。但是,如果下一層認為其輸入已通過驗證,則任何可以繞過客戶端的惡意用戶就可以不受限制地訪問系統(tǒng)。
3. 過濾特殊字符
出納員在處理信函內容“將500元從123456號賬戶轉到另一個654321賬戶”的時候,轉譯出現(xiàn)問題,即報錯。
只要注入的 SQL 代碼語法正確,便無法采用編程方式來檢測篡改。因此,必須驗證所有用戶輸入,并仔細檢查在您所用的服務器中執(zhí)行構造 SQL 命令的代碼。本主題中的以下各部分說明了編寫代碼的最佳做法。
絕不串聯(lián)未驗證的用戶輸入。字符串串聯(lián)是腳本注入的主要輸入點。
在可能據(jù)以構造文件名的字段中,不接受下列字符串:AUX、CLOCK$、COM1 到 COM8、CON、CONFIG$、LPT1 到 LPT8、NUL 以及 PRN。
還有,如果可能,拒絕包含以下字符的輸入。
輸入字符 在 Transact-SQL 中的含義
; 查詢分隔符。
' 字符數(shù)據(jù)字符串分隔符。
-- 注釋分隔符。
/* ... */ 注釋分隔符。服務器不對 /* 和 */ 之間的注釋進行處理。
xp_ 用于目錄擴展存儲過程的名稱的開頭,如 xp_cmdshell。
測試輸入的大小和數(shù)據(jù)類型,強制執(zhí)行適當?shù)南拗?/strong>。這有助于防止有意造成的緩沖區(qū)溢出。
測試字符串變量的內容,只接受所需的值。
拒絕包含二進制數(shù)據(jù)、轉義序列和注釋字符的輸入內容。這有助于防止腳本注入,防止某些緩沖區(qū)溢出攻擊。
使用 XML 文檔時,根據(jù)數(shù)據(jù)的架構對輸入的所有數(shù)據(jù)進行驗證。絕不直接使用用戶輸入內容來生成 Transact-SQL 語句。
涇溪石險人兢慎,終歲不聞傾覆人。卻是平流無石處,時時聞說有沈淪?!跑鼹Q《涇溪》