[深入學習Web安全](5)詳解MySQL注射

來源:http://bbs.ichunqiu.com/thread-10222-1-1.html?from=ch

作者:萬年死宅

首發(fā):i春秋社區(qū)

注明:轉(zhuǎn)載請務(wù)必注明i春秋社區(qū)(bbs.ichunqiu.com)

0x00 目錄

0x00 目錄

0x01 MySQL注射的簡單介紹

0x02 對于information_schema庫的研究

0x03 注射第一步——確定查詢語句的查詢對象個數(shù)0x04 注射第二步——UNION聯(lián)合查詢

0x05 注射第三步——MySQL基礎(chǔ)信息收集

0x06 注射第四步——通過利用點GET敏感表及列

0x07 注射第五步——通過已知表、列GET數(shù)據(jù)

0x01 MySQL注射的簡單介紹

MySQL的注射,我們已經(jīng)在第4篇文章的演示過了,我們就來簡單的總結(jié)下,我們MySQL注射的利用點。

首先,我們先來說下現(xiàn)在幾乎沒什么網(wǎng)站用的Access數(shù)據(jù)庫吧,在最早期的Web安全技術(shù)的學習中,我們最早接觸到的工具相信都是啊D和明小子,而這兩款工具正是針對與Access數(shù)據(jù)庫的注射漏洞的利用工具。

而提到Access的注射,相信大家都能想到兩個字“爆破”或者是“猜解”。對,這就是Access數(shù)據(jù)庫存在SQL注射漏洞時的利用點,而我們第4篇文章中所演示的MySQL注射的利用點,自然不是“猜解”。(順便說一下,我說的只是針對于MySQL5及以上版本)這種注射的利用點是information_schema這個默認數(shù)據(jù)庫,這里面記錄了該MySQL數(shù)據(jù)庫所存儲的所有數(shù)據(jù)。

所以,針對于MySQL數(shù)據(jù)庫的注射都是利用提取information_schema庫里的信息來獲取表名與列名的。

0x02對于information_schema庫的研究

既然這類注射的利用點在于information_schema這個默認庫,那么自然,我們就應(yīng)該增進對于這個庫的一些了解,接下來,我們就來研究下這個information_schema庫。

首先,我們啟動MySQL服務(wù),并且登錄MySQL:

然后,我們還是來看下存在的數(shù)據(jù)庫:

我們看到了information_schema數(shù)據(jù)庫,也就證明了我安裝的MySQL版本大于5,我們可以來看下具體版本:

我們可以看到版本是5.6.17。接著,我們進入information_schema庫:

接著,我們來show一下表:

可以看到,這個庫里面有很多表,而我們獲取其他數(shù)據(jù)庫里的表、列名情況所利用的是一個叫tables的表,如下圖:

我們看看這個tables表里存在那些column:

可以看到,tables表里情況復(fù)雜。。。我們所需要學習的只是其中幾個,包括table_name、colum_name、table_schema,如圖:

還有一個沒圈到,可能是在下面,也可能是我眼睛不好。。。。我先來了解下table_schema這個列:

這里面包含了所有我們安裝在這個MySQL上的數(shù)據(jù)庫的db_name,會有很多重復(fù),接著,我們來看下table_name里的情況:

這個表里則包含了該MySQL安裝過的表的名字,好了,關(guān)于這個infromation_schema的庫,我就寫到這里,because我們的主題不是這個。

0x03 注射第一步——確定查詢語句的查詢對象個數(shù)

我們在第4篇的通用注射方式里的第一步就是確定原查詢語句的查詢對象的個數(shù),什么意思呢?

其實很簡單,我們還是使用第4篇的栗子,我把MySQL切換到sqli數(shù)據(jù)庫:

然后,用上節(jié)課的SQL模型,如下:

這個X的位置,便是我們能夠注射的位置,這個查詢對象是什么意思呢?

其實,在這里查詢對象就是data,個數(shù)就是1。這樣或許大家還是不能理解,那我們舉如下栗子:

這次查詢對象就變?yōu)榱?,但是長度卻改變了,因為*代表的是ALL的意思,那我們就來看看在news表中到底有幾個對象:

我們能看到,news表中有兩個列,所以,這次的查詢對象個數(shù)就是2。

但是,我們進行SQL注射只能控制SQL語句的一個部分,而不能知道原本的查詢語句啊,那怎么辦?

這時,我們就只能勞靠order by了,我們來看如下的栗子(還是一樣的SQL模型):

我們在上面的栗子中可以看到,第一次查詢是正常的查詢,返回正常的查詢結(jié)果,而第二次查詢則是加了order by 1,達到的效果就是返回正常查詢結(jié)果,因為原SQL模型的查詢對象個數(shù)就是1,而第三次查詢則使用了order by 2,而原查詢語句的查詢對象個數(shù)是1,而不是2,所以產(chǎn)生了錯誤。

