-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
972 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
name: GitHub Pages | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
permissions: | ||
contents: write | ||
|
||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.x | ||
- uses: actions/cache@v2 | ||
with: | ||
key: ${{ github.ref }} | ||
path: .cache | ||
- run: | | ||
pip install mkdocs-material | ||
cd ./workbook | ||
mkdocs gh-deploy --force |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Local .terraform directories | ||
**/.terraform/* | ||
|
||
# .tfstate files | ||
*.tfstate | ||
*.tfstate.* | ||
|
||
# Crash log files | ||
crash.log | ||
|
||
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most | ||
# .tfvars files are managed as part of configuration and so should be included in | ||
# version control. | ||
# | ||
# example.tfvars | ||
|
||
# Ignore override files as they are usually used to override resources locally and so | ||
# are not checked in | ||
override.tf | ||
override.tf.json | ||
*_override.tf | ||
*_override.tf.json | ||
|
||
# Include override files you do wish to add to version control using negated pattern | ||
# | ||
# !example_override.tf | ||
|
||
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan | ||
# example: *tfplan* | ||
|
||
# macOS | ||
.DS_Store | ||
|
||
# mkdocs | ||
workbook/site/* | ||
|
||
# Node.js | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"cSpell.words": [ | ||
"exfiltrating" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
# hth-village-24 | ||
Hackers Teaching Hackers (HTH) 2024 - Kubernetes Village | ||
# Hackers Teaching Hackers (HTH) 2024 - Kubernetes Village | ||
|
||
Welcome to the Hackers Teaching Hackers (HTH) 2024 - Kubernetes Village. This repository contains all the instructions for completing the village. | ||
|
||
See the [HTH 2024 Kubernetes Village](https://pumasecurity.github.io/hth-village-24/) GitHub pages to get started. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# HTH Workshop Documentation | ||
|
||
The documentation in this directory is built using `mkdocs` and the `material` theme. | ||
|
||
You can view the public documentation at [https://pumasecurity.github.io/hth-village-24/](https://pumasecurity.github.io/hth-village-24/) | ||
|
||
## Mkdocs Deployment | ||
|
||
To deploy the docs, run the following command: | ||
|
||
```bash | ||
mkdocs gh-deploy --force | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Airborneio 24 Challenge | ||
|
||
The *Airborneio 24* challenge requires you to find a flag located on the Kubernetes node's file system. Without direct access to the file system and a view only Kubernetes role, you will need to find a misconfiguration in an existing resource to gain access to the flag. | ||
|
||
## Host Path Mount Misconfiguration | ||
|
||
Pods often need to store data on the file system as processes execute. Kubernetes supports many different volume types. The Kubernetes [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) volume mount provides persisted storage for a pod using a directory on the host node's filesystem. Often the most simple way to gain persisted storage, the [host path mount](https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Writable%20hostPath%20mount/){: target="_blank" rel="noopener"} can be a powerful attack vector for privilege escalation. | ||
|
||
Review the pod configurations in the `hth` namespace. Which pod is using a **hostPath** mount configuration? What directory on the host node's filesystem is being mounted into the pod? | ||
|
||
??? tip "Hint" | ||
|
||
- List the pods running in the `hth` namespace. | ||
|
||
```bash | ||
kubectl get pods -n hth | ||
``` | ||
|
||
!!! abstract "Expected Output" | ||
```bash | ||
NAME READY STATUS RESTARTS AGE | ||
api-randomid 1/1 Running 0 2d21h | ||
ui-randomid 1/1 Running 0 2d21h | ||
``` | ||
|
||
- Describe the configuration for each pod using the `kubectl describe pod` command. Search the output for the pod that has a **Volume** with a **Type** set to **HostPath**. The volume's **Path** is pointing to a directory on the node's file system that will be accessible from inside a pod running in the cluster. | ||
|
||
```bash | ||
kubectl describe pod -n hth ENTER_POD_NAME | ||
``` | ||
|
||
!!! abstract "Expected Output" | ||
```yaml hl_lines="2-4" | ||
Volumes: | ||
hth: | ||
Type: HostPath (bare host directory volume) | ||
Path: ????? | ||
HostPathType: DirectoryOrCreate | ||
``` | ||
|
||
- The same pod will have a **Mount** referencing the *hth* volume. The mount will specify that specifies the directory inside the container. | ||
|
||
!!! abstract "Expected Output" | ||
```yaml hl_lines="2" | ||
Mounts: | ||
????? from hth (rw) | ||
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-rgfww (ro) | ||
``` | ||
|
||
??? success "Answer" | ||
|
||
- With this knowledge, you have discovered a [host path mount](https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Writable%20hostPath%20mount/){: target="_blank" rel="noopener"} attack path to get from a compromised **api** pod to the node's filesystem. | ||
|
||
``` | ||
Pod: api-randomid | ||
Pod Mount Location: /mnt/hth/ | ||
Host Path Location: /opt/data/hth | ||
``` | ||
|
||
## Host Path Mount Privilege Escalation | ||
|
||
Given a scenario where the pod is compromised, an attacker can use the **hostPath** volume mount to gain unauthorized access data on the Kubernetes node. Use the `kubectl exec` command to obtain a shell on the compromised pod and exfiltrate the `airborneio-24` flag from the Kubernetes node's filesystem. | ||
|
||
??? tip "Hint" | ||
|
||
- Use the `kubectl exec` command to obtain a shell on the compromised pod. | ||
|
||
```bash | ||
kubectl exec --stdin --tty -n hth ENTER_POD_NAME -- /bin/bash | ||
``` | ||
|
||
|
||
!!! abstract "Expected Output" | ||
```bash | ||
root@api-randomid:/# | ||
``` | ||
|
||
- Once inside the pod, list the contents of the mount location. | ||
|
||
```bash | ||
ls -l ????? | ||
``` | ||
|
||
!!! abstract "Expected Output" | ||
```bash | ||
total 0 | ||
drwxr-xr-x. 2 root root 68 Nov 8 23:03 api | ||
drwxr-xr-x. 2 root root 27 Nov 8 23:03 secrets | ||
``` | ||
|
||
- List the contents of the directory to find the `airborneio-24` flag. | ||
|
||
```bash | ||
ls -l ?????/secrets/ | ||
``` | ||
|
||
!!! abstract "Expected Output" | ||
```bash | ||
-rw-r--r--. 1 root root 42 Nov 8 23:03 airborneio-24 | ||
``` | ||
|
||
- Use the `cat` command to read the contents of the `airborneio-24` file and retrieve the flag. | ||
|
||
- Run the following command to exit the shell and return to your local machine. | ||
|
||
```bash | ||
exit | ||
``` | ||
|
||
??? success "Answer" | ||
|
||
- The `airborneio-24` flag is located in the `/mnt/hth/secrets` directory on the container's filesystem. | ||
```bash | ||
cat /mnt/hth/secrets/airborneio-24 | ||
``` | ||
|
||
!!! abstract "Expected Output" | ||
```bash | ||
hth{?????} | ||
``` | ||
|
||
## Next Challenge | ||
|
||
Congratulations! You have identified a [host path mount](https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Writable%20hostPath%20mount/){: target="_blank" rel="noopener"} misconfiguration and exfiltrated the **Airborneio 24** flag from the Kubernetes node's file system. | ||
|
||
Continue to the [Shadowhawk Challenge](./shadowhawk.md) to learn how Kubernetes pod can inherit permissions from the underlying Kubernetes node. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# API Key Challenge | ||
|
||
## Introduction | ||
|
||
## Conclusion | ||
|
||
Congratualtions on completing the API Key Challenge! You have successfully completed the following objectives: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
:root { | ||
/* Cloud */ | ||
--primary-color: #ffA500; | ||
--secondary-color: #ffA500; | ||
--primary-text-color: #ffffff; | ||
--secondary-text-color: #f9f3d8; | ||
|
||
/* Default Colors from Material */ | ||
--md-default-fg-color: hsla(0, 0%, 0%, 0.87); | ||
--md-default-fg-color--light: hsla(0, 0%, 0%, 0.54); | ||
--md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32); | ||
--md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07); | ||
--md-default-bg-color: hsla(0, 0%, 100%, 1); | ||
--md-default-bg-color--light: hsla(0, 0%, 100%, 0.7); | ||
--md-default-bg-color--lighter: hsla(0, 0%, 100%, 0.3); | ||
--md-default-bg-color--lightest: hsla(0, 0%, 100%, 0.12); | ||
|
||
/* Primary color shades */ | ||
--md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); | ||
--md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1); | ||
--md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1); | ||
--md-primary-bg-color: hsla(0, 0%, 100%, 1); | ||
--md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); | ||
|
||
/* Accent color shades */ | ||
--md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1); | ||
--md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1); | ||
--md-accent-bg-color: hsla(0, 0%, 100%, 1); | ||
--md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); | ||
} | ||
|
||
.md-typeset, | ||
.md-typeset code :not(h1, h2, h3, h4, h5), | ||
.md-typeset abstract, | ||
.md-typeset .admonition, | ||
.md-typeset details, | ||
.md-typeset .footnote, | ||
.md-typeset :is(.admonition, details) { | ||
font-size: 0.9rem; | ||
} | ||
|
||
.md-typeset :is(.emojione, .twemoji, .gemoji) { | ||
border-style: none; | ||
display: inline-flex; | ||
height: 1.125em; | ||
vertical-align: text-top; | ||
} | ||
|
||
/* | ||
Aviata: | ||
Light Blue – 51, 105, 148 - #336994 | ||
Dark Blue – 20, 38, 45 - #14262D | ||
Cream – 249, 243, 216 - #F9F3D8 | ||
Orange – 245, 130, 32 - #F58220 | ||
White – 255, 255, 255 - #FFFFFF | ||
*/ | ||
[data-md-color-scheme=aviata-dark] { | ||
/* --md-hue: 232; */ | ||
--md-default-fg-color: #f9f3d8; | ||
--md-default-fg-color--light: hsla(232, 75%, 90%, 0.62); | ||
--md-default-fg-color--lighter: hsla(232, 75%, 90%, 0.32); | ||
--md-default-fg-color--lightest: hsla(232, 75%, 90%, 0.12); | ||
--md-default-bg-color: #2b4b60; | ||
/* --md-default-bg-color: #14262d; /* Official */ | ||
--md-default-bg-color--light: hsla(232, 15%, 21%, 0.54); | ||
--md-default-bg-color--lighter: hsla(232, 15%, 21%, 0.26); | ||
--md-default-bg-color--lightest: hsla(232, 15%, 21%, 0.07); | ||
|
||
--md-code-fg-color: hsla(232, 18%, 86%, 1); | ||
--md-code-bg-color: hsla(232, 15%, 15%, 1); | ||
|
||
--md-code-hl-color: rgba(66, 135, 255, .15); | ||
--md-code-hl-number-color: #e6695b; | ||
--md-code-hl-special-color: #f06090; | ||
--md-code-hl-function-color: #c973d9; | ||
--md-code-hl-constant-color: #9383e2; | ||
--md-code-hl-keyword-color: #6791e0; | ||
--md-code-hl-string-color: #2fb170; | ||
--md-code-hl-name-color: var(--md-code-fg-color); | ||
--md-code-hl-operator-color: var(--md-default-fg-color--light); | ||
--md-code-hl-punctuation-color: var(--md-default-fg-color--light); | ||
--md-code-hl-comment-color: var(--md-default-fg-color--light); | ||
--md-code-hl-generic-color: var(--md-default-fg-color--light); | ||
--md-code-hl-variable-color: var(--md-default-fg-color--light); | ||
|
||
--md-typeset-color: var(--md-default-fg-color); | ||
--md-typeset-a-color: var(--md-primary-fg-color); | ||
--md-typeset-mark-color: rgba(66, 135, 255, .3); | ||
--md-typeset-kbd-color: hsla(232, 15%, 94%, 0.12); | ||
--md-typeset-kbd-accent-color: hsla(232, 15%, 94%, 0.2); | ||
--md-typeset-kbd-border-color: hsla(232, 15%, 14%, 1); | ||
--md-typeset-table-color: hsla(232, 75%, 95%, 0.12); | ||
|
||
--md-admonition-bg-color: hsla(232, 0%, 100%, 0.025); | ||
--md-footer-bg-color: hsla(232, 15%, 12%, 0.87); | ||
--md-footer-bg-color--dark: hsla(232, 15%, 10%, 1); | ||
} | ||
|
||
/* Light theme (default) */ | ||
[data-md-color-scheme=aviata-light] { | ||
|
||
--md-code-fg-color: hsla(200, 18%, 26%, 1); | ||
--md-code-bg-color: hsla(0, 0%, 96%, 1); | ||
|
||
--md-code-hl-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); | ||
--md-code-hl-number-color: hsla(0, 67%, 50%, 1); | ||
--md-code-hl-special-color: hsla(340, 83%, 47%, 1); | ||
--md-code-hl-function-color: hsla(291, 45%, 50%, 1); | ||
--md-code-hl-constant-color: hsla(250, 63%, 60%, 1); | ||
--md-code-hl-keyword-color: hsla(219, 54%, 51%, 1); | ||
--md-code-hl-string-color: hsla(150, 63%, 30%, 1); | ||
--md-code-hl-name-color: var(--md-code-fg-color); | ||
--md-code-hl-operator-color: var(--md-default-fg-color--light); | ||
--md-code-hl-punctuation-color: var(--md-default-fg-color--light); | ||
--md-code-hl-comment-color: var(--md-default-fg-color--light); | ||
--md-code-hl-generic-color: var(--md-default-fg-color--light); | ||
--md-code-hl-variable-color: var(--md-default-fg-color--light); | ||
|
||
--md-typeset-color: var(--md-default-fg-color); | ||
--md-typeset-a-color: var(--md-primary-fg-color); | ||
--md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); | ||
--md-typeset-del-color: hsla(6, 90%, 60%, 0.15); | ||
--md-typeset-ins-color: hsla(150, 90%, 44%, 0.15); | ||
--md-typeset-kbd-color: hsla(0, 0%, 98%, 1); | ||
--md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1); | ||
--md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1); | ||
--md-typeset-table-color: hsla(0, 0%, 0%, 0.12); | ||
|
||
--md-admonition-fg-color: var(--md-default-fg-color); | ||
--md-admonition-bg-color: var(--md-default-bg-color); | ||
|
||
--md-footer-fg-color: hsla(0, 0%, 100%, 1); | ||
--md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7); | ||
--md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3); | ||
--md-footer-bg-color: hsla(0, 0%, 0%, 0.87); | ||
--md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32); | ||
|
||
--md-typeset-h4-color: hsla(0, 0%, 0%, 0.87); | ||
} |
Oops, something went wrong.