Hi readers, here we will see how someone knowing/guessing role arn created for GitHub actions can escalate privileges.
Note: Now this has been fixed! If you try creating an OIDC connect it asks for GitHub organization.
Creating scenario-
Let’s assume we want GitHub actions to perform certain operations in our AWS account. For this example, we will be listing s3 buckets using GitHub actions. Steps-
- Adding GitHub as an Identity provider-
a) Goto Identity provider option in IAM.
b) Add identity provider with type OpenIDConnect.
c) Provider URL: https://token.actions.githubusercontent.com
d) Click get thumbprint.
e) Add Audience as sts.amazonaws.com
f) Click add provider
2. Creating and attaching a new role to this provider-
a) Creating managed policy with the following permissions-
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:List*"
],
"Resource": "*"
}
]
}
b) Go to the identity provider and click assign role-
c)
d) Attach the newly created policy “github_list_s3” to the role.
e) Click next, choose the name for the role and click create role-
f) Goto the role and check the trust relationship-
Note: This is created by default and this can be abused! We will see how to do that below.
3. Creating GitHub action-
a) Create a .github directory in the repository
b) Create another directory named workflows within this.
c) Create a new file yaml file which will contain actions we need to perform via GitHub action.
d) Contents of YAML-
name: 'Aws testing'
# The workflow should only trigger on pull requests to the main branch
on:
workflow_dispatch:
# Required to get the ID Token that will be used for OIDC
permissions:
id-token: write
jobs:
read-dev:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: us-east-1
role-to-assume: arn:aws:iam::864154101007:role/github_action
role-session-name: OIDCSession
- run: aws s3 ls
shell: bash
- run: aws sts get-caller-identity
shell: bash
We specified which role to assume.
and we are running cli commands “aws s3 ls” and “aws sts get-caller-identity”
e) Commit and push the changes to the gihub repo.
4. Running the action-
a) Go to action, choose the workflow and click “Run workflow”.
and we were able to list the s3 bucket pswalia1u which is the only one currently present.
Abusing this scenario
Now the problem with this is if anyone knows or is able to guess the role arn which is being assumed by GitHub action “arn:aws:iam::864154101007:role/github_action” in this case, then he can perform the same action(listing s3 bucket) using his own GitHub action.
The easiest way to abuse this is to fork someone’s repository with GitHub actions performing tasks in aws. ☠️
For solving this problem we need to make modifications to the trust relationship for role “arn:aws:iam::864154101007:role/github_action”:
We need to modify the default one
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::864154101007:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}
]
}
to
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::864154101007:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": [
"repo:pswalia5u/actions_testing:pull_request",
"repo:pswalia5u/actions_testing:ref:refs/heads/main"
],
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}
]
}
We added “USER_NAME/REPOSITORY_NAME”
Thanks for reading!
References:
https://www.eliasbrange.dev/posts/secure-aws-deploys-from-github-actions-with-oidc/
https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions