CoreDNS poisoning

CoreDNS is the "new" DNS system for Kubernetes which replaced the old KubeDNS system.

By default, the CoreDNS configuration is stored as a configmap in the kube-system namespace

The following is an example of a CoreDNS configuration file.

apiVersion: v1
  Corefile: |
    .:53 {
        health {
           lameduck 5s
        kubernetes cluster.local {
           pods insecure
           ttl 30
        prometheus :9153
        hosts {
        forward . /etc/resolv.conf {
           max_concurrent 1000
        cache 30
kind: ConfigMap
  creationTimestamp: "2024-03-29T04:00:45Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "417"
  uid: 40770875-a1f7-4bf0-aeb5-4b71f60035a1


If an attacker is able to edit this ConfigMap, they could redirect DNS traffic. In the following example, running kubectl exec -it tcpdump -- nslookup returns the name servers of


Running nslookup outside of a pod returns the same results.

The CoreDNS config map file can be queried using kubectl get configmap coredns -n kube-system -o yaml.

If an attacker can edit this ConfigMap, they can add a rewrite rule that redirects traffic from to by adding in rewrite name into the config map.

Editing the config map can be accomplished by running kubectl get configmap coredns -n kube-system -o yaml > poison_dns.yaml, manually adding the file, and then running kubectl apply -f poison_dns.yaml, or by running kubectl edit configmap coredns -n kube-system and making changes.

Once the ConfigMap has been edited, CoreDNS usually needs to be restarted. To do so run kubectl rollout restart -n kube-system deployment/coredns. Finally, we can re-run the previous nslookup command inside a pod to prove that our traffic to will be routed to by running kubectl exec -it tcpdump -- nslookup This time, instead of the name servers being returned being the valid name server for, they are instead the name server for


Pull requests needed ❤️

References & Resources