问题背景

在最近的项目中发现了一个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.能过了防御机制后看一下传输的格式

1599299151.png!small

目标控制在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 成功

1599300748.png!small

本文作者:Loren麟