實(shí)驗(yàn)內(nèi)容與步驟
在MySQL數(shù)據(jù)庫(kù)的注入中,如果你有仔細(xì)看過(guò)SQL注入語(yǔ)句的話(huà),你可能就會(huì)發(fā)現(xiàn),在獲取數(shù)據(jù)庫(kù)名、表名和字段的時(shí)候,注入語(yǔ)句中information_schema這個(gè)數(shù)據(jù)庫(kù)出現(xiàn)得很頻繁,那么有沒(méi)有想過(guò)為什么會(huì)需要用到這個(gè)數(shù)據(jù)庫(kù)呢? 這個(gè)數(shù)據(jù)庫(kù)又是什么?它里面保存了什么?
?? ?? information_schema數(shù)據(jù)庫(kù)是MySQL自帶的,MySQL 5以下沒(méi)有這個(gè)數(shù)據(jù)庫(kù),它提供了訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)元數(shù)據(jù)的方式。什么是元數(shù)據(jù)呢?元數(shù)據(jù)是關(guān)于數(shù)據(jù)的數(shù)據(jù),如數(shù)據(jù)庫(kù)名或表名,列的數(shù)據(jù)類(lèi)型,或訪(fǎng)問(wèn)權(quán)限等。也就是說(shuō)information_schema中保存著關(guān)于MySQL服務(wù)器所維護(hù)的所有其他數(shù)據(jù)庫(kù)的信息。如數(shù)據(jù)庫(kù)名,數(shù)據(jù)庫(kù)的表,表欄的數(shù)據(jù)類(lèi)型與訪(fǎng)問(wèn)權(quán)限等。在INFORMATION_SCHEMA中,有數(shù)個(gè)只讀表。
????? 在phpmyadmin中,在左側(cè)點(diǎn)擊information_schema數(shù)據(jù)庫(kù)。
?
?
?展開(kāi)后如下圖,顯示了該數(shù)據(jù)庫(kù)中的所有表,由于表數(shù)量太多,只截了一部分,可以拉動(dòng)右邊的滾動(dòng)條查看所有表。
也可以執(zhí)行如下SQL語(yǔ)句來(lái)查看該庫(kù)中的所有表:
?? ???show tables;
? 需要注意的是,要在information_schema這個(gè)數(shù)據(jù)庫(kù)中執(zhí)行該SQL語(yǔ)句。如何進(jìn)入information_schema數(shù)據(jù)庫(kù)執(zhí)行SQL語(yǔ)句,請(qǐng)參考前面進(jìn)入sqli數(shù)據(jù)庫(kù)執(zhí)行SQL語(yǔ)句的步驟。
????? 這上面顯示的表,它們實(shí)際上是視圖,而不是基本表,所以你在數(shù)據(jù)庫(kù)的數(shù)據(jù)保存目錄,會(huì)看不到這個(gè)數(shù)據(jù)庫(kù)的實(shí)體文件。數(shù)據(jù)庫(kù)的數(shù)據(jù)保存在 C:wampinmysqlmysql5.6.17data 目錄,在這個(gè)目錄下一共有如下4個(gè)目錄:
?
?
?想要查看數(shù)據(jù)庫(kù)的數(shù)據(jù)保存目錄,可以執(zhí)行select @@datadir,如下圖:
?
?
?每一個(gè)目錄對(duì)應(yīng)數(shù)據(jù)庫(kù)中的一個(gè)數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)中執(zhí)行show databases;的時(shí)候,可以看到存在5個(gè)數(shù)據(jù)庫(kù),正是少了information_schema這個(gè)數(shù)據(jù)庫(kù)。
在SQL注入中,我們重點(diǎn)關(guān)注的表有如下幾個(gè),因?yàn)橹饕臅r(shí)候主要利用這幾個(gè)表來(lái)獲取數(shù)據(jù):
? ? ? SCHEMATA:提供了當(dāng)前mysql數(shù)據(jù)庫(kù)中所有數(shù)據(jù)庫(kù)的信息,其中SCHEMA_NAME字段保存了所有的數(shù)據(jù)庫(kù)名。show databases的結(jié)果取自此表。
????? TABLES:提供了關(guān)于數(shù)據(jù)庫(kù)中的表的信息,詳細(xì)表述了某個(gè)表屬于哪個(gè)schema,表類(lèi)型,表引擎,創(chuàng)建時(shí)間等信息,其中table_name字段保存了所有列名信息,show tables from schemaname的結(jié)果取自此表。
?? ?? COLUMNS:提供了表中的列信息。詳細(xì)表述了某張表的所有列以及每個(gè)列的信息,其中column_name保存了所有的字段信息。show columns from schemaname.tablename的結(jié)果取自此表。
? ? ? 為了更好地說(shuō)明這些表的作用,我們進(jìn)入mysql終端。
? ? ? 點(diǎn)擊右下角的wampserver圖標(biāo),如果沒(méi)有該圖標(biāo),可以雙擊桌面的WampServer運(yùn)行。
?
?
??然后在彈出來(lái)的列表中點(diǎn)擊MySQL,再選擇MySQL控制臺(tái)。
?
?
?會(huì)彈出一個(gè)命令行窗口,這就是mysql客戶(hù)端,此時(shí)要求輸入密碼,由于root的密碼為空,直接回車(chē)即可。
?
?
?進(jìn)入information_schema 數(shù)據(jù)庫(kù),命令為:use information_schema;?。一定要注意后面記得加分號(hào),分號(hào)表示一個(gè)語(yǔ)句結(jié)束,如果沒(méi)有檢測(cè)到你輸入分號(hào),它會(huì)認(rèn)為你一個(gè)語(yǔ)句還沒(méi)結(jié)束,直到碰到分號(hào)后,才開(kāi)始執(zhí)行語(yǔ)句。
?
?
?首先執(zhí)行show databases;查看所有的數(shù)據(jù)庫(kù),然后再執(zhí)行select schema_name from schemata;。
可以看到他們的作用是一樣的,都是列出所有數(shù)據(jù)庫(kù),跟我們前面說(shuō)的一樣,SCHEMA_NAME字段保存了所有的數(shù)據(jù)庫(kù)名。
? ? ? 所以,在注入中,我們可以通過(guò)注入select schema_name from schemata 來(lái)查詢(xún)的當(dāng)前數(shù)據(jù)庫(kù)中所有的數(shù)據(jù)庫(kù)名,如果你去查看一些爆數(shù)據(jù)庫(kù)名的注入語(yǔ)句,就會(huì)發(fā)現(xiàn)里面包含這么一句:select schema_name from information_schema.schemata limit 0,1,其原理就是通過(guò)查詢(xún)information_schema.schemata中schema_name的結(jié)果,其中l(wèi)imit 0,1用來(lái)獲取第一條記錄,通過(guò)遞增第一個(gè)參數(shù),可以每次獲取一條記錄,也就是一次獲取一個(gè)數(shù)據(jù)庫(kù)名,直到出現(xiàn)錯(cuò)誤為止,說(shuō)明沒(méi)有更多的錯(cuò)誤。
? ? ? 通常在獲取了數(shù)據(jù)庫(kù)名后,就會(huì)選擇感興趣的數(shù)據(jù)庫(kù),然后來(lái)獲取其中的數(shù)據(jù),首先需要獲取感興趣的數(shù)據(jù)庫(kù)中的所有表名,通過(guò)查詢(xún)information_schema庫(kù)中的TABLES表就可以獲取表名。
?? ?? 在TABLES表中,它保存了所有數(shù)據(jù)庫(kù)中的所有表名以及這個(gè)表所屬的庫(kù),意思是說(shuō),不管你在哪個(gè)數(shù)據(jù)庫(kù)中的表,在這里都會(huì)有一條記錄對(duì)應(yīng),如果你在一個(gè)數(shù)據(jù)庫(kù)中創(chuàng)建了一個(gè)表,相應(yīng)地在這個(gè)表里,也會(huì)有一條記錄對(duì)應(yīng)你創(chuàng)建的那個(gè)表。
? ? ? desc 可以用來(lái)看表結(jié)構(gòu)??聪聇ables的表結(jié)構(gòu),執(zhí)行desc tables;,結(jié)果如下圖:
?
?
??注意上圖中標(biāo)記的那2條記錄,每一條記錄中,他們分別記錄一個(gè)表名和一個(gè)這個(gè)表所屬的庫(kù)名。其中TABLE_NAME保存的是表名,而TABLE_SCHEMA保存的是這個(gè)表名所在的數(shù)據(jù)庫(kù)。我們可以查詢(xún)一條記錄看看,在查詢(xún)前,先看看有多少條記錄,避免記錄太多查看不方便,執(zhí)行select count(*) from tables;?結(jié)果如下圖:
?
?
??說(shuō)明當(dāng)前所有數(shù)據(jù)庫(kù)中的表數(shù)量為142。查詢(xún)?nèi)我庖粭l記錄查看,我這里選擇最后一條記錄,SQL語(yǔ)句為:select * from tables limit 141,1G由于在客戶(hù)端中,默認(rèn)查詢(xún)結(jié)果顯示不友好,所以,可以把語(yǔ)句后面的分號(hào)改成G,他會(huì)讓一條記錄顯示一行,看起來(lái)不那么亂。G只支持在客戶(hù)端中用,在其他連接數(shù)據(jù)庫(kù)的軟件中,使用G會(huì)報(bào)錯(cuò)。
?
?
?? 可以看到,最后一條記錄的TABLE_NAME是user,TABLE_SCHEMA為sqli。查看sqli數(shù)據(jù)庫(kù)中的表,SQL語(yǔ)句為:show tables from sqli;可以看到確實(shí)存在user表。
?既然information_schema的TABLES表中的TABLE_SCHEMTA字段是保存的數(shù)據(jù)庫(kù)名,而TABLE_NAME保存了表名,那么我們就可以使用TABLE_SCHEMTA字段作為查詢(xún)條件,查詢(xún)TABLE_NAME,即可得知所有指定數(shù)據(jù)庫(kù)中的所有表名。比如,我們想要通過(guò)information_schema數(shù)據(jù)庫(kù)來(lái)查詢(xún)sqli數(shù)據(jù)庫(kù)中所有的表,那么就可以使用如下SQL語(yǔ)句:
? ? ??select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = 'sqli';
?? ?? 如果當(dāng)前庫(kù)為information_schema,則可以省略不寫(xiě),否則跨庫(kù)查詢(xún)的時(shí)候,需要帶上庫(kù)名。結(jié)果如下圖:
通過(guò)修改TABLE_SCHEMA 的限制,可以查詢(xún)?nèi)我鈹?shù)據(jù)庫(kù)中的所有表名,網(wǎng)上的通過(guò)注入爆表名便是這個(gè)原理。
?? ?? 知道了表名,那么如何獲取表中的字段呢?要知道我們沒(méi)有表名的話(huà),會(huì)把所有的數(shù)據(jù)查詢(xún)出來(lái),而如果注入沒(méi)有回顯,不能進(jìn)行union查詢(xún),那么想要獲取我們的標(biāo)目數(shù)據(jù),無(wú)疑效率極低。
????? 幸運(yùn)的是,在information_schema數(shù)據(jù)庫(kù)中,同樣存在一個(gè)表,它保存了整個(gè)數(shù)據(jù)中,所有的列名,這個(gè)表就是COLUMNS。同樣先查看該表結(jié)構(gòu)。
?
?
?這里面,與注入相關(guān)的存在3個(gè)字段,分別是TABLE_SCHEMA、TABLE_NAME以及COLUMN_NAME,不難猜到,如果在該表中查詢(xún)一條記錄,TABLE_SCHEMA保存了這條記錄保存的字段所屬的數(shù)據(jù)庫(kù)名,而TABLE_NAME保存的是該字段所屬表名,COLUMN_NAME則是一個(gè)列名記錄,查詢(xún)一條記錄驗(yàn)證一下,首先確定該表有多少條記錄,執(zhí)行select count(*) from columns;,得知一共有1662條記錄,結(jié)果如下圖:
? 我們獲取最后一條記錄,執(zhí)行select * from columns limit 1661,1G
? ? ??
? 其中COLUMNS_NAME為ip,TABLE_NAME為user,TABLE_SCHEMA為sqli,這說(shuō)明,在sqli這個(gè)數(shù)據(jù)中,user表存在一個(gè)ip的列,也就是我們常說(shuō)的ip字段。
? ? ? 查看sqli的user表是否存在該字段,執(zhí)行SQL語(yǔ)句:show columns from sqli.user;
可以看到確實(shí)存在該字段。
? ? ? 既然在columns中,TABLE_NAME保存了字段所屬的表名,TABLE_SCHEMA保存了該字段所屬的庫(kù)名,與通過(guò)TABLES表獲取表名一樣,我們就可以查詢(xún)把TABLE_NAME 和TABLE_SCHEMA做為查詢(xún)條件,查詢(xún)符合條件的COLUMN_NAME,也就是查詢(xún)指定數(shù)據(jù)庫(kù)中某表中的字段。
?? ?? 比如,我們要通過(guò)information_schema數(shù)據(jù)庫(kù)的columns表查詢(xún)sqli數(shù)據(jù)庫(kù)中user表中所有的字段,可以執(zhí)行如下SQL語(yǔ)句:
? ? ??select column_name from information_schema.columns where TABLE_SCHEMA='sqli' and TABLE_NAME='user';
?查詢(xún)結(jié)果與show columns from sqli.user;?一致。
? ? ? 知道了庫(kù)名、表名、字段,如果有回顯且支持聯(lián)合查詢(xún),就可以直接通過(guò)在注入點(diǎn)后面注入一個(gè)聯(lián)合查詢(xún)語(yǔ)句,即可直接獲取數(shù)據(jù),如果不能回顯,則可能需要通過(guò)盲注獲取數(shù)據(jù),可以參考MySQL盲注實(shí)驗(yàn)。
?
本文摘自 :https://www.cnblogs.com/