SQL injection***原理

SQL injection***原理

這篇是sql注入基礎內容,目的是能瞭解注入的基本原理,並不涉及到具體的***,這也是個人學習筆記,如有不足和錯誤之處忘看客指正heyihome.blog.51cto.com

一、什麼是SQL injection

通常大家都知道除了一些靜態頁面站點外,如今網絡上大量網站需要使用數據庫,並且用戶的種種操作都會與其產生交互。比較典型的就是用戶名、密碼輸入登陸,還有電子商務網站購物也需要同數據庫交互查詢商品信息等,而SQL注入***就是在正常的交互中插入惡意數據格式和請求來達到***目的。

二、哪裏使用注入***

WEB應用向後端數據庫提交輸入時,就是容易遭受***的時候,通常多數SQL注入***是在URL裏面輸入,也可以在表格域和其他一些動態生成的SQL查詢語句的輸入參數。

三、***實施原理

讓我們先從基本的sql查詢語句開始

Seclect somedatacolumn,someotherdatacolumn FROM somedatadasetable where someconditionismet

上面這段就是一條標準的SQL查詢語句,查詢 某字段 從  哪個表 匹配條件是什麼。

例如SQL在電子商務網站上應用,當需要查詢某產品信息時,應用程序通過CGI參數建立鏈接,在其查詢中引用,鏈接通常看起來如下:

http://www.xxxxx.cn/shop_view.asp?id=35

其應用程序需要知道用戶希望看到那類商品,所以瀏覽器會發送一個標識符,這裏爲“id”,然後應用程序動態將其包含在SQL查詢請求中,以便能在數據庫中匹配到對應的數據,其在後臺的解釋可能如下:

這樣看起來應該是沒任何問題的,那麼風險在哪裏呢?假設如果我們是在某論壇登錄,那麼在後臺的SQL查詢中,語句應該是這樣的:

Seclet name.picture,description,price FROM Products Where ID=35

其中被引號框入的數據就是用戶在論壇登陸時輸入的用戶名和密碼,假設有個惡意用戶想盜取我們的用戶名和密碼登錄,那麼他需要知道正確的namepassword纔可登錄。但如果這個站點存在sql注入漏洞會如何呢?

例如論壇有zhangsan這個用戶,我們在用戶帳號的表格域中輸入 zhangsan' -- (-- 爲註釋符,雙虛線),那麼在後臺sql查詢中將出現如下語句

Seclet accountdate FROM accountinfo Where accountid = 'anaccountnumber' AND password = 'apassword'

因爲“--”爲註釋符,那麼語句後面的內容都被忽視,實際不做檢查,其實際查詢的語句就成了

這樣結果是什麼,我們沒輸入密碼,但通過認證進行了登錄。

Tipe:輸入時在用戶後使用了單引號,這個引號是做爲sql查詢請求的以部分,這就意味可以改變提交到數據庫的查詢語句結構。但注意,由於我們使用了單引號,在SQL中引號中必須包含字符串。如果是用整數型數據查詢,那麼就不用必須輸入單引號了

從上面的結果中可以看到,通過註釋符跨過了對密碼的認證,但前提是知道用戶名纔可以,如果我們做下變動,想獲取全部用戶信息呢?我們需要提交這樣一條語句

Seclet accountdate FROM accountinfo Where accountid = 'zhangsan' --' AND password = 'password'

這句話意思是隻要爲真,就查詢所有用戶信息,其實現如下,account部分可以用單引號來屏蔽web程序生成匹配好的單引號,True條件可以1=12>1這類含義數學運算。(有些數據庫支持直接輸入 true),爲此輸入

' OR 1=1 --

在後臺sql查詢語句就變成如下了,導致返回了數據庫所以用戶ID信息

Seclet accountdate FROM accountinfo Where accountid = 'zhangsan'

這個例子在web源代碼通常是這類形式:

Seclet accountdate FROM accountinfo Where accountid = '' OR true

Seclet accountdate FROM accountinfo Where accountid = '' OR 1=1

$SQLquery = "seclect * from users where username = ' ".$_POST["username"]." ' and password = ' ".$_POST["password"]." ' ";

$DBresult = db_query($SQLquery);

If($DBresult){

// username + password is correct --- log the user in

}

Else{

// username or password was incorrect

}

從以上代碼可以看出來,由於我們輸入的字符串導致返回多行數據,DBresult變量將爲一個正數,由此通過了認證。這個例子危險在於對數據沒有進行驗證,因爲在sql注入中總是會有一些返回值回來。這個例子中web應用接收數據時會得到數據庫中所有數據的第一行。

這裏有個假設前提爲開發者使用第一條記錄來確定對用戶的判斷,這是常用編程技巧,因爲正常操作中只返回第一行。但剛纔所使用字符串導致返回多行數據,由於在用戶列表信息中通常第一行都是admin帳號,所以這裏會導致我們可以用admin帳號直接登錄系統,而不需要知道用戶名和密碼。

如果對上述***進行擴展,使數據庫能執行更多的操作,那麼就需要用到分號執行附加命令,例:

這樣就在數據庫中增加了lisi這個帳號。不過注意的是,這樣做不代表能登錄系統,因爲除了用戶名密碼外,一個完整的帳號信息還包含權限等等內容,這些需要知道數據庫表內的列和字符格式,這個一般很難能知曉。但如果利用數據庫返回的錯誤信息,可以瞭解更多數據庫的組成。

除了INSERT插入數據,還可以用DROP TABLE直接破壞數據庫。

四、防範方法

避免注入需要開發對各類特色字符進行過濾,在url、表格域、等在用戶可控制輸入的地方,只要於SQL語法相關的特殊字符和保留字應該在提交到數據庫之前進行過濾掉。其過濾操作應在服務器端進行,如果是在客戶端執行的HTML中,會給用戶機會去修改驗證程序來繞過驗證。

在建立數據庫時也應該根據用戶對數據的操作需求,來賦予不同的權限,這樣即便發生了SQL注入***,也會讓其限制在那些被正常訪問到的數據中。例如管理員可能需要對帳號具有讀取寫入權限,但普通用戶就不應該有這樣的權限。

By 何藝 ver1.0

2011-1-15

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