写在前面的话


在安全防御端的研究中,或者作为安全防御端研究人员,我们常常都会站在攻击者的角度或攻击向量切入点来思考安全防御问题,这些攻击者一般来说都是来自信任区域之外的威胁行为者。但是,如果攻击者已经成功进入了我们的信任区域,并且想要获取我们的数据,此时该怎么办呢?


这就是我们常说的外部威胁转变成内部威胁之后的场景,随着云服务的使用和覆盖越来越广泛,攻击者也开始利用云服务来实现自己的目标。在这篇文章中,我们将深入分析威胁行为者如何使用AWS服务来实现渗透和数据窃取。


关于Amazon S3


Amazon Simple Storage Service(Amazon S3)是一种对象存储,它具有简单的 Web 服务接口,可用于在Web上的任何位置存储和检索任意数量的数据。S3的数据存储结构非常简单,就是一个扁平化的两层结构:一层是存储桶(Bucket,又称存储段),另一层是存储对象(Object,又称数据元)。存储桶是S3中用来归类数据的一个方式,它是数据存储的容器,每一个存储对象都需要存储在某一个存储桶中。


本文主要以Amazon S3为例,并探索针对Amazon S3的威胁模型和渗透用例。


下图显示的是常见的Amazon S3系统架构图:



从企业网络内部发出的请求将首先到达出口代理、防火墙或 CASB,而这些功能可以是连续的、单一的或一体化的解决方案。但这些功能往往寻求实现的结果是相同的,即数据泄露防护。


CASB应防止威胁行为者登录除目标企业帐户之外的其他云服务提供商帐户。


防火墙或出口代理应防止威胁行为者建立与任意或其他已知恶意域的连接。


在企业内部网络中,威胁行为者可以做到以下两件事情:


1、使用组织AWS帐户访问S3,可能没有权限或仅使用s3:GetObject;
2、匿名访问 S3,即可以使用curl获取S3资源;


当然了,还有第三条路径,即把目标用户的账号凭证带入企业内部网络中,不过这超出了本文的讨论范畴。


需要注意的是,本文讨论的场景中我们是没有任何权限的,或者说我们最多就只有一个s3:GetObject。


研究计划


下图显示的是本文使用S3作为数据提取机制的流程图:



我们先看看下面这个场景:



此时,威胁行为者可以控制目标用户中的RoleA,而RoleA的权限中明确规定了不允许对目标环境执行任何操作或资源访问。那么在这种情况下,威胁行为者是否能够成功利用RoleA实现数据泄露,并将数据提取到不同账户中的AttackerBucket呢?


当然了,在执行操作时,RoleA肯定会收到AccessDenied的提示,这是无法绕过的。另外,威胁行为者要做的是获取一个对象,而不是执行写入操作。看起来挺难的吧?与此同时大家可别忘了,我们还有代理、防火墙和CASB来阻止请求到达威胁行为者的S3 Bucket。



但S3又一个非常棒的功能,即“服务器访问日志”,S3的服务器会将所有针对目标S3 Bucket发出的请求详细记录到日志中。


它的行为方式和常见的Web服务器日志记录行为类似,但此时并不是直接在服务器/var/log下传递请求日志,而是需要配置另一个Bucket,即一个日志Bucket。


如果你使用过这个功能的话,你可能会见过如下所示的来自内部AWS服务(例如 IAM 访问分析器)的请求日志信息:


attackerbucket [19/Oct/2023:12:48:23 +0000] 54.229.101.202 arn:aws:sts::123456789012:assumed-role/AWSServiceRoleForAccessAnalyzer/access-analyzer [..] - "GET /?location HTTP/1.1" 200 - 137 - 28 - "-" "aws-sdk-java/2.20.162 Linux/4.14.255-318-256.530.amzn2.x86_64

 

OpenJDK_64-Bit_Server_VM/25.382-b05 Java/1.8.0_382 vendor/Amazon.com_Inc. md/internal exec-env/AWS_Lambda_java8.al2 io/sync http/Apache cfg/retry-mode/legacy" – [..] SHA256 AuthHeader attackerbucket.s3.eu-west-1.amazonaws.com TLSv1.2 - -


