Skip to content

Commit

Permalink
Fixes and instructions for Todolist + log4shell on K8s
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Smalling committed Dec 21, 2021
1 parent c9735dd commit 47172b1
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 9 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,47 @@ It's divided into modules, each one having its own README:

* [Todolist Goof](todolist-goof/README.md)
* [Log4Shell Goof](log4shell-goof/README.md)

---
## Kubernetes based Todolist + Log4Shell exploit
To deploy Todolist on Kubernetes along with the needed ldap backend for exploiting the Log4shell
vulnerability:

### Prerequisites
1. A kubernetes cluster where you have permissions to create namespaces, deployments and services
2. The `kubectl` client and credenials configuration
3. Docker Desktop or docker-ce (for building and pushing images)
4. A DockerHub account

### Quickstart
Assuming you have your kubernetes cluster up and ready, from the top level of this repo you can run `./k8s-quickstart.sh` which will do the following:
1. Builds todolist-goof image and pushes it to Docker Hub. _(see below for account/tagging info)_
2. Deploys the todolist to the `default` namespace in your kubernetes cluster along with a LoadBalancer type service
3. Builds the log4shell-server image and pushes to Docker Hub. _(see below for account/tagging info)_
4. Deploys the log4shell-server and a pair of ClusterIP type services into a new namespace named `darkweb` in your Kubernetes cluster.

### Accessing the application
Once complete, run `kubectl get svc` and note the IP Address or hostname of the `goof` service.

You should be able to open a browser to http://{svc-ip-addr}/todolist and see the app

#### EKS cluster notes
* In order to perform NetworkPolicy egress examples, you will need to deploy the Calico CNI plugin as EKS does not implement NetworkPolicy by default.
The `eks-calico.sh` script in `todolist-goof/k8s` will deploy this for you. (that script is sym-linked to the top level here too)
* You should log into the AWS console and change inbound access for the good service's ELB to only allow your home IP, otherwise you *will* have audience members trying to mess with it.

#### Docker Desktop Kubernetes notes
* Docker Desktop automatically serves the goof service loadblancer external IP to your workstation's localhost so the app will be available at http://localhost/todolist
* Docker Desktop Kubernetes CNI does not implement Network Policy so you will not be able to demonstrate any mitigation techniques that use that.

#### Kind (Kubernetes on Docker) notes
* Kind's default CNI does not currently support Network Policy so you should deploy your own using the instructions on their website.
* If running Kind on top of Docker Desktop, you will need to run a port-forward to access the app. For example, use something like this: `kubectl port-forward service/goof 8000:80` and then access it via browser at http://localhost:8000/todolist

### Quick cleanup
Run the `/.k8s-quickstop.sh` script at the top level of this repo which will do the following:
1. Deletes the todolist deployment and associated service in the `default` namespace
2. Deletes the log4shell deployment and associated services in the `darkweb` namespace and deltes the namespace as well
**Note:** This will not delete any additional objects you may have deployed such as NetworkPolicies.

It is up to you to shut down your Kubernetes cluster as appropriate.
1 change: 1 addition & 0 deletions eks-calico.sh
10 changes: 10 additions & 0 deletions k8s-quickstart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
TOP_LEVEL_MYDIR=$(dirname $0)
if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi
$TOP_LEVEL_MYDIR/todolist-goof/k8s/quickstart.sh $DOCKER_ACCOUNT
$TOP_LEVEL_MYDIR/log4shell-goof/log4shell-server/k8s/quickstart.sh $DOCKER_ACCOUNT
4 changes: 4 additions & 0 deletions k8s-quickstop.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
TOP_LEVEL_MYDIR=$(dirname $0)
$TOP_LEVEL_MYDIR/todolist-goof/k8s/shutdown.sh
$TOP_LEVEL_MYDIR/log4shell-goof/log4shell-server/k8s/shutdown.sh
8 changes: 6 additions & 2 deletions log4shell-goof/log4shell-server/k8s/imagebuild.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#!/usr/bin/env bash
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi

echo "📦 Building image ${DOCKER_ACCOUNT}/log4shell-server:latest ..."
docker build -t ${DOCKER_ACCOUNT}/log4shell-server:latest .
Expand Down
13 changes: 13 additions & 0 deletions log4shell-goof/log4shell-server/k8s/quickstart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
LOG4SHELL_MYDIR=$(dirname $0)
if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi

$LOG4SHELL_MYDIR/imagebuild.sh $DOCKER_ACCOUNT
$LOG4SHELL_MYDIR/startup.sh $DOCKER_ACCOUNT


8 changes: 6 additions & 2 deletions log4shell-goof/log4shell-server/k8s/startup.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#!/usr/bin/env bash
MYDIR=$(dirname $0)
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi

cat $MYDIR/deploy.yaml | envsubst | kubectl apply -f -

Expand Down
8 changes: 8 additions & 0 deletions todolist-goof/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ COPY --chown=tomcat:tomcat web.xml /usr/local/tomcat/conf/web.xml
COPY --from=build /usr/src/goof/todolist-web-struts/target/todolist /usr/local/tomcat/webapps/todolist
COPY --from=build /usr/local/openjdk-8/bin/native2ascii /docker-java-home/jre/bin/native2ascii
COPY --from=build /usr/local/openjdk-8/lib/tools.jar /docker-java-home/jre/lib/tools.jar






#Uncomment the next line for log4shell vulnerability if using base tomcat image > 8.5.33
#ENV JAVA_OPTS="-Dcom.sun.jndi.ldap.object.trustURLCodebase=true"
3 changes: 3 additions & 0 deletions todolist-goof/k8s/eks-calico.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/calico-operator.yaml
kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/calico-crs.yaml
11 changes: 8 additions & 3 deletions todolist-goof/k8s/imagebuild.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
#!/usr/bin/env bash
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
MYDIR=$(dirname $0)
if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi

echo "📦 Building image ${DOCKER_ACCOUNT}/java-goof:latest ..."
docker build -t ${DOCKER_ACCOUNT}/java-goof:latest .
docker build -t ${DOCKER_ACCOUNT}/java-goof:latest $MYDIR/..
echo
echo "🚚 Pushing image to DockerHub..."
docker push ${DOCKER_ACCOUNT}/java-goof:latest
42 changes: 42 additions & 0 deletions todolist-goof/k8s/java-goof2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: goof
name: goof
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: goof
template:
metadata:
labels:
app: goof
spec:
containers:
- image: ${DOCKER_ACCOUNT}/java-goof:latest
imagePullPolicy: Always
name: java-goof
securityContext:
runAsNonRoot: true
runAsUser: 65534 #nobody
runAsGroup: 65534 #nobody
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
labels:
app: goof
name: goof
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: goof
13 changes: 13 additions & 0 deletions todolist-goof/k8s/quickstart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
TODO_MYDIR=$(dirname $0)
if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi

$TODO_MYDIR/imagebuild.sh $DOCKER_ACCOUNT
$TODO_MYDIR/startup.sh $DOCKER_ACCOUNT


9 changes: 7 additions & 2 deletions todolist-goof/k8s/startup.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#!/usr/bin/env bash
MYDIR=$(dirname $0)
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"

if [[ "$1" == "" ]]; then
read -e -i "${DOCKER_ACCOUNT}" -p "Please enter your DockerHub user/account name: " input
name="${input:-$DOCKER_ACCOUNT}"
else
DOCKER_ACCOUNT=$1
fi

cat $MYDIR/java-goof.yaml | envsubst | kubectl apply -f -

Expand Down

0 comments on commit 47172b1

Please sign in to comment.