一次"走进误区"的Mssql注入

0x00

首发,【一次走进误区的Mssql注入 https://xz.aliyun.com/t/2596】

# 0x01 有问题吧?

  • 抓包看到输入一个号码后,会有两个请求查询判断:

请求判断

  1. 卡号是否存在;
  2. 卡号对应的个人信息;
  • 初步判断:此处进行了数据库查询

# 0x02 进一步测试

## Part Ⅰ 自动化工具

  • 直接使用了sqlmap,同时首次实用工具时参数上添加了几个条件:

    1. “– delay 10”;

      为什么使用delay,因为考虑到测试对象的敏感程度,有waf等防护是必然的,请求的延时可以避免大量测试请求直接造成IP被封禁等一系列的影响,造成之后测试的硬性阻隔,当然,之后的测试发现,短时间内的频繁请求会被禁IP。

    2. “–time-sec 15” ; // 考虑到时间盲注的延时

    3. “–timeout 20” ; // 考虑到超时

    4. “tamper”; // 混淆&绕过

      此处的正常思路应是先尝试确认过滤了哪些字符,哪些没有被过滤,然后逐步构造payload,针对性的写tamper进行测试。

    • 自己使用自动化工具不能发现问题,判断此处不存在注入,可能是因为自带的tamper混淆没有能够成功构造出合适的payload.

## Part Ⅱ 手工注入

### 信息确认

  • 回到手工注入,首先需要判断什么数据库类型等数据库信息,之后可以针对性的进行构造;
  1. 构造常规的payload “ ‘ and @@version ”,或是“ ‘ and @@version – ”提示语法错误;
1
2
> > payload1: ' select @@version 
> >

Tips:

  • 这里使用数据库“内置函数“进行测试,因为数据库查询的优先级原因,正常情况下会优先执行内置函数查询
  • 通过报错可以看到语法错误,以及通过报错信息搜集数据库信息,辅助确定数据库类型
  • 如果执行了构造的payload,那么页面返回信息会显示相关的信息

payload报错

1
2
3
> > **上一次尝试select 语句有错误,换用另一payload进行测试,如下**
> > payload2: /' and @@version
> >

语法错误

注:这个报错信息不是构造的payload参数中的,是其他代码的错误,并且注释符都无用,最后想到的可能性为,此处的“or a.xxxcode= ”语句是前面用户输入ID值得一部分,需要作为整体去数据库查询,只能闭合当前的payload,所以用下面的方法,再添加and语句,完成闭合

lite
1
2
> payload4: ' and @@version>0 and '1'='1
>

注:

  • 这里的思路是结合数据库查询的优先级,使用数据库的内置函数,它的查询顺序优先于一般查询,因此此处使用数据库内置函数进行尝试;

### mssql注入

  • 数据库类型确定:MSSQL
  • 爆破其他参数:
1
2
3
4
> > payload5: and db_name()>0 and '1'='1 // 当前数据库
> > payload6: and user_name()>0 and '1'='1 // 当前用户
> > payload7: and @@servername>0 and '1'='1 // 主机名
> >

注:爆破进行到下一步,爆破表的时候发现无论怎么构造,都是没有回显的,查找了一些文章,有人提到了Mssql 2008 出库不出表([你们有遇到过mssql2008出裤不出表的情况吗?](https://xz.aliyun.com/t/2270))的情况,这么尴尬,这么唬人的么?

## Part Ⅲ 出库不出表?

和小伙伴讨论讨论分析了一下,这里为什么会没有任何回显,其实构造的payload是正常执行的,但是返回和正常返回一致,再回想一遍整个过程,发现了关键点的所在,也就清晰了整个流程;

逻辑流程图

Bingo!!!! !!

重点在用户输入的ID和你使用or还是and连接语句

  • or : 使用or连接,那么无论ID处的查询结果是0还是1,均会触发到下一步,比较payload查询到的参数与0进行大小比较报错进而达到”爆表“等效果;
  • and : 使用and连接,那么执行结果分为两种显示情况
    • ID查询返回结果为0,无论后半部分查询结果如何返回,最终结果均为0;
    • ID查询返回结果为1,结合后半部分查询结果为1,最终查询结果为1,触发比较,”爆表“、”爆字段“ and etc.

### 完成一次手注

  • 社会工程学

通过搜索引擎,社一个存在的用户ID号,用来进行查询,可以在这一步的两个请求,分别判断为存在以及返回用户信息:

有数据返回

  • 出库不出表?
1
2
3
4
> payload: and (SELECT top 1 Name FROM Master..SysDatabases)>0 // 爆其他数据库
> payload: and (select top 1 name from [数据库名字].sys.all_objects where type='U' AND is_ms_shipped=0)>0 // 爆表
> payload: and (select top 1 COLUMN_NAME from[数据库名字].information_schema.columns where TABLE_NAME='表名')>0 // 爆字段
>

  • 下图已到字段为止,ok,收工.

### 思路反思(当时自己的错误思路)

这是一个用户输入ID的位置,输入ID之后进行了两个操作:

  • 查询ID是否已存在,无论如何构造,该返回结果只是0或1;
  • 查询ID对应的信息,如果已存在,返回对应用户信息,不存在,则返回“[]”,数据为空;

注意:

  • 这两个过程不存在逻辑关系,相互独立,不管是否已存在,都会请求查询ID对应的用户数据;
  • 此处注入如果用一个不存在的用户ID,当查询结果显示用户ID并不不存在的时,停止进一步查询其他数据,所以返回结果均为空,在进行爆表爆字段等尝试的时候,也不会有任何的回显

当时自己没有理清晰整个查询的流程以及使用什么方式连接,所以误导自己进入了误区,希望和我一样没有”精通“数据库的人阔以引以为戒。em……

# 0x03 参考资源

难得这次帮自己丰富了一下经验,同时收获也很大,个中滋味就是很满足,小小满足感~~~

而且这次在搜索解决问题的过程中,发现了很不错的网站,可以学习参考。