CVE-2020-25695 Postgresql中的权限提升

已经快一年多了,我希望每个人都安康。这是我今年的第一篇也是唯一的一篇文章,涵盖了我在Postgresql中发现的一个有趣的特权升级漏洞。这会影响从9.5开始的所有受支持的Postgresql版本,很可能也会影响大多数较早的版本。

该漏洞类似于检查时间到使用时间TOCTOU的问题,但是在这种情况,它与退出安全受限操作之前未完全清除/重置状态有关。

测试版本:

  • 13.0 – PostgreSQL 13.0 (Debian 13.0-1.pgdg100+1)
  • 12.4 – PostgreSQL 12.4 (Debian 12.4-1.pgdg100+1)
  • 12.3 – PostgreSQL 12.3 (Debian 12.3-1.pgdg100+1)
  • 11.9 – PostgreSQL 11.9 (Debian 11.9-1.pgdg90+1)

发行说明和更新:https : //www.postgresql.org/

目标

我的目标找到一个漏洞,该漏洞将允许一个没有权限的用户将其提升到superuser

有一些合法的方法可以为用户提供更高的Postgresql权限,而不给予用户完整的superuser权限。

通常使用SECURITY DEFINER函数完成此操作。

配置不当时,可以使用一个恶意编写的SECURITY DEFINER 函数和可控制search_path来提升特权。(Cybertec Blog)

在Postgresql文档中(how to safely write security definer functions)显式地说明了此功能。

由于SECURITY DEFINER函数是以拥有它的用户的特权执行的,因此,需要注意使用,确保该函数不会被滥用。

尽管这是合法的功能,它仍然提供了一个很好的开始,因为它使我了解了在源代码中查找的位置。

或许会有一种在其他上下文使用SECURITY DEFINER的方式。

查找

我首先研究了安全定义器函数和Postgresql切换用户权限的其他位置,我注意到其中提高security-restricted operations。这立即引发了一种幻想,即可能在其中找到某些东西。调用grep,并搜索了提到security-restricted operations的位置。

该术语出现的两个地方是src/backend/commands/analyze.cANALYZE指令)和src/backend/commands/vacuum.cVACUUM指令),两者中都有相同的代码注释。

/*
* Switch to the table owner's userid, so that any index functions are run
* as that user.  Also lock down security-restricted operations and
* arrange to make GUC variable changes local to this command.
*/

这带我们走进下一部分。

索引和功能

这似乎很有趣,我不知道索引可以运行函数。现在是时候去先弄清楚如何使索引运行用户功能。

原来这是很容易做到的。文档有大量的索引调用函数示例(即使这些不是用户定义的, 它也展示了如何构造sql查询的语法)

例如:

CREATE INDEX ON films ((lower(title)));

在这种情况下, 一个索引被创建在filmstitle列,并使用lower函数将其转换为小写。这将很直接轻松地提供一个用户创建的功能而不是lower

我跳过了一些必要的调试步骤,但可以归结为阅读使用函数时抛出的错误信息。此时要注意的事情是一个INDEX需要一个IMMUTABLE函数,这意味着该函数将始终为给定的输入返回相同的结果。这是有道理的,INDEX正在尝试优化唯一性。

CREATE FUNCTION sfunc(integer) 
  RETURNS integer
  LANGUAGE sql IMMUTABLE AS
  'SELECT $1';

现在创建一个表,并在该表创建一个索引:

CREATE TABLE blah (a int, b int);
INSERT INTO blah VALUES (1,1);

CREATE INDEX indy ON blah (sfunc(a));

这作用并不是很大,我想要一个做更有用事情的功能。例如将值插入到其他表中。原因是我想索引正在执行索引功能的用户。 在这点上,我的想法是:

create index as unpriv --> privileged user executes ANALYZE/VACUUM --> index function executes as privileged user

在这种场景,我计划使用SERCURITY INVOKER诱使Postgres以特权用户执行此功能。

-- create the table to insert the user into
CREATE TABLE t0 (s varchar);

-- create the security invoker function
CREATE FUNCTION sfunc(integer) RETURNS integer
   LANGUAGE sql 
   SECURITY INVOKER AS
   'INSERT INTO t0 VALUES (current_user); SELECT $1';

如上文所说, 索引需要一个IMMUTABLE函数.因此,尝试在索引使用该函数,将引发错误:

tmp=# CREATE INDEX indy ON blah (sfunc(a));
ERROR:  functions in index expression must be marked IMMUTABLE

这似乎是一个死胡同。然后我突然想到可以重新创建/重新定义功能。只要您使用CREATE OR REPLACE FUNCTION,任何现有的功能将会被覆盖。也许INDEX不会去检查一个定义好的函数是否会发生改变。(剧透,它的确不会)

```

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