一次"走进误区"的Mssql注入
1 0x00
2 # 0x01 有问题吧?
- 抓包看到输入一个号码后,会有两个请求查询判断:
- 卡号是否存在;
- 卡号对应的个人信息;
- 初步判断:此处进行了数据库查询
3 # 0x02 进一步测试
3.1 ## Part Ⅰ 自动化工具
直接使用了sqlmap,同时首次实用工具时参数上添加了几个条件:
“– delay 10”;
为什么使用delay,因为考虑到测试对象的敏感程度,有waf等防护是必然的,请求的延时可以避免大量测试请求直接造成IP被封禁等一系列的影响,造成之后测试的硬性阻隔,当然,之后的测试发现,短时间内的频繁请求会被禁IP。
“–time-sec 15” ; // 考虑到时间盲注的延时
“–timeout 20” ; // 考虑到超时
“tamper”; // 混淆&绕过
此处的正常思路应是先尝试确认过滤了哪些字符,哪些没有被过滤,然后逐步构造payload,针对性的写tamper进行测试。
- **自己使用自动化工具不能发现问题,判断此处不存在注入,可能是因为自带的tamper混淆没有能够成功构造出合适的payload. **
3.2 ## Part Ⅱ 手工注入
3.2.1 ### 信息确认
- 回到手工注入,首先需要判断什么数据库类型等数据库信息,之后可以针对性的进行构造;
- 构造常规的payload “ ‘ and @@version ”,或是“ ‘ and @@version – ”提示语法错误;
payload1: ' select @@version
Tips:
- 这里使用数据库“内置函数“进行测试,因为数据库查询的优先级原因,正常情况下会优先执行内置函数查询
- 通过报错可以看到语法错误,以及通过报错信息搜集数据库信息,辅助确定数据库类型
- 如果执行了构造的payload,那么页面返回信息会显示相关的信息
**上一次尝试select 语句有错误,换用另一payload进行测试,如下** payload2: /' and @@version
**注:这个报错信息不是构造的payload参数中的,是其他代码的错误,并且注释符都无用,最后想到的可能性为,此处的“or a.xxxcode= ”语句是前面用户输入ID值得一部分,需要作为整体去数据库查询,只能闭合当前的payload,所以用下面的方法,再添加and语句,完成闭合 **
payload4: ' and @@version>0 and '1'='1
注:
- 这里的思路是结合数据库查询的优先级,使用数据库的内置函数,它的查询顺序优先于一般查询,因此此处使用数据库内置函数进行尝试;
3.2.2 ### mssql注入
- 数据库类型确定:MSSQL
- 爆破其他参数:
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出裤不出表的情况吗?)的情况,这么尴尬,这么唬人的么?
3.3 ## Part Ⅲ 出库不出表?
和小伙伴讨论讨论分析了一下,这里为什么会没有任何回显,其实构造的payload是正常执行的,但是返回和正常返回一致,再回想一遍整个过程,发现了关键点的所在,也就清晰了整个流程;
Bingo!!!! !!
重点在用户输入的ID和你使用or还是and连接语句
- or : 使用or连接,那么无论ID处的查询结果是0还是1,均会触发到下一步,比较payload查询到的参数与0进行大小比较报错进而达到”爆表“等效果;
- and : 使用and连接,那么执行结果分为两种显示情况
- ID查询返回结果为0,无论后半部分查询结果如何返回,最终结果均为0;
- ID查询返回结果为1,结合后半部分查询结果为1,最终查询结果为1,触发比较,”爆表“、”爆字段“ and etc.
3.3.1 ### 完成一次手注
- 社会工程学
通过搜索引擎,社一个存在的用户ID号,用来进行查询,可以在这一步的两个请求,分别判断为存在以及返回用户信息:
- 出库不出表?
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,收工.
3.3.2 ### 思路反思(当时自己的错误思路)
这是一个用户输入ID的位置,输入ID之后进行了两个操作:
- 查询ID是否已存在,无论如何构造,该返回结果只是0或1;
- 查询ID对应的信息,如果已存在,返回对应用户信息,不存在,则返回“[]”,数据为空;
注意:
- 这两个过程不存在逻辑关系,相互独立,不管是否已存在,都会请求查询ID对应的用户数据;
- 此处注入如果用一个不存在的用户ID,当查询结果显示用户ID并不不存在的时,停止进一步查询其他数据,所以返回结果均为空,在进行爆表爆字段等尝试的时候,也不会有任何的回显
当时自己没有理清晰整个查询的流程以及使用什么方式连接,所以误导自己进入了误区,希望和我一样没有”精通“数据库的人阔以引以为戒。em……
4 # 0x03 参考资源
难得这次帮自己丰富了一下经验,同时收获也很大,个中滋味就是很满足,小小满足感~~~
而且这次在搜索解决问题的过程中,发现了很不错的网站,可以学习参考。

如果你觉得这篇文章对你有所帮助,欢迎赞赏~
