DEV Community

Damrongsak Reetanon
Damrongsak Reetanon

Posted on

พลาดเบอร์ไหนถึงจะโดน hack ผ่าน kubelet

มีข่าวหนึ่งเมื่อวันที่ 3 กุมภาพันธ์ 2564 เกี่ยวกับ Kubernetes จาก Unit42 ของ PaloAlto Network เนื้อหาก็ประมาณว่า มี malware ชื่อว่า Hildegard มุ่งโจมตี Kubernetes โดยเฉพาะ พออ่านลงไปในรายละเอียดของเนื้อหา จุดเริ่มต้นของการโจมตีในกรณีนี้ เกิดจากข้อผิดพลาดในการกำหนดค่า Configuration ของ kubelet เปิดให้เข้าถึงได้โดยไม่ต้องระบุตัวตน จากนั้นก็เรียกคำสั่งให้ทำงานใน container ผ่านทาง kubelet API และในเนื้อหายังบอกอีกว่า ถ้าติดตั้ง Kubernetes แบบมาตรฐานจะเปิดให้เข้าถึงได้โดยไม่ต้องระบุตัวตนเป็นค่าปกติ

Standard Kubernetes deployments come with anonymous access to kubelet by default.

"งานเข้าล่ะ" คำแรกที่อยู่ในหัวตอนที่อ่านข่าวนี้ เริ่มตั้งถามหลายข้อในหัว แล้วค่อย ๆ ไล่หาคำตอบจนคิดว่า น่าจะสบายใจแล้ว

  • จะรู้ได้ไงว่า kubelet เปิด anonymous access อยู่
  • จะเรียกใช้งานคำสั่งให้ทำงานใน container ผ่านทาง kubelet API ได้อย่างไร

จะรู้ได้ไงว่า kubelet เปิด anonymous access อยู่

ไปเจอใน github Liz Rice VP Open Source Engineering at @aquasecurity เขียนไว้

วิธีการการทดสอบ

curl -sk https://<node_ip>:10250/pods/ 
Enter fullscreen mode Exit fullscreen mode
  • ถ้าได้ status code เป็น 401 และมีข้อความตอนกลับมาว่า Unauthorized แสดงว่า ค่า --anonymous-auth ใน kubelet configuration เป็น false อยู่
  • ถ้าได้ status code เป็น 403 และมีข้อความตอนกลับมาว่า Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) แสดงว่า ค่า --anonymous-auth ใน kubelet configuration เป็น true และ --authorization-mode เป็น Webhook
  • ถ้าได้ข้อมูลของ Pod แสดงว่า ค่า --anonymous-auth ใน kubelet configuration เป็น true และ --authorization-mode เป็น AlwaysAllow

จะเรียกใช้งานคำสั่งให้ทำงานใน container ผ่านทาง kubelet API ได้อย่างไร

วิธีการการทดสอบ

curl -ks -X POST https://<node_ip>:10250/run/<namespace>/<pod>/<container> -d "cmd=<command>" 
Enter fullscreen mode Exit fullscreen mode

ระบบที่ใช้ในการทดสอบ

  • Kubernetes version 1.15.2 และ 1.20.2 (ล่าสุด ณ.วันที่ 6 กุมภาพันธ์ 2564)
  • ติดตั้ง Kubernetes ด้วย kubeadm
  • node จำนวน 2 nodes มี ip เป็น 192.168.254.74, 192.168.254.75
root@cp0:~# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME cp0 Ready master 14h v1.15.2 192.168.254.71 <none> Ubuntu 20.04.1 LTS 5.4.0-51-generic containerd://1.3.3-0ubuntu2.2 node0-0 Ready <none> 14h v1.15.2 192.168.254.74 <none> Ubuntu 20.04.1 LTS 5.4.0-51-generic containerd://1.3.3-0ubuntu2.2 node0-1 Ready <none> 14h v1.15.2 192.168.254.75 <none> Ubuntu 20.04.1 LTS 5.4.0-51-generic containerd://1.3.3-0ubuntu2.2 
Enter fullscreen mode Exit fullscreen mode

