Add vulnerable environment setup guide to module documentation
Step-by-step minikube-based setup for deploying a vulnerable che-machine-exec instance for module verification.
This commit is contained in:
@@ -9,6 +9,141 @@ This allows lateral movement between workspaces and potential cluster compromise
|
||||
|
||||
Affected versions: Red Hat OpenShift Dev Spaces prior to patches RHSA-2025:22620, RHSA-2025:22652, RHSA-2025:22623.
|
||||
|
||||
## Vulnerable Environment Setup
|
||||
|
||||
The `che-machine-exec` binary runs directly on your host machine, not inside `minikube`. It uses
|
||||
the Kubernetes in-cluster client config which looks for credentials at
|
||||
`/var/run/secrets/kubernetes.io/serviceaccount/` on whatever machine the binary is running on.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Linux host with `Docker` installed (should also work on macOS)
|
||||
- [`minikube`](https://minikube.sigs.k8s.io/docs/start/) installed
|
||||
- `kubectl` installed, or use `minikube kubectl --` as a built-in alternative
|
||||
- [`Go`](https://go.dev/dl/) installed (tested with `go1.24`)
|
||||
|
||||
Install `minikube` (Linux):
|
||||
|
||||
```
|
||||
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
|
||||
sudo install minikube-linux-amd64 /usr/local/bin/minikube
|
||||
```
|
||||
|
||||
Install `kubectl` (Linux):
|
||||
|
||||
```
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
```
|
||||
|
||||
### 1. Start minikube
|
||||
|
||||
```
|
||||
minikube start --driver=docker \
|
||||
--memory=4096 \
|
||||
--cpus=2 \
|
||||
--disk-size=20g
|
||||
```
|
||||
|
||||
### 2. Build from source
|
||||
|
||||
```
|
||||
git clone https://github.com/eclipse-che/che-machine-exec.git
|
||||
cd che-machine-exec
|
||||
go build -o che-machine-exec-vuln .
|
||||
```
|
||||
|
||||
The `main` branch does not enforce authentication on the WebSocket routes. The service is designed to sit behind an OAuth proxy and Kubernetes network policies.
|
||||
|
||||
### 3. Create a Kubernetes service account
|
||||
|
||||
```
|
||||
kubectl create namespace eclipse-che
|
||||
kubectl create serviceaccount machine-exec-test -n eclipse-che
|
||||
kubectl create clusterrolebinding machine-exec-test \
|
||||
--clusterrole=cluster-admin \
|
||||
--serviceaccount=eclipse-che:machine-exec-test
|
||||
```
|
||||
|
||||
### 4. Deploy a target pod
|
||||
|
||||
The binary needs a running pod matching its pod selector. Use `ubuntu` (not `busybox`) so
|
||||
that reverse shell payloads have access to `bash`:
|
||||
|
||||
```
|
||||
kubectl run target-workspace \
|
||||
--image=ubuntu:latest \
|
||||
--restart=Never \
|
||||
-n eclipse-che \
|
||||
--labels="che.workspace_id=test-workspace-id" \
|
||||
-- sleep 3600
|
||||
```
|
||||
|
||||
Wait until the pod is running:
|
||||
|
||||
```
|
||||
kubectl get pod target-workspace -n eclipse-che
|
||||
```
|
||||
|
||||
### 5. Populate the in-cluster credentials directory
|
||||
|
||||
Populate with real `minikube` values:
|
||||
|
||||
```
|
||||
sudo mkdir -p /var/run/secrets/kubernetes.io/serviceaccount
|
||||
|
||||
kubectl -n eclipse-che create token machine-exec-test | \
|
||||
sudo tee /var/run/secrets/kubernetes.io/serviceaccount/token > /dev/null
|
||||
|
||||
sudo cp \
|
||||
$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name=="minikube")].cluster.certificate-authority}') \
|
||||
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
|
||||
printf "eclipse-che" | sudo tee /var/run/secrets/kubernetes.io/serviceaccount/namespace > /dev/null
|
||||
```
|
||||
|
||||
Verify the CA cert is populated:
|
||||
|
||||
```
|
||||
head -1 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
```
|
||||
|
||||
### 6. Start the server
|
||||
|
||||
```
|
||||
export KUBERNETES_SERVICE_HOST=$(minikube ip)
|
||||
export KUBERNETES_SERVICE_PORT=8443
|
||||
export CHE_WORKSPACE_NAME=dummy-workspace
|
||||
export DEVWORKSPACE_NAME=dummy-devworkspace
|
||||
|
||||
./che-machine-exec-vuln \
|
||||
-url 0.0.0.0:3333 \
|
||||
-static /tmp/static \
|
||||
-pod-selector "che.workspace_id=test-workspace-id" \
|
||||
-idle-timeout 24h
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```
|
||||
[GIN-debug] Listening and serving HTTP on 0.0.0.0:3333
|
||||
```
|
||||
|
||||
### 7. Verify the service is reachable
|
||||
|
||||
```
|
||||
curl http://127.0.0.1:3333/healthz
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- `LHOST` must not be `127.0.0.1` when testing. The reverse shell originates from inside the
|
||||
`minikube` pod, which cannot reach the host loopback. Use the `minikube` gateway IP instead
|
||||
(typically `192.168.49.1`, confirm with `minikube ssh "ip route | grep default"`).
|
||||
- The token from `kubectl create token` expires after 1 hour by default. Regenerate it
|
||||
by repeating step 5 if the server starts returning `Unauthorized` errors.
|
||||
- The target pod sleeps for 1 hour. Recreate it if it exits before testing is complete.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
|
||||
Reference in New Issue
Block a user