AWS - IAM & STS 인증되지 않은 열거

Reading time: 5 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

계정에서 역할 및 사용자 이름 열거

Assume Role Brute-Force

caution

이 기술은 더 이상 작동하지 않습니다 — 역할이 존재하든 아니든 항상 다음 오류가 반환됩니다:

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::947247140022:user/testenv is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::429217632764:role/account-balanceasdas

다음 명령으로 확인할 수 있습니다:

aws sts assume-role --role-arn arn:aws:iam::412345678909:role/superadmin --role-session-name s3-access-example

필요한 권한 없이 assume a role을 시도하면 AWS 오류 메시지가 발생합니다. 예를 들어, 권한이 없으면 AWS는 다음과 같은 응답을 반환할 수 있습니다:

ruby
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::012345678901:user/MyUser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS

이 메시지는 role의 존재를 확인해 주지만, 그 role의 assume role policy가 귀하가 해당 role을 assume하는 것을 허용하지 않는다는 것을 나타냅니다. 반면, assume a non-existent role leads to a different error:

less
An error occurred (AccessDenied) when calling the AssumeRole operation: Not authorized to perform sts:AssumeRole

흥미롭게도, 이 방법은 존재하는 역할과 존재하지 않는 역할을 구별하는 것이 서로 다른 AWS 계정 간에도 적용됩니다. 유효한 AWS account ID와 목표 단어 목록(wordlist)이 있으면, 계정에 존재하는 역할을 별다른 제약 없이 열거할 수 있습니다.

You can use this script to enumerate potential principals abusing this issue.

Trust Policies: Brute-Force Cross Account roles and users

Configuring or updating an IAM role's trust policy involves defining which AWS resources or services are permitted to assume that role and obtain temporary credentials. If the specified resource in the policy exists, the trust policy saves successfully. However, if the resource does not exist, an error is generated, indicating that an invalid principal was provided.

warning

해당 리소스에 cross account role 또는 user를 지정할 수 있다는 점에 유의하세요:

  • arn:aws:iam::acc_id:role/role_name
  • arn:aws:iam::acc_id:user/user_name

이것은 정책 예시입니다:

json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::216825089941:role/Test"
},
"Action": "sts:AssumeRole"
}
]
}

GUI

다음은 존재하지 않는 역할을 사용할 때 나타나는 오류입니다. 해당 역할이 존재하면, 정책은 아무런 오류 없이 저장됩니다. (이 오류는 업데이트 시 발생하지만, 생성 시에도 동일하게 적용됩니다)

CLI

bash
### You could also use: aws iam update-assume-role-policy
# When it works
aws iam create-role --role-name Test-Role --assume-role-policy-document file://a.json
{
"Role": {
"Path": "/",
"RoleName": "Test-Role",
"RoleId": "AROA5ZDCUJS3DVEIYOB73",
"Arn": "arn:aws:iam::947247140022:role/Test-Role",
"CreateDate": "2022-05-03T20:50:04Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::316584767888:role/account-balance"
},
"Action": [
"sts:AssumeRole"
]
}
]
}
}
}

# When it doesn't work
aws iam create-role --role-name Test-Role2 --assume-role-policy-document file://a.json
An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: Invalid principal in policy: "AWS":"arn:aws:iam::316584767888:role/account-balanceefd23f2"

이 과정을 https://github.com/carlospolop/aws_tools로 자동화할 수 있습니다

  • bash unauth_iam.sh -t user -i 316584767888 -r TestRole -w ./unauth_wordlist.txt

또는 Pacu 사용:

  • run iam__enum_users --role-name admin --account-id 229736458923 --word-list /tmp/names.txt
  • run iam__enum_roles --role-name admin --account-id 229736458923 --word-list /tmp/names.txt
  • 예제에서 사용된 admin role은 pacu가 열거를 위해 필요한 정책을 생성하기 위해 가장하여 사용하는 귀하의 계정 내 role입니다

Privesc

만약 role이 잘못 구성되어 누구나 이를 assume할 수 있도록 허용된 경우:

json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole"
}
]
}

공격자는 단순히 해당 role을 assume할 수 있다.

타사 OIDC Federation

당신이 Github Actions workflowAWS 내부의 role에 접근하는 것을 읽을 수 있게 되었다고 가정해보자.
이 신뢰 설정은 다음과 같은 trust policy를 가진 role에 대한 접근 권한을 부여할 수 있다:

json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<acc_id>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}
]
}

이 신뢰 정책은 올바를 수 있지만, 더 많은 조건의 부재 때문에 신뢰하지 않아야 합니다.
이는 이전 역할이 ANYONE from Github Actions에 의해 맡겨질 수 있기 때문입니다! 조건에는 org name, repo name, env, brach 등도 지정해야 합니다...

또 다른 잠재적 잘못된 구성은 다음과 같이 조건을 추가하는 것입니다:

json
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:org_name*:*"
}

참고: wildcard (*)는 colon (:) 앞에 옵니다. 예를 들어 org_name1 같은 org를 생성하고 Github Action에서 assume the role할 수 있습니다.

참고

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기