ทดสอบหลังจากติดตั้งทันที

#[at control plane] root@cp0:~# curl -sk https://192.168.254.74:10250/pods/ Unauthorized 
Enter fullscreen mode Exit fullscreen mode

ผลการทดสอบพบว่า ไม่สามารถเข้าถึง kubelet โดยไม่ต้องระบุตัวตนได้

ตรวจสอบ kubelet configuration ในส่วนของ Authentication และ Authorization

#[at node0-0] root@node0-0:~# cat /var/lib/kubelet/config.yaml |grep -A 12 authentication authentication: anonymous: enabled: false webhook: cacheTTL: 2m0s enabled: true x509: clientCAFile: /etc/kubernetes/pki/ca.crt authorization: mode: Webhook webhook: cacheAuthorizedTTL: 5m0s cacheUnauthorizedTTL: 30s 
Enter fullscreen mode Exit fullscreen mode

พบว่ามีการกำหนดค่าในส่วนของ Authentication และ Authorization ไว้

ทดสอบตั้งค่า Authentication เป็น false และ Authorization เป็น AlwaysAllow

#[at node0-0] root@node0-0:~# cat /var/lib/kubelet/config.yaml |grep -A 4 authentication authentication: anonymous: enabled: true authorization: mode: AlwaysAllow root@node0-0:~# systemctl restart kubelet #[at control plane] root@cp0:~# curl -sk https://192.168.254.74:10250/pods/ | jq |head -n 15 { "kind": "PodList", "apiVersion": "v1", "metadata": {}, "items": [ { "metadata": { "name": "weave-net-27v7f", "generateName": "weave-net-", "namespace": "kube-system", "selfLink": "/api/v1/namespaces/kube-system/pods/weave-net-27v7f", "uid": "93ac4298-5eb7-497f-b914-9c4183230050", "resourceVersion": "72856", "creationTimestamp": "2021-02-05T07:35:15Z", "labels": { 
Enter fullscreen mode Exit fullscreen mode

พบว่า สามารถแสดงรายการของ Pod ใน node นั้นได้

เรียกคำสั่ง hostname ที่ Container testcon ใน Pod testpd ผ่านทาง kubelet API

root@cp0:~# curl -ks -X POST https://192.168.254.74:10250/run/default/testpod/testcon -d "cmd=hostname" testpod 
Enter fullscreen mode Exit fullscreen mode

ทดสอบลบ kubelet configuration ในส่วนของ Authentication และ Authorization ออกทั้งหมด

#[at node0-0] root@node0-0:~# cat /var/lib/kubelet/config.yaml | grep authentication root@node0-0:~# systemctl restart kubelet #[at control plane] root@cp0:~# curl -sk https://192.168.254.74:10250/pods/ Unauthorized 
Enter fullscreen mode Exit fullscreen mode

พบว่า ไม่สามารถเข้าถึง kubelet โดยไม่ต้องระบุตัวตนได้

สรุป

  • ในการทดสอบ Kubernetes ทั้ง version 1.15.2 และ 1.20.2 ได้ผลการทดสอบเหมือนกัน
  • ค่าปกติหลังจากติดตั้ง Kubernetes ด้วย kubeadm ไม่สามารถเข้าถึง kubelet โดยไม่ต้องระบุตัวตนได้
  • ต้องกำหนดค่า authentication และ authorization ถึงจะเข้าถึง kubelet โดยไม่ต้องระบุตัวตนได้
authentication: anonymous: enabled: true authorization: mode: AlwaysAllow 
Enter fullscreen mode Exit fullscreen mode
  • Hacker อาจจะมีวิธีการไม่สามารถเข้าถึง kubelet โดยไม่ต้องระบุตัวตนได้ ในรูปแบบอื่น ๆ ได้อีก

test [at] your own risk

มูลค่าความสุข

Top comments (1)

Collapse
 
terngr profile image
terngr

ขอบคุณครับ