Skip to content

Commit 5414759

Browse files
authored
Merge branch 'master' into aztesting
2 parents fff47bb + c0ee3fc commit 5414759

17 files changed

Lines changed: 760 additions & 62 deletions

File tree

.github/workflows/docker-terraform-compatibility.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# This action verifies compatibility between the terraform version used in Dockerfile and scenarios.
2+
# It also does a test build of the Dockerfile to verify nothing is broken.
3+
14
name: Docker Terraform validation
25

36
on:
@@ -135,3 +138,32 @@ jobs:
135138
}
136139
echo "✔️ Success: ${{ matrix.scenario }}"
137140
echo "::endgroup::"
141+
142+
verify-docker-build:
143+
runs-on: ubuntu-latest
144+
steps:
145+
146+
# Checkout the repository
147+
- name: Check out repository
148+
uses: actions/checkout@v3
149+
150+
# Set up Docker Buildx for multi-architecture builds
151+
- name: Set up Docker Buildx
152+
uses: docker/setup-buildx-action@v2
153+
154+
# Build the Docker image for multiple architectures
155+
- name: Build Docker Image amd64
156+
run: |
157+
docker buildx build \
158+
--platform linux/amd64 \
159+
--file Dockerfile \
160+
--tag rhinosecuritylabs/cloudgoat:latest \
161+
--load .
162+
163+
- name: Build Docker Image arm64
164+
run: |
165+
docker buildx build \
166+
--platform linux/arm64 \
167+
--file Dockerfile \
168+
--tag rhinosecuritylabs/cloudgoat:latest \
169+
--load .
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Once Release PR merges
2+
# Tag as release
3+
# Release
4+
# Publish
5+
6+
name: Tag and Publish
7+
8+
on:
9+
pull_request:
10+
types:
11+
- closed # Only trigger when a PR is merged
12+
branches:
13+
- master # Only trigger when merged into master
14+
15+
jobs:
16+
tag_and_publish:
17+
if: startsWith(github.event.pull_request.head.ref, 'release-v') # Only run for release PRs
18+
runs-on: ubuntu-latest
19+
environment: pypi
20+
permissions:
21+
id-token: write
22+
contents: write
23+
24+
steps:
25+
- name: Checkout Repository
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
29+
30+
- name: Set up Python
31+
uses: actions/setup-python@v5
32+
with:
33+
python-version: "3.10"
34+
35+
- name: Install Poetry
36+
run: pip install poetry
37+
38+
- name: Install Dependencies
39+
run: poetry install
40+
41+
- name: Get Version from pyproject.toml
42+
id: get_version
43+
run: |
44+
VERSION=$(poetry version -s)
45+
echo "VERSION=$VERSION" >> $GITHUB_ENV
46+
47+
- name: Tag the Release
48+
run: |
49+
git config --global user.name "GitHub Actions"
50+
git config --global user.email "actions@github.com"
51+
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
52+
git tag "v${{ env.VERSION }}"
53+
git push origin "refs/tags/v${{ env.VERSION }}"
54+
55+
- name: Create GitHub Release
56+
uses: softprops/action-gh-release@v2
57+
with:
58+
tag_name: v${{ env.VERSION }}
59+
name: Release v${{ env.VERSION }}
60+
draft: true
61+
prerelease: false
62+
generate_release_notes: true
63+
64+
- name: Build package
65+
run: poetry build
66+
67+
- name: Publish to PyPI
68+
uses: pypa/gh-action-pypi-publish@release/v1
69+
70+
# Set up Docker Buildx for multi-architecture builds
71+
- name: Set up Docker Buildx
72+
uses: docker/setup-buildx-action@v2
73+
74+
# Log in to Docker Hub using secrets
75+
- name: Log in to Docker Hub
76+
uses: docker/login-action@v2
77+
with:
78+
username: ${{ secrets.DOCKER_USER }}
79+
password: ${{ secrets.DOCKER_PASSWORD }}
80+
81+
# Build and push the Docker image for multiple architectures
82+
- name: Build and Push Docker Image
83+
run: |
84+
VERSION=${{ env.VERSION }}
85+
docker buildx build \
86+
--platform linux/amd64,linux/arm64 \
87+
--file Dockerfile \
88+
--tag rhinosecuritylabs/cloudgoat:$VERSION \
89+
--tag rhinosecuritylabs/cloudgoat:latest \
90+
--push .

