前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为了--force-pivoting参数,我问候了sqlmap开发者

为了--force-pivoting参数,我问候了sqlmap开发者

作者头像
意大利的猫
发布2020-08-20 11:40:22
1.7K0
发布2020-08-20 11:40:22
举报
文章被收录于专栏:漫流砂漫流砂

关键参数

--force-pivoting

背景

有一天一个哥们儿在群里丢了一个站,存在SQL注入,说有点问题

我看了一眼,目标具体情况如下

系统

数据库

服务器

脚本

w2k3

MsSQL2000

iis6.0

.net4.0

解决问题

老旧配置漏洞一般很多

这种比较老旧的配置一般都是可以轻松拿下的,所以也没在意,直接丢在sqlmap里面了,等了一会,我发现:在爆数据库,表,列的时候都很正常,但是到了最后获取最后的列中的数据的时候就发生了问题,获取到的值都是空的,如下

我的第一想法就是编码问题,于是我尝试加上 --hex参数,之后结果依旧是空值 后来和朋友一起讨论这个问题的时候,我们发现sqlmap给我们推荐了一个参数 --force-pivoting我们决定尝试一下,没想到真的dump出了数据

探究

对于我来说,似乎是发现了新大陆,我决定把它彻底研究明白,可能也是做为工具党的救赎吧

1. 查询SQLMAP的帮助信息

sqlmap -hh | grep pivoting

你没有看错,sqlmap 的帮助文档中竟然没有这个参数,后来在sqlmap的twitter和github上发现,这种参数属于 hidden参数,不在帮助文档显示

2. 查询百度,bing

先可着国内来吧

可以看到百度,bing国内外版本都没有任何技术信息 果断换谷歌吧

可以看到,谷歌搜索的结果中含有一些相关的结果,但是搜索结果都是指向sqlmap官方的GitHub和twitter地址,既然有结果我们就深入一下吧

最后我发现,只有以下三个链接是关于这个参数的 https://github.com/sqlmapproject/sqlmap/issues/3092 https://github.com/sqlmapproject/sqlmap/issues/3032 https://twitter.com/sqlmap/status/994557504364404736

我简单总结一下获取到的信息,这个参数是2018年5月10日进行更新的

主要针对out-of-order MsSQL table dumps 为什么我不进行翻译呢?因为这就是一个大坑,一会再说!

其他的信息都是这样的

使用者: 对MsSQL进行dump数据时候会发生问题 作者:可能是最近的一段代码导致的,吧啦吧啦吧啦... 更新啦! 使用者: 可以了!

可以了之后就没有一点探究精神吗?? 为什么能dump了不问一下吗? 没错,我开始了苦逼的自行探究

3. sqlmap发包分析

我打死都不想去读sqlmap的源码,毕竟容易头冷 sqlmap的源码其实写的很好,有精力的可以去分析一下

这里给大家介绍一个很方便的分析发包的方法,很多人都会

sqlmap -r 1.txt -D database1 -T table1 -C id,name,pass --dump -v 3

-v 3 应该是最适合用来分析的

可以看到详细的payload已经给出来,这样我们就直接看payload就行了 这里我要强调一下,要在同阶段进行抓取详细信息

什么意思呢? 看以下几个步骤,你就能懂了(此处抓包就是 -v 3的意思)

  • 获取到列名
  • 此时开始抓包,不使用 --force-pivoting 参数,查询 name,pass 列的数据
  • 保存抓包,并且删除之前 sqlmap 保留的缓存
  • 获取到列名
  • 此时开始抓包,使用 --force-pivoting 参数,查询 name,pass 列的数据
  • 保存抓包
  • 分析比较

保存下来的基本有几万条数据吧,不过大部分都是相似的,所以分析起来也不难

(上面是不带参数,下面是带参数) 可以看到,两个方法都是获取到了 一共有多少条数据

接下来是数据的细化

这里看见,不带参数使用的payload是

admin' AND UNICODE(SUBSTRING((SELECT ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32)) FROM (SELECT name, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS LIMIT FROM dyfc.dbo.UserInfo)x WHERE LIMIT=1),1,1))>64 AND 'ChJT'='ChJT

以我浊见对这段sql语句进行一个简单的解读 unicode(substring(xxx,1,1)) > 64 很容易理解,就是判断xxx的第一个字符转化后是否大于64,这个是基本方法了,大家都知道

我们把xxx 单独拿出来分析

SELECT ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32))FROM(SELECT name,ROW_NUMBER()OVER(ORDER BY(SELECT1))AS LIMIT FROM dyfc.dbo.UserInfo)x WHERE LIMIT=1

简单建模就是 select a from b where c = d;首先看 c, d

LIMIT=1

这个参数主要用来提高效率,表示找到数据后就不再向下检索

然后看 a

ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32))

这句就是判断 name 的值是不是空的,如果是空的,就用char(32)来代替

之后再看 b

