在进行云上渗透测试(CPT)时,目标是发现和利用高风险问题,例如权限提升、远程代码执行或进入生产环境。我们通常从开发环境中的低权限用户开始,这个权限一般和刚入职的员工访问权限差不多。
在一些项目中,权限提升将我们从低权限用户升级到管理员,而且都是在同一个AWS账户中。但是,如果权限提升涉及到离开组织并带入外部角色,会发生什么?让我们看看如何利用 AWS CloudTrail 服务来发现我们可以横向的其他 AWS 账户。
提升权限
根据我们的经验,伪装成刚入职的开发人员索要相关员工所有权限是进行 CPT 时比较常见的做法,之所以这样做是因为敏感信息存储在许多地方,如果只将范围限制在AWS资产上,我们就会错过作为公司员工可能存在的权限提升路径。
开发人员可能在开发环境中拥有大量权限,但通常不具备管理员权限,并且肯定不能访问或修改生产环境中的资产。我们通常会在开发环境中进行详细的测试,并尝试通过查找 API 密钥来提升权限。我们通常会在 S3 存储桶、Lambda 环境变量、内部 wiki 或存储在其他地方(例如 GitHub 或 BitBucket 代码存储库)中找到一些。
一旦我们找到一组或多组 AWS API 密钥,所面临的的首个问题就是它们有什么访问权限,以及它们的用途是什么。因为已经对开发环境进行了比较详细的测试,所以想弄清楚开发环境的密钥所具备的权限是比较简单的。但在其他AWS账户中,我们能用这些密钥做什么呢?这取决于权限策略是如何制定的。
其中一些可能很容易弄清楚,例如下面的策略显示,当前账户具有sts:AssumeRole
权限,当然前提是策略里的 Effect 值为 Allow
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example1",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789012:role/myassumerole"
}
]
}
但是,如果 API 密钥所属账户的策略是下面这个样子要怎么办?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example2",
"Effect": "Allow",
"Action": "sts:*",
"Resource": "*"
}
]
}
此用户账户也许能够担任多个 AWS 账户中的角色,但权限策略中没有任何内容提供有关 AWS 账户 ID 或角色名称的信息。AWS 没有查询其他账户中可以带入的角色的机制,因此在渗透期间,我们无法确定我们可以带入 AWS 账户123456789012
,但真的是这样吗?
Pacu 这个工具里的 iam_enum_roles 模块可以被用来枚举 AWS 环境中的角色,该模块将尝试猜测目标帐户中的角色名称,并确定它们是否可以被带入。但是使用这个 Pacu 模块仍然需要我们知道我们想要带入的目标 AWS 账户 ID。如果我们没有这些信息怎么办?幸运的是,还有另一种方法可以在其他 AWS 账户中查找角色,并结合现有的工具和技术来枚举权限提升的路径。
带入角色
假设我们为一个名为deployBot的账户找到了一套有效的API密钥。在枚举过程中,我们发现该账户的权限比较有限,不过它有sts:assumeRole:*
权限,考虑到这个账户的名字,我们怀疑我们可以使用它来横向到另一个环境,但首先我们需要知道准备横向的帐户 ID 和角色名称。
虽然我们可能没办法枚举出可以带入的所有角色,但如果我们的账户拥有cloudtrail:LookupEvents
权限,我们或许可以使用 CloudTrail 尝试并列举其中一些角色。
在 AWS 中,assumeRole
会被 CloudTrail 记录,详细信息将被存储在任何被配置为捕获此类管理事件的跟踪中。因此,我们可以查询 CloudTrail 并搜索这些成功的assumeRole
事件,从而尝试找到我们可以访问,但我们还不知道的其他 AWS 账户。
相关命令如下:
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole --region us-east-1 | jq '.Events | .[] | .Username as $username | .CloudTrailEvent | fromjson | {timestamp: .eventTime, user: $username, assumedRole: .requestParameters.roleArn}'
此命令的输出如下所示:
{
"timestamp": "2021-12-23T00:35:45Z",
"user": "root",
"assumedRole": null
}
{
"timestamp": "2021-12-23T00:00:26Z",
"user": "user1",
"assumedRole": "arn:aws:iam::123456789012:role/SecurityAudit"
}
{
"timestamp": "2021-12-23T00:00:26Z",
"user": "user1",
"assumedRole": "arn:aws:iam::210987654321:role/SecurityAudit"
}
{
"timestamp": "2021-12-22T23:50:41Z",
"user": "deploybot",
"assumedRole": "arn:aws:iam::112233445566:role/deployToProd"
}
从这个输出中,我们可以看到有人试图使用 root 账户来带入一个角色,但是 AWS 不允许这样做,所以它失败了。我们还看到用户user1
带入了 AWS 账户为123456789012
和210987654321
的角色。但是更有趣的事件是用户deploybot
,他带入了一个名为deployToProd
AWS Account的角色112233445566
,这是一个值得关注的线索。
我们与客户确认后得知该账户属于他们,并且在这样做之前,我们已经被授权跟踪这个线索,在确认后,我们将带入该角色并开始在新的 AWS 账户中进行渗透。事情的发展方向取决于分配给AWS 112233445566
中的deploybot
账户和资产的权限。
用户帐户可能几乎没有权限,在这种情况下,这条路径被证明是一条死胡同。或者,用户帐户可能具有完全的管理权限,在这种情况下,我们刚刚成功入侵了客户的生产帐户,或者介于两者之间的任何东西。但更多的时候,通过一些中间的权限升级方法,我们最终会达到破坏关键生产资源的目标。关键在于 CloudTrail 可用于首先发现此类权限提升路径的存在。
结论
以上是我们经常遇到的简化但现实的云渗透测试场景。在枚举过程中,我们经常会发现客户没有告诉我们 AWS 账户的凭证或 API 密钥,但它们为敏感的云资源提供了可行的权限提升路径。
本文描述的这条命令是一种新方法,通过使用来自 CloudTrail 的信息列出assumeRole
事件,从而实现对 AWS 攻击面的枚举。这可能会发现现有的跨账户关系,否则这些关系可能会被忽视,特别是如果涉及不寻常的角色名称,这时如果去猜测或使用暴力破解角色名称的工具就会错过这些角色。
我们希望这些信息能够帮助其他云渗透测试人员识别和修复跨账户访问问题。
本文为翻译文章,原文链接: https://bishopfox.com/blog/cloudtrail-pivot-to-aws-accounts