.github/workflows/release.yml

Lines changed: 77 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,82 @@
1-
name: Release
1+
# This is triggered manually.
2+
# This will bump the version and open a release pull request
3+
# Once the PR is accepted finish-release runs.
4+
25

3-
on:
4-
push:
5-
branches:
6-
- main
6+
name: Release
77

8+
on:
9+
workflow_dispatch:
10+
inputs:
11+
SemVer_level:
12+
type: choice
13+
description: Which SemVer to bump
14+
options:
15+
- major
16+
- minor
17+
- patch
18+
default: patch
19+
SemVer_version:
20+
type: string
21+
description: "Specify an exact version (leave empty to auto-bump)"
22+
default: ""
23+
824
jobs:
9-
release:
25+
create_release_branch:
1026
runs-on: ubuntu-latest
1127
steps:
12-
- name: Checkout Repository
13-
uses: actions/checkout@v4
14-
with:
15-
fetch-depth: 0 # Required for versioning
16-
17-
- name: Set up Python
18-
uses: actions/setup-python@v5
19-
with:
20-
python-version: "3.10"
21-
22-
- name: Install Poetry
23-
run: pip install poetry
24-
25-
- name: Install Dependencies
26-
run: poetry install
27-
28-
- name: Run Tests
29-
run: poetry run pytest # Adjust if needed
30-
31-
- name: Bump Version
32-
id: bump_version
33-
run: |
34-
poetry version patch # Change to minor/major if needed
35-
echo "VERSION=$(poetry version -s)" >> $GITHUB_ENV
36-
37-
- name: Commit & Tag New Version
38-
run: |
39-
git config --global user.name "GitHub Actions"
40-
git config --global user.email "actions@github.com"
41-
git add pyproject.toml
42-
git commit -m "chore(release): bump version to $VERSION"
43-
git tag "v$VERSION"
44-
git push origin main --tags
45-
46-
- name: Create GitHub Release
47-
uses: softprops/action-gh-release@v2
48-
with:
49-
tag_name: v${{ env.VERSION }}
50-
name: Release v${{ env.VERSION }}
51-
draft: true
52-
prerelease: false
53-
generate_release_notes: true
54-
55-
- name: Publish to PyPI
56-
env:
57-
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
58-
run: poetry publish --build
28+
- name: Checkout Repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 0
32+
33+
- name: Set up Python
34+
uses: actions/setup-python@v5
35+
with:
36+
python-version: '3.10'
37+
38+
- name: Install poetry
39+
run: pip install poetry
40+
41+
- name: Install dependencies
42+
run: poetry install
43+
44+
- name: Determine Version
45+
id: determine_version
46+
run: |
47+
if [ -n "${{ github.event.inputs.SemVer_version }}" ]; then
48+
VERSION=${{ github.event.inputs.SemVer_version }}
49+
poetry version "$VERSION"
50+
else
51+
poetry version ${{ github.event.inputs.SemVer_level }}
52+
VERSION=$(poetry version -s)
53+
fi
54+
sed -i "s/cloudgoat.version=\".*\"/cloudgoat.version=\"$VERSION\"/" Dockerfile
55+
echo "VERSION=$VERSION" >> $GITHUB_ENV
56+
echo "::set-output name=VERSION::$VERSION"
57+
58+
- name: Create Release Branch
59+
run: |
60+
git checkout -b release-v${{ env.VERSION }}
61+
62+
- name: Commit Version Change
63+
run: |
64+
git config --global user.name "GitHub Actions"
65+
git config --global user.email "actions@github.com"
66+
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
67+
git add .
68+
git commit -m "chore(release): bump version to ${VERSION}"
69+
git push origin release-v${{ env.VERSION }}
70+
71+
- name: Create Pull Request via CLI
72+
run: |
73+
gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}"
74+
gh pr create \
75+
--base master \
76+
--head release-v${{ env.VERSION }} \
77+
--title "Release v${{ env.VERSION }}" \
78+
--body "Automated release PR for version v${{ env.VERSION }}" \
79+
--draft=false
80+
env:
81+
GH_PAT: ${{ secrets.GITHUB_TOKEN }}
82+
GH_REPO: ${{ github.repository }}

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
FROM python:3.12-alpine
22