(SELECT name,ROW_NUMBER()OVER(ORDER BY(SELECT1))AS LIMIT FROM dyfc.dbo.UserInfo)x

可以看到这个是一个临时表,这个表有name,和 row_number() 组成,row_number() over 的用法大家可以自行查询一下,主要的作用即使用来规定如何排序,如何分组,最后会返回1,2,3,4 这种序列号 那么新的临时表可能是下面这种形式

name

row_number

张三

1

李四

2

王五

3

赵六

4

需要注意的是,后面有一个 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS LIMIT 把ROW_NUMBER()的结果别名 LIMIT ,这样的话之前我们分析的 c,d 就有问题了

重新分析 c,d

WHERE LIMIT=1

也就是说ROW_NUMBER() = 1 ,用来控制选取临时表的第几个数据

那么总体的思路就很明确了,就是通过各种控制和筛选,最终查询排序后的第一个name的值,但从服务器中返回的是500错误,这是为什么的? 从图片可以看出,只查询了三条,都返回500 错误就停止了查询,开始下一个name的查询,所以这个500 应该就是罪魁祸首了


我们来看一下加了参数的

可以看到,最终查询出了name的值 对语句进行深入剖析

admin' AND UNICODE(SUBSTRING((SELECT MIN(ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32))) FROM dyfc.dbo.UserInfo WHERE CONVERT(NVARCHAR(4000),name)>CHAR(32)),1,1))>64 AND 'QJZr'='QJZr

分析方式是一样的

SELECT MIN(ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32)))FROM dyfc.dbo.UserInfoWHERE CONVERT(NVARCHAR(4000),name)>CHAR(32)

这回先分析a

MIN(ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32)))

跟之前的主要变化是在最外层加上了一个MIN()函数,这个函数主要是用来获取最小值的 遗憾的是你一般查资料,很多博主只比较过数字,在这里我们要比较的是字符 简单来说汉字和字母的顺序就是纯字母小,汉字大

字母之间比较首字母大小,一样比第二个 汉字之间比较首拼音,一样比第二个

所以a在之前的基础上还要选中最小的那个,具体从哪里开始选还得看 c,d 部分b 部分就没必要分析了

我们看 c,d 部分

CONVERT(NVARCHAR(4000),name)>CHAR(32)

将name转化为NVARCHAR()格式的数据,并且这个数据大于 CHAR(32),也就是大于 空格 对应的ascii值

总体表达就是查询非空格的最小name值


此时我们看一看没加参数和加了参数的两种如何进行接下来的获取

没加参数的是通过控制limit的值递增来遍历数据

加参数的是通过 where语句后面比较的字符来控制的,每次都用上一次查询出来的数据作为比较字符,由于每次查询的都是最小的,所以也能实现递增的效果

那么问题来了,为什么不加参数的就不能执行呢?是语句有问题吗??

4. 实验探究

实践是检验真理的唯一标准,这是没错的!

我自行搭建了一下windows2003,MsSQL2000环境,终于找到了最终的原因

原来是因为MsSQL2000中不支持ROW_NUMBER() 函数


吐槽

如果想探究这个参数的朋友现在应该已经得到答案了,可以看到这里就结束了 想点赞,转发,赞赏的朋友可以动手了!!!

接下来我要说的是关于这个参数整个探究过程中的其他部分,或许你们遇到新参数或者新知识时候也会有这样的心路历程

慌乱

我查询完国内外资料,发现什么都没有的时候是慌乱的

这种慌乱不是怕没有参考资料,而是怕自己写出来的东西会误导接下来的人

分析

我喜欢筛选共性,分析特性

所以针对此次事件,我之前在渗透mysql的时候从来都没有遇到过,所以应该是MsSQL的特性 分析这个参数名称 --force-pivoting ,一般安全工具force都是强迫使用什么什么技术,而且sqlmap之前也有 --force-ssl 这个参数,就是强迫使用ssl,所以推测终点肯定在 pivoting 上,而且是 MsSQL特有的

我查询了一下pivoting的意思是纽带(符合最后得出的结果),但是我在探究的过程中就成功掉入了 pivot的坑!!!

在坑中挣扎

老天爷,你老拿个pivot函数配合我干啥玩意!!!

MsSQL还真有一个函数叫 pivot,做行列转换用的,还TM是MSSQL特有的 得到这个消息的我是幸福的,我寻思这没跑了吧 pivot函数的使用方法可以参照下面链接

SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句https://www.cnblogs.com/wy123/p/5933734.html

我感觉是找到了救命稻草,就要完成这个知识点了,然而事实是残酷的 在使用了参数的那个记录中并没有 pivot 字符!!!

你以为我就这么放弃了吗??? 并没有,好不容易的稻草怎么可能就这么放开,我觉得可能是sqlmap官方使用了替换字符串的方式使pivot 字符串被拆分了,我倔强的认为着就是这样,虽然一方面也知道其实没有必要拆分 经过了一段挣扎后,认清了事实,一切从原点出发。

