Skip to content

Commit

Permalink
wip: initial access + airborne
Browse files Browse the repository at this point in the history
  • Loading branch information
ejohn20 committed Nov 12, 2024
1 parent c98eed4 commit 3264529
Show file tree
Hide file tree
Showing 20 changed files with 972 additions and 2 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/mkdocs.yaml
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
38 changes: 38 additions & 0 deletions .gitignore
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
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"exfiltrating"
]
}
7 changes: 5 additions & 2 deletions README.md
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.
13 changes: 13 additions & 0 deletions workbook/README.md
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
```
127 changes: 127 additions & 0 deletions workbook/docs/airborneio-24.md
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.
7 changes: 7 additions & 0 deletions workbook/docs/api-key.md
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:
139 changes: 139 additions & 0 deletions workbook/docs/css/custom.css
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);
}
Loading

0 comments on commit 3264529

Please sign in to comment.