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