33
LABEL maintainer="Rhino Assessment Team <cloudgoat@rhinosecuritylabs.com>"
4-
LABEL cloudgoat.version="2.0.0"
4+
LABEL cloudgoat.version="2.0.1"
55

66
# Install bash, necessary tools, AWS CLI, and Terraform in a single layer
77
RUN apk add --no-cache \

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,19 @@ docker run -it -v ~/.aws:/root/.aws/ rhinosecuritylabs/cloudgoat:latest
111111
<details open>
112112
<summary><strong>Easy</strong></summary>
113113

114+
---
115+
116+
### beanstalk_secrets (Easy)
117+
`cloudgoat create beanstalk_secrets`
118+
119+
In this scenario, you are provided with low-privileged AWS credentials that grant limited access to Elastic Beanstalk. Your task is to enumerate the Elastic Beanstalk environment and discover misconfigured environment variables containing secondary credentials. Using these secondary credentials, you can enumerate IAM permissions to eventually create an access key for an administrator user. With these admin privileges, you retrieve the final flag stored in AWS Secrets Manager.
120+
121+
[Visit Scenario Page.](cloudgoat/scenarios/beanstalk_secrets/README.md)
122+
123+
Contributed by Tyler Ramsbey
124+
125+
---
126+
114127
### sns_secrets (Easy)
115128
`cloudgoat create sns_secrets`
116129

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Scenario: beanstalk_secrets
2+
3+
**Size:** Medium
4+
5+
**Difficulty:** Moderate
6+
7+
**Command:** `./cloudgoat.py create beanstalk_secrets`
8+
9+
## Scenario Resources
10+
11+
- 1 VPC
12+
- 1 Elastic Beanstalk Environment
13+
- 1 IAM Low-Privilege User
14+
- 1 IAM Secondary User
15+
- 1 AWS Secrets Manager Secret
16+
17+
## Scenario Start(s)
18+
19+
1. AWS Access Key and Secret Key for the low-privileged user.
20+
21+
## Scenario Goal(s)
22+
23+
Retrieve the final flag from AWS Secrets Manager by escalating privileges from a low-privileged user to an administrator account.
24+
25+
## Summary
26+
27+
In this scenario, you are provided with low-privileged AWS credentials that grant limited access to Elastic Beanstalk. Your task is to enumerate the Elastic Beanstalk environment and discover misconfigured environment variables containing secondary credentials. Using these secondary credentials, you can enumerate IAM permissions to eventually create an access key for an administrator user. With these admin privileges, you retrieve the final flag stored in AWS Secrets Manager.
28+
29+
## Exploitation Route
30+
31+
32+
![Flowcharts](https://github.com/user-attachments/assets/cf16f767-d8b3-436f-9812-c2d06ea0876b)
33+
34+
35+
36+
## Walkthrough - Elastic Beanstalk Secrets
37+
38+
1. Start by using the provided low-privileged AWS credentials.
39+
2. Verify access with `aws sts get-caller-identity`.
40+
3. Enumerate Elastic Beanstalk applications and environments using Pacu’s `beanstalk__enum` module.
41+
4. Identify the EB environment with misconfigured environment variables that store secondary credentials.
42+
5. Use the secondary credentials to enumerate IAM resources and permissions.
43+
6. Discover that you can create an access key for an administrator user using the `iam:CreateAccessKey` permission.
44+
7. Generate an admin access key and take over the account.
45+
8. Finally, use the admin privileges to retrieve the final flag from AWS Secrets Manager.
46+
47+
A detailed cheat sheet & walkthrough for this route is available [here](./cheat_sheet.md).

0 commit comments

Comments
 (0)