DEV Community

Cover image for How the live Kubernetes DNS Tunneling Demo Was Scripted ? live at CDS 2025 Conference !
Ali Alp
Ali Alp

Posted on

How the live Kubernetes DNS Tunneling Demo Was Scripted ? live at CDS 2025 Conference !

In the talk CDS 2025 - Breaking Kubernetes for fun and profit
at the ContainerDays Conference 2025, you saw a live demo with moving panes, ASCII art, and Kubernetes commands that just flowed. Here’s the actual script that made it possible.

And here’s a breakdown of the script.

1. The Base: demo-magic.sh

The script begins with:

. demo-magic.sh
Enter fullscreen mode Exit fullscreen mode

demo-magic.sh is a small Bash library that makes live demos smoother:

  • p "text" → prints a command (for narration only).
  • pe "command" → prints and executes the command.
  • pei "command" → prints, executes, and leaves pane open for interaction.
  • TYPE_SPEED=20 → controls how fast characters appear (20 ms per char).

This creates the “typed in front of you” effect without human typos.


2. Preparing a Clean Stage

echo "" > ~/kind.log
kind delete cluster > /dev/null 2>&1 || true
docker kill dnscat2-server> /dev/null 2>&1 || true
tmux kill-pane -a
Enter fullscreen mode Exit fullscreen mode

This resets the environment so you can re-run the demo without leftovers:

  • Clear previous logs.
  • Delete any old kind cluster.
  • Kill the malicious dnscat2 server if running.
  • Kill all extra tmux panes.

3. Setting Up tmux Panes

tmux split-window -v -p 30
tmux select-pane -t 0 
tmux split-window -h -p 60
tmux select-pane -t 0
tmux clock-mode -t 2
Enter fullscreen mode Exit fullscreen mode

This creates the demo “dashboard”:

  • Pane 0 (top-left): your main command area.
  • Pane 1 (bottom 30%): for ASCII visuals initially and later the attacker's DNS server.
  • Pane 2 (right 60%): for logs/status, with a live clock.

Then:

tmux send-keys -t 1 "watch -t jp2a --width=65 --height=31 Picture1.png |lolcat -a -s 10 -d 60" Enter
Enter fullscreen mode Exit fullscreen mode

Pane 1 shows a looping ASCII-art hacker picture, colored with lolcat.


4. Audience Engagement

echo "Are you ready ???"
wait
Enter fullscreen mode Exit fullscreen mode

wait pauses until you press Enter — a natural place to talk to the audience before starting the heavy steps.


5. Spinning Up the Cluster

tmux send-keys -t 2 " tail -f ~/kind.log" Enter
kind create cluster > ~/kind.log 2>&1 
kind get kubeconfig > ~/.kube/config
kind load docker-image alialp/dnscat2-client > /dev/null 2>&1 
kubectl config set-context --current --namespace demo
Enter fullscreen mode Exit fullscreen mode
  • Pane 2 tails the log, so the audience sees cluster creation progress.
  • kind create cluster builds the Kubernetes-in-Docker cluster.
  • The dnscat2-client image is preloaded into the cluster.
  • Context is switched to the demo namespace.

6. Bringing in the Evil Server

tmux send-keys -t 1 C-c
tmux send-keys -t 1 "bash ./dns-evil-server.sh" Enter
kubectl create namespace demo
Enter fullscreen mode Exit fullscreen mode
  • Pane 1 stops showing ASCII art and instead launches your malicious DNS server.
  • Namespace demo is created.

7. Manipulating CoreDNS

kubectl wait --namespace kube-system --for=condition=Ready pod --all --timeout=90s
kubectl replace -f coredns-cm.yaml --force
kubectl rollout restart -n kube-system deployment coredns
kubectl wait --namespace kube-system --for=condition=Ready pod --all --timeout=90s
Enter fullscreen mode Exit fullscreen mode

This ensures the DNS manipulation ConfigMap is in place to support localhost DNS forwarding via docker and the CoreDNS is restarted cleanly.


8. Deploying the Malicious Client

tmux send-keys -t 2 C-c
tmux send-keys -t 2 "watch -t -d -n 1 -- kubectl get pods -n demo" Enter
pei "cat ./dnscat2-client-pod.yaml"
pe "kubectl apply -f dnscat2-client-pod.yaml"
Enter fullscreen mode Exit fullscreen mode
  • Pane 2 now watches the demo namespace pods.
  • The manifest is shown (cat) then applied.
  • Audience sees the pod start running.

9. Waiting for Pod Readiness

while ! kubectl get pod dnscat-client -o jsonpath="{.status.phase}" 2>/dev/null | grep -q Running; do sleep 1; done;
Enter fullscreen mode Exit fullscreen mode

This loop blocks until the pod is Running.


10. Switching Pane Colors and Sniffing Traffic

tmux select-pane -t 1 -P 'bg=#872736'; 
tmux send-keys -t 2 C-c
tmux send-keys -t 2 "kubectl sniff -n demo dnscat-client -o - |tshark -i -" Enter
Enter fullscreen mode Exit fullscreen mode
  • Pane 1 background turns red to draw attention and shows that a DNS tunneling session has been created between the Kubernetes pod and the attacker's DNS server.
  • Pane 2 starts packet capture from the client pod, piping into tshark.

11. Showing Exfiltration in Action

kubectl exec -n demo pods/dnscat-client -- watch -t -d -n 1 ls -al  /home/
Enter fullscreen mode Exit fullscreen mode

From Pane 0, the client is controlled via DNS tunneling — audience sees live file listings.


12. Ending the Demo

p "echo 'Press Enter to end the demo! '"
echo "✅ Demo complete!"
echo "Cleaning up..."
kind delete cluster
docker kill dnscat2-server
tmux kill-pane -a 
clear
Enter fullscreen mode Exit fullscreen mode

Cleanup is automatic: cluster deleted, server killed, panes closed, screen cleared.


13. Why It Works

  • demo-magic handles timing and typing.
  • tmux gives multiple views: art, logs, live status.
  • send-keys lets you preload commands into panes, so nothing is manually retyped under stress.
  • wait gives natural narration breaks.
  • color and visuals keep the audience engaged.

14. Takeaway for Attendees

You can adapt the same approach for any technical live demo:

  1. Pre-script your commands with demo-magic.
  2. Use tmux to dedicate panes to visuals, background logs, and main typing.
  3. Use ASCII art or colors to keep people looking at your screen.
  4. Always add cleanup steps so you can rerun reliably.

Happy coding :)

Top comments (0)