這就是利用order by來獲取未知查詢語句的查詢對象個數(shù)。

0x04 注射第二步——UNION聯(lián)合查詢

好滴,接下來,我們就要使用聯(lián)合查詢了,這個union到底是拿來干啥的啊,很不解對吧,那我們就先來學習一下union。

我們先來執(zhí)行如下SQL語句,并查看結(jié)果:

可以看到select什么就是什么,接著,我們來看一下下面這個圖(別閑枯燥,都是為了后面做鋪墊):

這就是news表里的全部數(shù)據(jù),我們想一下,我們有如下程序:

這個程序,我們假設(shè)它叫test.php吧,關(guān)于getData()函數(shù),圖上有注釋,我們想,當id為1~9的時候,這個程序確實沒任何問題,但是試想,當id等于10的時候,就沒法查詢出結(jié)果,說不定還會報錯,這樣很影響用戶體驗。

所以,有時,可以使用union來解決這種問題,例如如下SQL模型就能解決這種問題:

X的位置就是剛才那個程序的id參數(shù)的拼接處,這樣就解決了剛才說的問題,不信我們來看:

可以看到,在第一次查詢時id為1,的確存在這個數(shù)據(jù),于是正常返回查詢結(jié)果,其實也不完全正常,因為還多了個Error,但是這個很好處理,直接在mysql_fetch_array()之后的返回值里取數(shù)組的[0]就可以了。

而第二次查詢,id為10,不存在這條數(shù)據(jù),于是,語句錯誤了,所以查詢結(jié)果就變成了Error。

Ok,就是這樣,這就是UNION的基礎(chǔ)用法,但是還沒轉(zhuǎn)過彎來的同學可能還會問那剛才為什么要order by?

其實,這也怪我,沒講清楚,我們來看如下栗子:

很明了吧,嘿嘿,好了。我們最后在說一個問題,當我們有原語句出現(xiàn)錯誤時,我們的union的內(nèi)容就會替換掉查詢結(jié)果,其實類似于如下等式:

select * from news where id=10 union select 'Error',1000;

=

select 'Error',1000;

好了,接著就是下一個內(nèi)容了。

0x05 注射第三步——MySQL基礎(chǔ)信息收集

Ok,基礎(chǔ)的東西終于嘮完了,我們就來玩玩吧,我們先看下面這樣一個列表:

database()??當前數(shù)據(jù)庫

version() 數(shù)據(jù)庫版本

user() 當前用戶

就這樣三個基礎(chǔ)信息吧,我們先直接查詢下:

我們可以看到如下幾個基礎(chǔ)信息,根據(jù)我們0x04里最后提的等式,可以構(gòu)造出如下SQL語句來GET這些信息:

OK,長話短說了我們試試吧,首先是GET當前庫:

接著是數(shù)據(jù)庫版本:

最后是當前用戶:

OK,就這么簡單,其實注射并不難,只是缺少系統(tǒng)性的資料以及各種資料的“質(zhì)量”參差不齊才導(dǎo)致有很多朋友覺得SQL注射很難學。

0x06 注射第四步——通過利用點GET敏感表及列

好滴,接著,我們來到了0x06,真心寫得好累,阿西吧,神吶。。。好了,利用點自然是information_schema庫。

我們首先想獲取的自然是當前庫里的所有表,大家還記得吧,在0x02的地方,我曾說過information_schema庫里的tables表里存著我們想要的信息,首先table_schema里存的是啥?是所有數(shù)據(jù)庫名吧,那table_name里存的啥?是所有表名吧,既然如此,只需要將select database()查出來的當前庫名對應(yīng)一下,自然就能得到所有屬于當前庫的表名了哎。

所以,我們來先正常嘗試一下(額,對了跨庫的話就“from 庫名.表名”就行了):

可以看到,確實獲取了屬于sqli庫的所有表名,此時一看,哪個敏感一幕了然啊,嘿嘿,讓我們猥瑣的繼續(xù):

就這么簡單,通過前面那個等式,大家就能夠通過這兩個語句直接構(gòu)造攻擊的Payload了吧,嘿嘿(容我猥瑣的笑會兒~~)

0x07 注射第五步——通過已知表、列GET數(shù)據(jù)

好了,最后,我們就能通過已知的表、列GET想要的數(shù)據(jù)了,例如:

但是例如php程序在處理查詢結(jié)果時有點坑咋辦?就例如mysql_fetch_array()后只取了[0]咋辦?難道一個一個查?那不累死?

所以還是用第4篇里講到過的group_concat()函數(shù)來解決吧,如下例:

好了,這篇paper就到這里了,接下來還會有更多更高級的SQL注射技巧等著大家~~

作者:萬年死宅

首發(fā):i春秋社區(qū)

注明:轉(zhuǎn)載請務(wù)必注明i春秋社區(qū)(bbs.ichunqiu.com)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容