你可以在日志中看到请求所使用的角色、来源和用户代理信息。上述日志中,我们可以看出 IAM 访问分析器正在Java8运行时中的Lambda上运行。


AWS文档中提到


当VPC终端节点策略拒绝时,Amazon S3不支持将服务器访问日志发送给VPC终端节点请求的请求者或Bucket所有者。

这是否意味着,当我们位于VPC外部(使用公司防火墙)或VPC没有限制性终端节点策略时,Amazon S3就支持发送服务器访问日志了呢?是的,没错!


分析执行


下图显示的是威胁行为者的配置图(一个日志Bucket):



威胁行为者可以启动S3服务器的访问日志记录功能,并将其转储到另一个他们可以控制的Bucket中,然后在没有权限的情况下,绕过IAM条件设置的数据边界,使用目标用户的身份从目标组织网络内窃取数据。同样的远离也适用于向“AttackerBucket”发送GET请求,但不同之处就在于目标网络的代理、防火墙或CASB如何去处理这些请求了。如果你仅允许使用AWS组织的凭证进行身份验证的请求,那么威胁行为者仍然可以使用此技术并访问S3服务和数据资源。


如果威胁行为者位于VPC内部时,会发生什么呢?VPC策略首先需要允许请求抵达S3服务:



在一个VPC内,威胁行为者需要一个泄露的VPC节点,例如一个允许将请求转发到S3服务器的节点。这样一来,威胁行为者不需要其 IAM 角色的任何权限即可请求访问 S3 服务和数据资源。


下面给出的是服务器访问日志记录的工作原理序列图:



S3 服务将接收并评估请求,并根据情况返回对应的响应信息。然后它会记录请求,收集日志,并将它们发送到日志Bucket中,同时请求者没有IAM访问权限的这一事实也会被记录下来。


当VPC节点位于威胁行为者和S3服务之间时,整体情况将完全取决于S3服务对来自VPC节点的请求评估结果了。如果请求从未到达S3服务,则不会生成和发送任何日志,比如说你的Bucket使用了资源限制条件屏蔽了外部资源访问等等。


威胁行为者接收到的日志信息格式大致如下:


[..] attackerbucket […] 31.94.19.179 – […] REST.GET.OBJECT PIIorOtherDataToExfilGoesHere "GET / PIIorOtherDataToExfilGoesHere HTTP/1.1" 403 AccessDenied 243 - 18 - "-" "UserAgentAlsoHasData " – […


其中的“PIIorOtherDataToExfilGoesHere”是我们从S3请求的对象密钥,“UserAgentAlsoHasData”是我们为该请求设置的用户代理。


威胁行为者可以使用“Key”、“User-Agent”或其他S3 GetObject请求参数并在这些请求中包含任意数据。生成的“拒绝访问”服务器日志条目中将包含威胁行为者控制的数据,这些数据最终可以在威胁行为者的日志Bucket中捕捉到。


可怕的是,每个请求都包含有一个1024字节长的密钥(“Key”),这足以泄露大量的数据了。


总结


总而言之,单独使用 AWS IAM 并不是有效的数据边界,如果没有额外的网络边界控制,服务器访问日志可以通过提供可携带任意数据的请求信息来用作窃取数据的机制。


参考资料


https://www.optiv.com/explore-optiv-insights/blog/escape-and-evasion-egressing-restricted-networks
https://aws.amazon.com/blogs/networking-and-content-delivery/continually-enhancing-domain-security-on-amazon-cloudfront/
https://www.youtube.com/watch?v=sc3J4McebHE
https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html#how-logs-delivered
https://github.com/aws-samples/data-perimeter-policy-examples/blob/main/vpc_endpoint_policies/s3_endpoint_policy.json
https://docs.aws.amazon.com/AmazonS3/latest/userguide/LogFormat.html


参考链接


https://airwalkreply.com/cloud-services-as-exfiltration-mechanisms?utm_source=cloudseclist.com&utm_medium=referral&utm_campaign=CloudSecList-issue-218