文章总结: 文章深入探讨了AWS服务关联角色(SLR)的特性、安全风险和防护措施。SLR是AWS服务自动创建的特殊IAM角色,存在枚举风险、权限过大和缺乏困惑代理人防护等问题。作者建议客户创建所有SLR以防止服务使用情况被探测,并避免使用AWS保留标签和命名规范。同时呼吁AWS优化API机制、加强SLR策略限制并修复权限提升问题。
综合评分: 90
文章分类: 安全建设,网络安全,应用安全,数据安全,其他
AWS服务关联角色的痛,希望你永远都不必懂
Dubito
云原生安全指北
2025年11月25日 08:35
江苏
注:本文翻译自Plerion的文章《Things you wish you didn’t need to know about AWS service-linked roles》[1],可点击文末“阅读原文”按钮查看英文原文。
全文如下:
一、引言
服务关联角色[2](Service-linked roles,SLR)或许本不是您需要关注的概念。但它们的特性如此特殊,以至于您正在阅读这篇关于它们的专业技术博文。
各位技术爱好者,我们要进入正题了。请注意——本文绝非AI生成的敷衍内容,因为您会看到拼写错误和语法问题 (#^.^#)。
服务关联角色的特殊性在于:
- • 只能通过
aws iam create-service-linked-roleAPI 创建 - • 无法通过
aws iam create-roleAPI 创建 - • 必须通过
aws iam delete-service-linked-roleAPI 删除 - • 除非满足特定条件,否则无法删除
- • 无法通过
aws iam delete-role删除 - • 路径格式为
role/aws-service-role/(注意不是”service-linked-role”) - • 角色名前缀为
AWSServiceRoleFor(注意不是”ServiceLinkedRole”) - • 自动关联路径为
policy/aws-service-role/的托管策略 - • 所有权归属 AWS,而非客户
- • 除描述信息外不可编辑(客户权限受限)
本文创作过程中未发现或披露任何安全漏洞。请各公关团队放心,接下来将由我们技术爱好者专注探讨其安全影响与优化方案。
若您喜欢本文,推荐继续阅读:关于S3存储桶的那些冷知识[3]。
二、背景
服务关联角色(service-linked roles)与服务角色(service roles)并非同一概念——无论多少用户UI元素或文档页面将它们混为一谈。事实上,AWS总是随心所欲地交替使用这些术语。但两者存在重要区别。
根据我完全称得上详尽的分析,服务关联角色的创设初衷是为了引导AWS服务[4]或具有跨服务依赖的服务资源。
服务关联角色是一种特殊的服务角色,用于授权服务代表您访问其他服务中的资源。
每个服务可为自身定义一个服务关联角色,包括信任策略和托管资源策略。某些服务显然可配置多个服务关联角色,尽管我尚未在实际环境中观察到这种现象。服务全权负责其服务关联角色的创建、修改和删除。以下是Organizations内的IAM Identity Center[5]的运作机制。
这种安全模型颇为奇特,虽未达到光怪陆离的程度,但确实令人费解。从物理层面看,AWS确实拥有并掌控一切(毕竟所有服务器都在其数据中心),但这并非指随便某个支持人员都能读取您的数据。我始终认为账户中的所有资源都应归我所有,可随心支配。然而,这些角色既无法编辑,又难以删除(有时),甚至连权限都无法调整。更甚者,我无法在账户中创建以“AWSServiceRoleFor”开头的普通角色。亚马逊正在未经客户监管的情况下单方面规定其所需访问权限。这既诡异又略显骇人,不是吗?
当然,AWS客户通过向导或模板创建并拥有的服务角色和执行角色概念依然存在。这些角色才符合安全模型的预期,为何不直接沿用它们呢?我确信其中必有深意。
三、枚举服务关联角色及其策略
IAM文档中提供了一张详尽的表格[6],列出了使用服务关联角色(service-linked roles)的各类服务。但这份表格是否及时更新且准确无误?并非如此。它能否让您全面理解所有信任策略和资源策略?同样不能。
幸运的是,存在一个(略显隐蔽的)高级机密 iamv2 服务API。如果您查看使用AWS管理控制台时的网络流量,会发现系统定期调用 iamv2 API。该API包含一个 getServiceLinkedRoleTemplate 方法,仅需传入 serviceName 参数。服务名称即完整的AWS服务域名,以”amazonaws.com[7]”结尾,例如”ec2.amazonaws.com”。
该函数返回的JSON数据结构如下,其中包含角色所需的完整资源策略和信任策略:
{
"namedPermissionsPolicies": [
{
"policyName": "AccessAnalyzerServiceRolePolicy",
"policyId": "ANPAZKAPJZG4CAIXDDRI2",
"arn": "arn:aws:iam::aws:policy/aws-service-role/AccessAnalyzerServiceRolePolicy",
"path": "/aws-service-role/",
"defaultVersionId": "v17",
"createDate": "Dec 2, 2019, 5:13:10 PM",
"updateDate": "May 12, 2025, 3:52:06 PM",
"policyDocument": "..."
}
],
"awsServiceName": "access-analyzer.amazonaws.com",
"assumeRolePolicy": "...",
"roleNamePrefix": "AWSServiceRoleForAccessAnalyzer",
"isAllowMultipleRoles": false
}
因此,只要我们能整理出完整的服务名称列表,就可以枚举所有服务关联角色及其策略。值得庆幸的是,AWS团队近期发布了便于开发者使用的服务参考目录[8],可通过编程方式获取,这为我们构建可靠列表提供了基础:
curl -s https://servicereference.us-east-1.amazonaws.com/v1/service-list.json \
| jq -r '.[].service + ".amazonaws.com"'
我多么想告诉您这能生成完整列表,但事实往往不如人意。某些隐藏的、区域特定的、非生产环境的、测试用的、开发中的服务并未包含在该列表中,不过现有数据已足够接近完整。如果您需要更全面的列表,可以尝试使用Nick Frichette的未公开AWS API探测工具[9]。虽然仍非完美,但这正是AWS生态规模化的体现。无论如何,我们现有的资源已经足够使用。
欢迎访问本人整理的服务关联角色名称列表[10]进行查阅。
四、检测任意账户的服务使用情况
早在2016年,年轻帅气的我曾发现AWS策略验证引擎中存在一个有趣特性,这个特性至今仍然存在。如果您在资源策略或信任策略中指定了无效的主体,策略验证引擎会抛出错误并提示该主体不存在:
这意味着只要知道账户ID和可能存在的合理主体名称,您就能检测任意账户中是否存在特定角色,即使您无权访问该账户。由于服务关联角色(SLR)的名称具有可预测性,且通常在首次使用服务时自动创建,您就能以一定准确度检测目标账户是否正在使用某个(支持SLR的)服务。
您可以通过以下方式实现检测:
- • 使用我原创的手工代码[11]
- • 采用工业化工具Quiet Riot[12]
- • 体验Roles[13]工具的超常规检测
若想深入了解黑客对您AWS账户的掌握程度,请参阅这篇技术博客[14]。
必须承认,服务关联角色的存在与服务的实际使用之间关联并不绝对,例如可能只是短暂使用后便不再触碰。若您希望迷惑攻击者并强化这种不确定性,可以通过编程方式在账户中创建所有可用的服务关联角色:
for svc in $(curl -s https://servicereference.us-east-1.amazonaws.com/v1/service-list.json | jq -r '.[].service + ".amazonaws.com"'); do
echo "Trying: $svc"
aws iam create-service-linked-role --aws-service-name "$svc" 2>&1
done
此操作将使您的账户显示为正在使用所有AWS服务的状态。
五、无列举权限时的资源枚举技术
假设您的AWS用户或角色绑定了如下策略:该策略仅允许两个IAM操作,DeleteServiceLinkedRole 和 GetServiceLinkedRoleDeletionStatus,但明确禁止除这两项外的所有操作。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificIAMActions",
"Effect": "Allow",
"Action": [
"iam:DeleteServiceLinkedRole",
"iam:GetServiceLinkedRoleDeletionStatus"
],
"Resource": "*"
},
{
"Sid": "ExplicitDenyAllOtherActions",
"Effect": "Deny",
"NotAction": [
"iam:DeleteServiceLinkedRole",
"iam:GetServiceLinkedRoleDeletionStatus"
],
"Resource": "*"
}
]
}
理论上您将无法列出账户中的任何资源。
例如,在绑定此角色后尝试列出SageMaker域时:
% aws sagemaker list-domains --region ap-southeast-2
An error occurred (AccessDeniedException) when calling the ListDomains operation: User: arn:aws:sts::123456789012:assumed-role/dg-test-with-deny/dg-deny-test is not authorized to perform: sagemaker:ListDomains on resource: arn:aws:sagemaker:ap-southeast-2:123456789012:domain/* with an explicit deny in an identity-based policy
结果符合预期。
然而,当我尝试删除SageMaker的服务关联角色时,却出现以下情况:
% TASK_ID=$(aws iam delete-service-linked-role \
--role-name AWSServiceRoleForAmazonSageMakerNotebooks \
--query 'DeletionTaskId' --output text)
% aws iam get-service-linked-role-deletion-status \
--deletion-task-id "$TASK_ID"
{
"Status": "FAILED",
"Reason": {
"Reason": "A service-linked role is required for managing Amazon SageMaker Studio domains. Try again after deleting all the domains in your account.",
"RoleUsageList": [
{
"Region": "ap-southeast-2",
"Resources": [
"arn:aws:sagemaker:ap-southeast-2:123456789012:domain/d-favr5gpmidva",
"arn:aws:sagemaker:ap-southeast-2:123456789012:domain/d-ldskx5dymwrb",
"arn:aws:sagemaker:ap-southeast-2:123456789012:domain/d-eviyaeotkfyc",
"arn:aws:sagemaker:ap-southeast-2:123456789012:domain/d-xspebcdlbc4d",
"arn:aws:sagemaker:ap-southeast-2:123456789012:domain/d-d14gz4fosoce"
]
}
]
}
}
由于删除任务会自动执行SageMaker域的列举操作(推测是通过委托服务本身权限或其他IAM黑魔法实现),我得以在从未亲自执行列举操作的情况下,直接查看列表结果。
该现象同样适用于其他在尝试删除服务关联角色时仍存在资源的服务。
六、关于困惑代理人防护的非必要性问题
困惑代理人(confused deputy)问题[15]确实令人困惑。
通俗解释:当您委托一个高权限AWS服务(如Lambda)执行小任务时,由于该服务无法准确辨别请求来源和意图,攻击者可能诱骗其滥用高阶权限执行越权操作。
历史上AWS曾多次出现困惑代理人漏洞。官方通过多种方式应对,包括发布大量相关文档。您可尝试搜索 "confused deputy" site:docs.aws.amazon.com 感受该议题的涉及范围。
如果您查看具体服务的说明页——例如我点击的AWS Transfer Family文档[16]——通常会看到关于服务角色/执行角色及如何构建安全信任策略的说明。以下是AWS Transfer Family执行角色的信任策略示例:
{
"Version":"2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "transfer.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "123456789012"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:transfer:us-east-1:123456789012:user/*"
}
}
}
]
}
请注意其中使用了 aws:SourceAccount 和 aws:SourceArn 条件键。这些条件实质上规定:当该角色被担当时,必须是由指定账户中的主体操作所触发。这样就能防止其他账户的用户诱骗 transfer.amazonaws.com 服务担当此角色。
为何要详细说明这一点?因为通过分析所有服务关联角色的信任策略,我们可以检验其困惑代理人防护机制。结果发现…它们完全没有防护。没有一个策略包含 Condition 条件语句。
这是否意味着这些角色可能被用于困惑代理人攻击?大概率不会,但我无法完全确定。AWS的说法则更为明确(详见本节末尾的官方回复)。
看起来AWS曾在某个时间点进行了调整,通过 iam:PassRole 逻辑来限制服务关联角色。如果您不熟悉该权限,iam:PassRole 既是主体请求的操作,也是执行该操作所需的权限。实际应用中,它允许用户或服务指示AWS”使用此角色”,使目标服务能担当该角色并行使相应权限。AWS似乎阻止了对服务关联角色执行此操作,这可能是他们预防困惑代理人滥用的方式,尽管信任策略中并未包含显式的条件语句。
以下是我尝试将CloudWatch服务关联角色用作执行角色的示例:
% aws events put-targets \
--rule dg-rule-test \
--region ap-southeast-2 \
--targets "Id"="test-queue-senal","Arn"="arn:aws:sqs:ap-southeast-2:123456789012:test-queue-senal","RoleArn"="arn:aws:iam::123456789012:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents"
An error occurred (ValidationException) when calling the PutTargets operation: Caller Account ID: 058264279384 is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789012:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents because a service-linked role cannot be used with the iam:PassRole action. Use a service role instead.
然而,我在网上发现大量文档(从Reddit讨论到官方AWS文档)都显示这种操作本应可行,例如这份AutoScaling文档:
我向AWS漏洞披露计划(VDP)寻求澄清,得到了更明确的答复:
当前所有IAM角色都不会受到困惑代理人问题影响,因为您无法使用来自其他账户的角色(包括服务角色和SLR)。您只能通过 iam:PassRole 权限将同一AWS账户中的IAM角色传递给服务
我的看法:这一结论总体上是准确的,前提是所有将角色传递给AWS服务的情况都受 iam:PassRole 机制约束,这确实是AWS的设计初衷。但设计意图与现实执行并非总是完全一致,因此我仍欣慰地看到所有执行角色模板都配备了防护困惑代理人攻击的条件语句,这相当于增加了一层安全保险。
七、资源策略存在值得商榷的实践
在我开始调侃IAM策略之前(说得好像我从未为了快速解决问题而在策略里配置过 iam:* 似的),我们需要先明确几点:
- • 客户必须在某种程度上信任AWS。既然选择使用AWS,就意味着需要建立一定程度的信任。所谓云计算本质就是”他人的计算机”——在这里是亚马逊的。
- • AWS已在安全领域投入巨额资金,但系统的复杂性和目标价值决定了黑客攻击终将发生,甚至可能早已存在。
- • 当安全事件发生时,客户仍应尽可能为攻击者设置障碍,从而限制潜在损害,并为检测和清除恶意行为争取更多时间。
- • 因此即使信任AWS,客户也应当以高标准审视其策略规范。
基于以上认知,现在开始扮演小丑吧。
许多服务关联角色策略未能将操作范围限定在特定资源子集,而是直接在Resource字段中使用通配符*。虽然某些功能确实需要这种配置,但多数情况下并非必要。当不需要时,这种设计就违背了最小权限原则[17]。
以下示例来自RDS服务关联角色策略:
{
"Sid": "Ec2",
"Effect": "Allow",
"Action": [
"ec2:AllocateAddress",
"ec2:AssociateAddress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateCoipPoolPermission",
"ec2:CreateLocalGatewayRouteTablePermission",
"ec2:CreateNetworkInterface",
"ec2:CreateSecurityGroup",
"ec2:DeleteCoipPoolPermission",
"ec2:DeleteLocalGatewayRouteTablePermission",
"ec2:DeleteNetworkInterface",
"ec2:DeleteSecurityGroup",
...
"ec2:DisassociateAddress",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:ModifyVpcEndpoint",
"ec2:ReleaseAddress",
"ec2:RevokeSecurityGroupIngress",
"ec2:CreateVpcEndpoint",
"ec2:DescribeVpcEndpoints",
"ec2:DeleteVpcEndpoints",
"ec2:AssignPrivateIpAddresses",
"ec2:UnassignPrivateIpAddresses"
],
"Resource": "*"
}
尽管我不完全了解RDS的内部工作机制,但可以推断这种配置存在合理性,因为RDS运行在EC2之上,需要对EC2实例具备一定控制权。但RDS是否应该为所有EC2实例(而不仅是RDS实例)分配IP地址?或者是否应该被授权配置非RDS实例的网络入站访问?显然这里需要某些限制。问题在于如何实现这些限制。而根据我的观察,AWS各服务在这方面已经尝试了各种令人瞩目的方案。
7.1 方式一:基于标签的策略
理念可嘉但实践问题重重。这段原本写着”使用标签有害”,但我的上级认为这个表述论证不足。
以下是Evidently[18]策略中的条件语句示例:
"Condition": { "StringNotEquals": { "aws:ResourceTag/Owner": "Evidently" } }
Owner 是客户常用的标签键,事实上它被亚马逊官方AWS标签指南[19]推荐为必选标签。如果该标签已被客户使用,使用该标签的服务将导致冲突,并可能与其他策略及下游系统产生不可预见的交互。试想该标签若被用于团队成本分摊会引发何种混乱。
这还只是特例,以下是服务关联策略条件中使用的全部标签键:
AmazonConnectCampaignsEnabled
AmazonConnectEnabled
AmazonECSManaged
AmazonEVSManaged
AmazonFSx
AmazonFSx.FileSystemId
AmazonMWAAManaged
AmazonTimestreamInfluxDBManaged
AppIntegrationsManaged
aws:backup:source-resource
aws:cloudformation:stack-id
aws:elasticfilesystem:default-backup
AWSAppFabricManaged
AWSApplicationMigrationServiceManaged
AWSBatchServiceTag
AWSDeviceFarmManaged
AWSElasticDisasterRecoveryManaged
AWSLicenseManager
AWSNetworkFirewallManaged
AWSPCSManaged
bugbust
codeguru-reviewer
created-for-service
CreatedBy
DeployedBy
DevOps-Guru-Analysis
DevOps-GuruInsightSsmOpsItemRelated
eks:eks-cluster-name
emr-container:endpoint:managed-certificate
EnableAWSServiceCatalogAppRegistry
ExcludeFileContentFromNotifications
FMManaged
GuardDutyManaged
InstanceConnectEndpointId
LicenseManagerLinuxSubscriptions
ManagedByAmazonSageMakerResource
ManagedByCloudWatchNetworkMonitor
OpenSearchManaged
OSISManaged
Owner
Redshift
refactor-spaces:application-id
refactor-spaces:environment-id
refactor-spaces:route-id
ResourceCreatedBy
RTBFabricManaged
SecurityIncidentResponseManaged
SSMForSAPCreated
SSMForSAPManaged
VerifiedAccessManaged
VpcLatticeManaged
WorkSpacesWebManaged
这些标签在客户环境中可能并不常见,但客户现在必须意识到:这些标签已被预留、为服务正常运行所必需、为安全机制正常运作所必需,且不应被客户的自定义需求所覆盖。
呃,您认识能完整追踪这些标签的人吗?客户是否知晓这些标签对安全的潜在影响?进而,客户是否明白仅通过给资源打标签就可能授予AWS访问权限?
我进行了一些测试,看看能不能以某种方式利用他们。例如,尝试通过特定标签配置使某个资源出现在其他服务的列表中。虽未成功,但坦白说我很快失去了耐心。我敢打赌这里一定存在跨服务访问的滥用案例。
最疯狂的是,上方的标签列表本身就包含解决方案。注意那些以 aws: 前缀开头的标签吗?这些标签专供AWS内部使用。以下是我尝试使用该前缀标签启动EC2实例时的结果:
An error occurred (InvalidParameterValue) when calling the RunInstances operation: Tag keys starting with 'aws:' are reserved for internal use
命名空间已经存在并被保留。只需将标签移至保留命名空间即可解决所有问题。例如,如果Evidently使用 aws:Owner 而非 Owner,就不会产生冲突。客户将无法更改这些资源的安全属性,跨服务访问也将受服务自身操作的限制。
最后别忘了,公共资源上的标签值也是可枚举的。若您不了解,有一款名为Conditional Love[20]的工具能够跨账户读取标签值[21]——只要知道标签键名称。
使用标签有害。🤷
7.2 方式二:基于名称的策略
其理念是使用资源名称的特定部分而非标签。这与方式一概念相似,也存在类似问题。
如果资源名称前缀能被预留,这本是一种合理方案(是真正合理而非妻子说”没事”那种合理)。但现实通常并非如此。好消息是资源通常无法重命名,因此在AWS获取访问权限后,客户往往难以再干预其访问范围。
以下是客户需要追踪的所有S3存储桶命名规范,因为它们都出现在服务关联角色策略中:
arn:aws:s3:::*/AWSAppFabric/*
arn:aws:s3:::amazon-braket-*
arn:aws:s3:::amazon-connect-*
arn:aws:s3:::amazon-connect-*/*
arn:aws:s3:::aws-license-manager-service-*
arn:aws:s3:::aws-migrationhub-orchestrator-*
arn:aws:s3:::aws-waf-logs-security-lake-*
arn:aws:s3:::AWSIVS_*/ivs/*
arn:aws:s3:::codeguru-reviewer-*
arn:aws:s3:::codeguru-reviewer-*/*
arn:aws:s3:::dms-serverless-premigration-results-*
arn:aws:s3:::migrationhub-orchestrator-*
arn:aws:s3:::migrationhub-orchestrator-*/*
arn:aws:s3:::migrationhub-strategy-*
arn:aws:s3:::sms-app-*
部分服务标准化了这一概念,为AWS专用保留了部分命名空间。例如CloudWatch设有专用条件 cloudwatch:namespace,用于阻止客户创建以 AWS/ 开头的日志组。
SES的做法就值得称道,它避免了前述所有缺陷,证明优秀实践确实可行:
{
"Sid": "AllowPutMetricDataToSESCloudWatchNamespaces",
"Effect": "Allow",
"Action": "cloudwatch:PutMetricData",
"Resource": "*",
"Condition": {
"StringLike": {
"cloudwatch:namespace": [
"AWS/SES",
"AWS/SES/MailManager",
"AWS/SES/Addons"
]
}
}
}
相信您已理解症结所在,但请允许我再举一个典型案例,Secrets Manager密钥。多条策略允许AWS从您的SecretsManager读取密钥,这让我深感不安。
任何以”Panorama”开头的密钥均可被AWS读取和删除。幸运的是Panorama[22]服务将于2026年5月停止运营。
{
"Sid": "SecretsManagerPermissions",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:CreateSecret",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:DeleteSecret"
],
"Resource": [
"arn:aws:secretsmanager:*:*:secret:panorama*",
"arn:aws:secretsmanager:*:*:secret:Panorama*"
]
}
这是Kafka服务,能够修改以AmazonMSK_开头的密钥访问权限的配置:
{
"Effect": "Allow",
"Action": [
"secretsmanager:PutResourcePolicy",
],
"Resource": "*",
"Condition": {
"ArnLike": {
"secretsmanager:SecretId": "arn:*:secretsmanager:*:*:secret:AmazonMSK_*"
}
}
}
License Manager中的Linux订阅可获取任意密钥值(糟糕!),但采用了有趣的条件组合:既需要标签(我们知道这并不理想),又包含以下AWS 可以做的更好的模型:
"Condition": { "StringEquals": {"aws:ResourceAccount": "${aws:PrincipalAccount}" }}
该条件要求主体(此处为服务关联角色)的账户ID必须与所访问资源的账户ID一致。这有效预防了跨账户类问题,对于可跨账户暴露的资源[23]尤为重要。
如果另一个账户(账户B)授予您的账户(账户A)访问其跨账户资源的权限,那么您账户(账户A)中所有AWS拥有的服务关联角色也将自动获得访问账户B中该资源的权限——这显然不符合设计初衷。账户B无法感知这种间接信任关系,只能通过推断得知。值得庆幸的是,我审查的所有策略均未明确允许 iam:AssumeRole 操作。
这些策略中还潜藏着一个更隐蔽的不良实践:权限提升。某些权限或其组合实际上允许将权限提升至超出既定策略范围。因此即便策略表面看似无害,却可能实现远超预期的操作。
以Application Migration Service服务关联角色策略中的这段配置为例,它实际上赋予了该角色执行EC2实例执行角色所有操作的能力。这是因为 ModifyInstanceAttribute 可用于修改用户数据启动脚本,而 StopInstances 与 StartInstances 的组合能触发脚本执行。这个2016年编写的脚本[24]至今仍然有效。
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:ModifyInstanceAttribute",
"ec2:GetConsoleOutput",
"ec2:GetConsoleScreenshot"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"Null": {
"aws:ResourceTag/AWSApplicationMigrationServiceManaged": "false"
}
}
}
类似地,当角色拥有 ssm:SendCommand 权限并配合 document/AWS-RunPowerShellScript 或 AWS-RunShellScript 使用时,实质上就获得了在实例执行角色上下文中运行代码的能力,包括该角色拥有的所有权限。
以下是Directory Service服务关联角色的示例:
{
"Sid": "SSMSendCommandPermission",
"Effect": "Allow",
"Action": [
"ssm:SendCommand"
],
"Resource": [
"arn:aws:ssm:*:*:document/AWS-RunPowerShellScript",
"arn:aws:ec2:*:*:instance/*"
]
}
虽然Plerion还能识别其他权限提升向量,但您已理解核心问题。Hacking The Cloud维护的这份包含40多种方法的清单[25]提供了更全面的参考。
八、如何查看您账户中的服务关联角色?
若您关注或想了解自身环境中的相关配置,可通过以下命令轻松查看账户中的所有服务关联角色:
aws iam list-roles \
--query 'Roles[?starts_with(Path, `/aws-service-role/`)].[RoleName, Path]' \
--output table
-----------------------------------------------------------------------------------------------------------------------------------
| ListRoles |
+--------------------------------------------------------+------------------------------------------------------------------------+
| AWSServiceRoleForAccessAnalyzer | /aws-service-role/access-analyzer.amazonaws.com/ |
| AWSServiceRoleForAmazonEKS | /aws-service-role/eks.amazonaws.com/ |
| AWSServiceRoleForAmazonEKSForFargate | /aws-service-role/eks-fargate.amazonaws.com/ |
| AWSServiceRoleForAmazonEKSNodegroup | /aws-service-role/eks-nodegroup.amazonaws.com/ |
| AWSServiceRoleForAmazonEMRServerless | /aws-service-role/ops.emr-serverless.amazonaws.com/ |
| AWSServiceRoleForAmazonGuardDuty | /aws-service-role/guardduty.amazonaws.com/ |
-----------------------------------------------------------------------------------------------------------------------------------
九、结论与行动倡议
致AWS客户:
- • 考虑在账户中创建所有服务关联角色(SLR),以防服务使用情况被枚举探测
- • 确保避免使用与AWS保留标签或特殊用途资源命名规范冲突的配置
致AWS官方:
- • 优化通过代理列举资源的API机制,消除对列表权限的依赖
- • 为服务关联角色信任策略添加困惑代理人防护,即使当前并非严格必需
- • 严格遵循最小权限原则收紧服务关联角色策略,避免使用非保留命名空间
- • 在服务关联角色策略中增加同账户访问限制
- • 排查并移除服务关联角色策略中可能导致权限提升的权限组合
致所有读者:
- • 远离毒品诱惑
您是否知道IAM角色名称必须全局唯一(与路径无关)?恭喜您坚持阅读至此,收获知识就是最好的回报。
引用链接
[1] 《Things you wish you didn’t need to know about AWS service-linked roles》: https://www.plerion.com/blog/about-aws-service-linked-roles
[2] 服务关联角色: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create-service-linked-role.html
[3] 关于S3存储桶的那些冷知识: https://www.plerion.com/blog/things-you-wish-you-didnt-need-to-know-about-s3
[4] 引导AWS服务: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html
[5] 以下是Organizations内的IAM Identity Center: https://docs.aws.amazon.com/singlesignon/latest/userguide/slrconcept.html
[6] 一张详尽的表格: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html#all_svcs
[7] amazonaws.com: http://amazonaws.com/
[8] 服务参考目录: https://docs.aws.amazon.com/service-authorization/latest/reference/service-reference.html
[9] 未公开AWS API探测工具: https://github.com/DataDog/undocumented-aws-api-hunter
[10] 本人整理的服务关联角色名称列表: https://gist.github.com/dagrz/08d067efe1594ebd9313d405f9687506
[11] 我原创的手工代码: https://github.com/dagrz/aws_pwn/blob/master/reconnaissance/validate_iam_principals.py
[12] Quiet Riot: https://github.com/righteousgambit/quiet-riot
[13] Roles: https://github.com/RyanJarv/roles
[14] 这篇技术博客: https://www.plerion.com/blog/what-do-hackers-know-about-your-aws-account
[15] 困惑代理人(confused deputy)问题: https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html
[16] AWS Transfer Family文档: https://docs.aws.amazon.com/transfer/latest/userguide/confused-deputy.html
[17] 最小权限原则: https://en.wikipedia.org/wiki/Principle_of_least_privilege
[18] Evidently: https://aws.amazon.com/blogs/aws/cloudwatch-evidently/
[19] AWS标签指南: https://aws.amazon.com/solutions/guidance/tagging-on-aws/
[20] Conditional Love: https://github.com/plerionhq/conditional-love
[21] 跨账户读取标签值: https://www.plerion.com/blog/conditional-love-for-aws-metadata-enumeration
[22] Panorama: https://aws.amazon.com/panorama/
[23] 可跨账户暴露的资源: https://github.com/SummitRoute/aws_exposable_resources
[24] 2016年编写的脚本: https://github.com/dagrz/aws_pwn/blob/master/elevation/bouncy_bouncy_cloudy_cloud.py
[25] 这份包含40多种方法的清单: https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/
交流群
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:云原生安全指北 Dubito《AWS服务关联角色的痛,希望你永远都不必懂》