从官方简介入手

被 out-of-order 支配的恐惧

经过刚才的教训,我决定从官方入手,上面我提到过官方对于这个参数的简单说明 主要针对out-of-order MsSQL table dumps 毕竟六级早就过了,很久没学英语了, 这种翻译大活还是交给翻译软件吧 翻译这个事,我一直以来最相信谷歌

谷歌翻译

百度翻译

有道翻译

词霸

搜狗翻译

确定翻译过来是针对无序的MsSQL表转储

那么问题来了,无序的MsSQL表是什么意思呢?? 我特意问了身边一个数据库非常厉害了妹纸,给她问的也是一脸懵逼,很难受 网络上搜索也搜索不到这个名词,有的都是无序的字符,无序分页

没错,我又找来了我的朋友,我俩又经过一番猜测,推测出应该是指没有主键的表

进入了环境差异的坑

还原漏洞的时候一定要尽可能还原真实版本的环境

我手边正好有windows2008的虚拟机,于是我就在上面安装了一下MsSQL 2008,你想的没错,两种语法在有主键和没主键的情况下都可以完美查询

于是于是!!!! 我开始怀疑是.net 4.0 的问题 从此掉入了 .net 的坑 经过了一番的挣扎,我又从这个坑里面出来了

反思了一段时间,我觉得还是还原一下真实环境吧

用盗版的坑!

还原环境真的是累人,记住一定要用官方镜像和软件

4in1版本的MsSQL 2000不知道是谁打包的,兼容性是真的差 我在xp上死活搭不起来,我以为是xp 32位的原因

我就下定决心,一次性完成,就用windows2003 64位版本 系统是安装成了,我发现无论是 4in1版本的,还是单独的官方正版,都不能在64位环境运行,此时的我是爆炸的,强忍住愤怒重新下载安装32位,最后顺利搭建成功,执行语句后发现是因为 row_number 函数在MsSQL 2000中不存在的原因导致的

大部分人肯定就到此结束了,但我是一个追求完美又拧巴的人

回到了翻译的坑

我为什么不相信百度(流泪)

如果仅仅是row_number 这个函数在旧版本的MsSQL中不存在,那么为什么是针对MsSQL的无序表呢?? 为什么不直接说针对旧版本,或者说与无序表有什么关联?? 你想的没错,我又去找我朋友了,我俩又猜测了一番,觉得作者脑洞肯定比我俩大

没有办法,我给sqlmap的作者发了一封邮件,用尽了我的英语墨水 没想到过了一天作者真的回复我了,下面附上回复内容

文字版

Hi. --force-pivoting forces usage of "pivoting" when regular methods fail. You are also being warned by sqlmap to use it in case of failure. What does "pivoting" mean? It means that instead of referencing rows by some form of row numbering (e.g. ROWNUMBER() like you've noticed) to reference them by a so called "pivot" column (e.g. column "userid" if there is one - or any row which has unique values along all entries). sqlmap in such cases, first retrieves the minimum (next) value of such pivot (e.g. SELECT MIN(userid) WHERE userid>{lastretrievedvaluefor_userid}). Afterwards, it retrieves values for all other columns (of current row) just by referencing current pivot column value. Once it finishes with all column values, it goes to the next pivot value,... and so long until the end. Bye

希望大家仔细看看原作者的回复

我总结一下,out-of-order 应该翻译为 有故障的,并不是无序的 百度竟然是对的!!!竟然是对的!!!

难受!!!

最后的碎碎念

最后再说三两句

--force-pivoting 这个参数能不用就不用 这里可能有朋友要说了,介绍了一整篇文章,怎么还不让用了呢??

这里我详细说一下,如果你不使用这个参数就可以实现数据获取,那就别用 从 sql 语句中分析,这个参数的思想是找一个列作为 pivot(枢纽),用这个枢纽去查询其他的数据 但是,作为枢纽的这个列最好是唯一的 举个例子, 选用id列作为pivot,如果id是不重复的,假如就是1,2,3,4 那么整个查询就是按照一定的顺序进行查询的

但是,一旦id列不是唯一的,比如有5个1,4个3 这种情况就会很麻烦,肯定会发生数据丢失


这篇文章用了大概10天时间,大部分都在弯路上

感谢sqlmap开发者和我的那位朋友

接下来我要去完成我的本科毕业设计了

又要拖更很长时间了

实在抱歉!

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

本文分享自 NOP Team 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关键参数
  • 背景
  • 解决问题
  • 探究
    • 1. 查询SQLMAP的帮助信息
      • 2. 查询百度,bing
        • 3. sqlmap发包分析
          • 4. 实验探究
          • 吐槽
            • 慌乱
              • 分析
                • 在坑中挣扎
                  • 从官方简介入手
                    • 用盗版的坑!
                      • 回到了翻译的坑
                        • 最后的碎碎念
                        相关产品与服务
                        云数据库 SQL Server
                        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档