Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Challenge 53: k8s debug container sidecars #1833

Merged
merged 42 commits into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a1c468f
updated binaries
commjoen Feb 22, 2025
30a3dce
Added executables
commjoen Feb 22, 2025
0c937f5
Updated dockerfile
commjoen Feb 22, 2025
3219594
Merge branch 'master' into not-to-be-merged-pastekitoo-test
commjoen Feb 22, 2025
80251fb
added initial deployment for cahllenge52, now sidecar to add
commjoen Feb 24, 2025
bb740ad
Merge branch 'master' into not-to-be-merged-pastekitoo-test
commjoen Mar 4, 2025
af8be9e
Merge branch 'master' into not-to-be-merged-pastekitoo-test
commjoen Mar 7, 2025
c63e4bd
have sidecar copying binary
commjoen Mar 7, 2025
3dc4e0d
added updated binaries
commjoen Mar 8, 2025
28cb549
now make hte container arm/x84 compatible
commjoen Mar 8, 2025
88b0951
Merge branch 'OWASP:master' into Pastekitoo-PR-week1
Pastekitoo Mar 8, 2025
6406735
Building of the challenge53 with the documentation need to be tested …
Mar 8, 2025
b708b6b
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Mar 8, 2025
c1b4309
Merge branch 'OWASP:master' into Pastekitoo-PR-week1
Pastekitoo Mar 8, 2025
fe376fa
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Mar 8, 2025
3e04b57
add k8s setup
commjoen Mar 9, 2025
7af2838
add it to minikube github tests
commjoen Mar 9, 2025
f34055d
Merge branch 'OWASP:master' into Pastekitoo-PR-week1
Pastekitoo Mar 10, 2025
913477f
Update src/main/java/org/owasp/wrongsecrets/challenges/kubernetes/Cha…
Pastekitoo Mar 10, 2025
5115fc5
Update src/main/resources/wrong-secrets-configuration.yaml
Pastekitoo Mar 10, 2025
01ddd84
Update src/main/resources/wrong-secrets-configuration.yaml
Pastekitoo Mar 10, 2025
7b0175d
Update src/main/resources/wrong-secrets-configuration.yaml
Pastekitoo Mar 10, 2025
bf01fc6
Update src/main/resources/wrong-secrets-configuration.yaml
Pastekitoo Mar 10, 2025
d17f1b1
Merge branch 'challenge-53-owasp' into Pastekitoo-PR-week1
Pastekitoo Mar 10, 2025
3a512c6
rename challenge52 to challenge53
Pastekitoo Mar 10, 2025
72e3feb
Update Challenge53Test.java
Pastekitoo Mar 10, 2025
d79fd6b
Update Challenge53.java
Pastekitoo Mar 10, 2025
f41e13d
adding binaries in ressources folder
Pastekitoo Mar 10, 2025
7041b4e
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Mar 10, 2025
3c360c0
Update Challenge53Test.java
Pastekitoo Mar 10, 2025
668c394
Update Challenge53Test.java
Pastekitoo Mar 10, 2025
78131d1
Update ChallengesControllerWithPresetKubernetesValuesTest.java
Pastekitoo Mar 10, 2025
a7a0d69
Update Challenge53Test.java
Pastekitoo Mar 10, 2025
22c0c53
Update Challenge53Test.java
Pastekitoo Mar 10, 2025
17269ae
Update challenge53_hint.adoc
Pastekitoo Mar 10, 2025
f3e39ba
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Mar 10, 2025
1d9ca01
Merge branch 'OWASP:master' into Pastekitoo-PR-week1
Pastekitoo Mar 10, 2025
8bb0bcc
Update Challenge53Test.java
commjoen Mar 11, 2025
660963c
remove not required binaries and have smarter copying for container c…
commjoen Mar 11, 2025
158393a
Merge branch 'master' into Pastekitoo-PR-week1
commjoen Mar 11, 2025
2bf773d
make the security policies tighter and fix entrypoint
commjoen Mar 11, 2025
dbfb407
Merge branch 'OWASP:master' into Pastekitoo-PR-week1
Pastekitoo Mar 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/scripts/docker-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,12 @@ create_containers() {
docker buildx build --platform linux/amd64,linux/arm64 -t jeroenwillemsen/wrongsecrets-desktop:latest -f Dockerfile_webdesktop --secret id=mysecret,env=SECRET_VALUE --push .
docker buildx build --platform linux/amd64,linux/arm64 -t jeroenwillemsen/wrongsecrets-desktop-k8s:$tag -f Dockerfile_webdesktopk8s --secret id=mysecret,env=SECRET_VALUE --push .
docker buildx build --platform linux/amd64,linux/arm64 -t jeroenwillemsen/wrongsecrets-desktop-k8s:latest -f Dockerfile_webdesktopk8s --secret id=mysecret,env=SECRET_VALUE --push .
cd k8s/challenge53
cp ../../src/main/resources/executables/wrongsecrets-challenge53-* ./executables
docker buildx build --platform linux/amd64,linux/arm64 -t jeroenwillemsen/wrongsecrets-challenge53:$tag -f Dockerfile --push .
docker buildx build --platform linux/amd64,linux/arm64 -t jeroenwillemsen/wrongsecrets-challenge53-debug:$tag -f Dockerfile.debug --push .
rm ./executables/wrongsecrets-challenge53-*
cd ../..
cd .github/scripts
elif [[ "$script_mode" == "test" ]]; then
docker buildx build -t jeroenwillemsen/wrongsecrets:$tag --build-arg "$buildarg" --build-arg "PORT=8081" --build-arg "argBasedVersion=$tag" --build-arg "spring_profile=without-vault" --load --secret id=mysecret,env=SECRET_VALUE ./../../.
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/minikube-k8s-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
kubectl apply -f k8s/secrets-secret.yml
kubectl apply -f k8s/challenge33.yml
kubectl apply -f k8s/secret-challenge-deployment.yml
kubectl apply -f k8s/challenge53/secret-challenge53.yml
golivecounter=0
while [[ $(kubectl get pods -l app=secret-challenge -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]];
do
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ src/main/resources/executables/decrypt/decrypt
src/main/resources/executables/wrongsecrets-dotnet
src/main/resources/executables/wrongsecrets-dotnet*

# Challenge 59
k8s/challenge53/executables/wrongsecrets-challenge53-c
k8s/challenge53/executables/wrongsecrets-challenge53-c*

# Node JS
js/node/
js/node_modules/
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ The K8S setup currently is based on using Minikube for local fun. You can use th
kubectl apply -f k8s/secrets-config.yml
kubectl apply -f k8s/secrets-secret.yml
kubectl apply -f k8s/challenge33.yml
kubectl apply -f k8s/challenge53/secret-challenge53.yml
echo "Setting up the bitnami sealed secret controler"
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.27.0/controller.yaml
kubectl apply -f k8s/sealed-secret-controller.yaml
Expand Down
3 changes: 3 additions & 0 deletions aws/k8s-vault-aws-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ kubectl create -f ../k8s/sealed-challenge48.json
echo "finishing up the sealed secret controler part"
echo "do you need to decrypt and/or handle things for the sealed secret use kubeseal"

echo "Setting up challenge 53"
kubectl apply -f ../k8s/challenge53/secret-challenge53.yml

kubectl get secrets | grep 'funnystuff' &>/dev/null
if [ $? == 0 ]; then
echo "secrets secret is already installed"
Expand Down
3 changes: 3 additions & 0 deletions azure/k8s-vault-azure-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ kubectl create -f ../k8s/sealed-challenge48.json
echo "finishing up the sealed secret controler part"
echo "do you need to decrypt and/or handle things for the sealed secret use kubeseal"

echo "Setting up challenge 53"
kubectl apply -f ../k8s/challenge53/secret-challenge53.yml

kubectl get secrets | grep 'funnystuff' &>/dev/null
if [ $? == 0 ]; then
echo "secrets secret is already installed"
Expand Down
3 changes: 3 additions & 0 deletions gcp/k8s-vault-gcp-ingress-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ else
kubectl apply -f ../k8s/challenge33.yml
fi

echo "Setting up challenge 53"
kubectl apply -f ../k8s/challenge53/secret-challenge53.yml

source ../scripts/install-vault.sh

echo "Add secrets manager driver to repo"
Expand Down
2 changes: 2 additions & 0 deletions k8s-vault-minikube-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ echo "Setting up the bitnami sealed secret controler"
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.28.0/controller.yaml
kubectl apply -f k8s/sealed-secret-controller.yaml
kubectl apply -f k8s/main.key
echo "Setting up challenge 53"
kubectl apply -f k8s/challenge53/secret-challenge53.yml
kubectl delete pod -n kube-system -l name=sealed-secrets-controller
kubectl create -f k8s/sealed-challenge48.json
echo "finishing up the sealed secret controler part"
Expand Down
8 changes: 8 additions & 0 deletions k8s/challenge53/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ubuntu:25.04
RUN useradd -m -u 2000 wrongsecrets

COPY --chown=wrongsecrets executables/ /home/wrongsecrets/

#use `docker buildx build --platform linux/amd64,linux/arm64 -t jeroenwillemsen/wrongsecrets-challenge53:4 -f Dockerfile --push .` to push
# use `docker run jeroenwillemsen/wrongsecrets-challenge53:5` to run it
CMD ["./home/wrongsecrets/start-on-arch.sh"]
8 changes: 8 additions & 0 deletions k8s/challenge53/Dockerfile.debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ubuntu:25.04

RUN useradd -m -u 2000 wrongsecrets

# Install gdb and others tools
RUN apt update && apt install -y gdb strace lsof procps

CMD ["/bin/bash"]
17 changes: 17 additions & 0 deletions k8s/challenge53/debug-container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsUser: 2000
runAsNonRoot: true
allowPrivilegeEscalation: false
containers:
- name: app
image: jeroenwillemsen/wrongsecrets-challenge53-debug:1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
## TODO: update container image and user
15 changes: 15 additions & 0 deletions k8s/challenge53/executables/start-on-arch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# Detect the architecture
ARCH=$(uname -m)

# Check if the system is running on Linux ARM
if [[ "$ARCH" == "arm" || "$ARCH" == "aarch64" ]]; then
echo "Running on Linux ARM architecture"
# Start the ARM binary
./home/wrongsecrets/wrongsecrets-challenge53-c-linux-arm
else
echo "Running on non-ARM architecture"
# Start the non-ARM binary
./home/wrongsecrets/wrongsecrets-challenge53-c-linux
fi
59 changes: 59 additions & 0 deletions k8s/challenge53/secret-challenge53-sidecar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: secret-challenge-53
namespace: default
spec:
progressDeadlineSeconds: 20
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: secret-challenge-53
template:
metadata:
labels:
app: secret-challenge-53
name: secret-challenge-53
spec:
securityContext:
runAsUser: 2000
runAsGroup: 2000
fsGroup: 2000
containers:
- image: jeroenwillemsen/wrongsecrets-challenge53:6
name: secret-challenge-53
imagePullPolicy: IfNotPresent
resources:
requests:
memory: '32Mi'
cpu: '50m'
ephemeral-storage: '100Mi'
securityContext:
capabilities:
drop:
- ALL
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
privileged: false
seccompProfile:
type: RuntimeDefault
volumeMounts:
- name: shared-data
mountPath: /shared-data
command: ["/bin/sh", "-c"]
args:
- cp /home/wrongsecrets/* /shared-data/ && exec /home/wrongsecrets/start-on-arch.sh
- image: jeroenwillemsen/wrongsecrets-challenge53-debug:1
name: sidecar
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "while true; do ls /shared-data; sleep 10; done"]
volumeMounts:
- name: shared-data
mountPath: /shared-data
volumes:
- name: 'ephemeral'
emptyDir: { }
- name: shared-data
emptyDir: { }
44 changes: 44 additions & 0 deletions k8s/challenge53/secret-challenge53.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: secret-challenge-53
namespace: default
spec:
progressDeadlineSeconds: 20
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: secret-challenge-53
template:
metadata:
labels:
app: secret-challenge-53
name: secret-challenge-53
spec:
securityContext:
runAsUser: 2000
runAsGroup: 2000
fsGroup: 2000
containers:
- image: jeroenwillemsen/wrongsecrets-challenge53:6
name: secret-challenge-53
imagePullPolicy: IfNotPresent
resources:
requests:
memory: '32Mi'
cpu: '50m'
ephemeral-storage: '100Mi'
securityContext:
capabilities:
drop:
- ALL
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
privileged: false
seccompProfile:
type: RuntimeDefault
volumes:
- name: 'ephemeral'
emptyDir: { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.owasp.wrongsecrets.challenges.kubernetes;

import org.owasp.wrongsecrets.challenges.FixedAnswerChallenge;
import org.owasp.wrongsecrets.challenges.docker.binaryexecution.BinaryExecutionHelper;
import org.owasp.wrongsecrets.challenges.docker.binaryexecution.MuslDetectorImpl;
import org.springframework.stereotype.Component;

/** Challenge53 with a focus on sidecars */
@Component
public class Challenge53 extends FixedAnswerChallenge {

private final BinaryExecutionHelper binaryExecutionHelper;
private final String executable;

protected Challenge53() {
this.executable = "wrongsecrets-challenge53-c";
this.binaryExecutionHelper = new BinaryExecutionHelper(53, new MuslDetectorImpl());
}

@Override
public String getAnswer() {
return binaryExecutionHelper.executeCommand("", executable);
}
}
Binary file added src/main/resources/executables/challenge53
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-advanced-c
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-advanced-c-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-advanced-c-linux
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c-linux
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c-linux-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c-linux-musl
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c-linux-musl-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-c-windows.exe
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-cplus
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-cplus-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-cplus-windows.exe
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-golang
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-golang-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-golang-linux
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-rust
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-rust-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-rust-linux
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-rust-linux-arm
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-rust-linux-musl
Binary file not shown.
Binary file not shown.
Binary file modified src/main/resources/executables/wrongsecrets-rust-windows.exe
Binary file not shown.
7 changes: 7 additions & 0 deletions src/main/resources/explanations/challenge53.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
=== Debugging Container Leak

Modern cloud environments often rely on debugging tools to troubleshoot issues in running applications. However, when debugging capabilities are left open in production, they can expose sensitive information.

A Kubernetes deployment has been misconfigured, allowing developers to attach a debugging container to a running application. Inside this pod, a binary holds a secret in memory. Normally, this secret would be protected, but due to the debugging access, it becomes retrievable.

Can you uncover the secret?
41 changes: 41 additions & 0 deletions src/main/resources/explanations/challenge53_hint.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
By default, the challenge runs without a debugging sidecar. Your goal is to analyze the binary running inside the pod and uncover the secret.

This challenge can be solved using the following steps:

1. Deploy the challenge without the sidecar:
```
kubectl apply -f k8s/challenge53/secret-challenge53.yml
```
Verify that the pod is running:
```
kubectl get pods
```

2. Realize that the pod alone does not provide debugging capabilities. Now, replace the deployment with one that includes a sidecar:
```
kubectl apply -f k8s/challenge53/secret-challenge53-sidecar.yml
```

3. Run the debugging container attached to the running pod:
```
kubectl exec -it <pod-name> -c sidecar -- /bin/sh
```

4. Navigate to the shared directory where the binary is stored:
```
cd /shared-data
```

5. Use `gdb` to inspect the binary and run it:
```
gdb wrongsecrets-challenge53-c-linux
run &
```

6. Locate the memory address of the secret:
```
print &secret
x/s <memory-address>
```

By analyzing the memory, you will uncover the hardcoded secret stored within the binary.
10 changes: 10 additions & 0 deletions src/main/resources/explanations/challenge53_reason.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=== Debugging Containers and Memory Secrets

Debugging tools are powerful, but when left available in production environments, they can expose sensitive information. This challenge highlights how an attacker with debugging access can retrieve secrets from memory using debugging techniques.

The scenario involves a Kubernetes pod running a compiled binary that holds a secret in memory. The binary is part of an application, but due to a misconfiguration, a debugging container can be attached to inspect it. This represents a real-world scenario where misconfigured debugging permissions can lead to security risks.

Organizations should be aware that:
- Allowing unrestricted debugging tools in production environments increases the attack surface.
- Secrets stored in memory can be extracted using debugging techniques.
- Best practices include restricting debug permissions, using ephemeral secrets, and ensuring sensitive data is encrypted in memory.
13 changes: 13 additions & 0 deletions src/main/resources/wrong-secrets-configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -827,3 +827,16 @@ configurations:
category: *secrets
ctf:
enabled: true

- name: Challenge 53
short-name: "challenge-53"
sources:
- class-name: "org.owasp.wrongsecrets.challenges.kubernetes.Challenge53"
explanation: "explanations/challenge53.adoc"
hint: "explanations/challenge53_hint.adoc"
reason: "explanations/challenge53_reason.adoc"
environments: [ *k8s, *k8s_vault, *gcp, *azure, *aws ]
difficulty: *hard
category: *secrets
ctf:
enabled: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.owasp.wrongsecrets.challenges.kubernetes;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

public class Challenge53Test {

@Test
void spoilerShouldGiveAnswer() {
var challenge = new Challenge53();
assertThat(challenge.spoiler().solution()).isEqualTo("K8S_DEBUG_SECRET");
assertThat(challenge.answerCorrect(challenge.spoiler().solution())).isTrue();
}

@Test
void incorrectAnswerShouldNotSolveChallenge() {
var challenge = new Challenge53();
assertThat(challenge.answerCorrect("wrong answer")).isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ void shouldNotShowDisabledChallengeAnywhere() throws Exception {
|| shortname.contains("45")
|| shortname.contains("46")
|| shortname.contains("47")
|| shortname.contains("48")) {
|| shortname.contains("48")
|| shortname.contains("53")) {
continue;
}
mvc.perform(get("/challenge/%s".formatted(challenge.name().shortName())))
Expand Down
Loading