Docker Breakout / Privilege Escalation
Last updated
Last updated
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Trickest kullanarak dünyanın en gelişmiş topluluk araçlarıyla desteklenen iş akışlarını kolayca oluşturun ve otomatikleştirin. Bugün Erişim Alın:
linpeas: Ayrıca konteynerleri sayabilir
CDK: Bu araç, bulunduğunuz konteyneri saymak ve otomatik olarak kaçış denemek için oldukça yararlıdır
amicontained: Kaçış yollarını bulmak için konteynerin sahip olduğu ayrıcalıkları almak için yararlı bir araç
deepce: Konteynerlerden sayım yapmak ve kaçış sağlamak için bir araç
grype: Görüntüde yüklü yazılımda bulunan CVE'leri alın
Eğer bir şekilde docker soketinin docker konteyneri içinde montelenmiş olduğunu bulursanız, oradan kaçış yapabileceksiniz. Bu genellikle bazı nedenlerden dolayı docker daemon'a bağlanması gereken docker konteynerlerinde olur.
Bu durumda, docker daemon ile iletişim kurmak için normal docker komutlarını kullanabilirsiniz:
Eğer docker soketi beklenmedik bir yerdeyse, yine de docker
komutunu -H unix:///path/to/docker.sock
parametresi ile kullanarak onunla iletişim kurabilirsiniz.
Docker daemon ayrıca bir portta dinliyor olabilir (varsayılan olarak 2375, 2376) veya Systemd tabanlı sistemlerde, Docker daemon ile iletişim Systemd soketi fd://
üzerinden gerçekleşebilir.
Ayrıca, diğer yüksek seviyeli çalışma zamanlarının çalışma zamanı soketlerine dikkat edin:
dockershim: unix:///var/run/dockershim.sock
containerd: unix:///run/containerd/containerd.sock
cri-o: unix:///var/run/crio/crio.sock
frakti: unix:///var/run/frakti.sock
rktlet: unix:///var/run/rktlet.sock
...
Konteynerin yetkilerini kontrol etmelisiniz, eğer aşağıdakilerden herhangi birine sahipse, ondan kaçış yapabilirsiniz: CAP_SYS_ADMIN
, CAP_SYS_PTRACE
, CAP_SYS_MODULE
, DAC_READ_SEARCH
, DAC_OVERRIDE, CAP_SYS_RAWIO
, CAP_SYSLOG
, CAP_NET_RAW
, CAP_NET_ADMIN
Mevcut konteyner yetkilerini daha önce bahsedilen otomatik araçlar ile veya kontrol edebilirsiniz:
Aşağıdaki sayfada linux yetenekleri hakkında daha fazla bilgi edinebilir ve bunları nasıl kötüye kullanacağınızı öğrenebilirsiniz:
Ayrıcalıklı bir konteyner, --privileged
bayrağı ile veya belirli savunmaları devre dışı bırakarak oluşturulabilir:
--cap-add=ALL
--security-opt apparmor=unconfined
--security-opt seccomp=unconfined
--security-opt label:disable
--pid=host
--userns=host
--uts=host
--cgroupns=host
Mount /dev
--privileged
bayrağı, konteyner güvenliğini önemli ölçüde azaltır, sınırsız cihaz erişimi sunar ve birçok korumayı atlatır. Ayrıntılı bir inceleme için, --privileged
'in tam etkileri hakkında belgeleri inceleyin.
Bu izinlerle, sadece root olarak ana makinede çalışan bir sürecin ad alanına geçebilirsiniz; örneğin init (pid:1) sadece şunu çalıştırarak: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Bunu bir konteynerde test edin:
Sadece yetkili bayrağı ile ana bilgisayarın diskine erişmeye veya release_agent veya diğer kaçışları kötüye kullanarak kaçmaya çalışabilirsiniz.
Aşağıdaki atlatmaları bir konteynerde çalıştırarak test edin:
İyi yapılandırılmış docker konteynerleri fdisk -l gibi komutlara izin vermez. Ancak, --privileged
veya büyük harfle belirtilmiş --device=/dev/sda1
bayrağı ile yanlış yapılandırılmış docker komutlarında, ana makine sürücüsünü görme ayrıcalıklarını elde etmek mümkündür.
Bu nedenle ana makineyi ele geçirmek oldukça basittir:
Ve voilà! Artık /mnt/hola
klasöründe monte edildiği için ana bilgisayarın dosya sistemine erişebilirsiniz.
Konteyner içinde, bir saldırgan, küme tarafından oluşturulan yazılabilir bir hostPath hacmi aracılığıyla altındaki ana işletim sistemine daha fazla erişim sağlamaya çalışabilir. Aşağıda, bu saldırgan vektörünü kullanıp kullanamayacağınızı görmek için konteyner içinde kontrol edebileceğiniz bazı yaygın şeyler bulunmaktadır:
Bir teknik açıklaması bulmak için:
Önceki istismarlar, konteynerin ana bilgisayarın dosya sistemindeki mutlak yolunu ifşa eder. Ancak, bu her zaman böyle değildir. Ana bilgisayar içindeki konteynerin mutlak yolunu bilmediğiniz durumlarda bu tekniği kullanabilirsiniz:
Yetkili bir konteyner içinde PoC'yi çalıştırmak, aşağıdaki gibi bir çıktı sağlamalıdır:
Montaj yapılmış birkaç dosya vardır ki bunlar altındaki ana makine hakkında bilgi verir. Bunlardan bazıları, bir şey olduğunda ana makine tarafından yürütülecek bir şeyi gösterebilir (bu, bir saldırganın konteynerden kaçmasına izin verecektir). Bu dosyaların istismarı şunları mümkün kılabilir:
release_agent (daha önce ele alındı)
Ancak, bu sayfada kontrol edilecek diğer hassas dosyalar bulabilirsiniz:
Birçok durumda, konteynerin ana makineden bazı hacimlerin montajlı olduğunu göreceksiniz. Eğer bu hacim doğru bir şekilde yapılandırılmamışsa, hassas verilere erişim/değişiklik yapma imkanınız olabilir: Gizli bilgileri okuyun, ssh authorized_keys'i değiştirin…
Eğer bir konteyner içinde root erişiminiz varsa ve host'tan mount edilmiş bir klasör varsa ve host'a yetkisiz bir kullanıcı olarak kaçtıysanız ve mount edilmiş klasör üzerinde okuma erişiminiz varsa. Konteyner içindeki mount edilmiş klasörde bir bash suid dosyası oluşturabilir ve host'tan çalıştırarak yetki yükseltebilirsiniz.
Eğer bir konteyner içinde root olarak erişiminiz varsa ve host'a yetkisiz bir kullanıcı olarak kaçtıysanız, her iki shell'i de host içinde privesc için kötüye kullanabilirsiniz eğer konteyner içinde MKNOD yeteneğine sahipseniz (varsayılan olarak vardır) bu yazıda açıklandığı gibi. Bu yetenekle konteyner içindeki root kullanıcısı blok cihaz dosyaları oluşturma iznine sahiptir. Cihaz dosyaları, temel donanım ve çekirdek modüllerine erişmek için kullanılan özel dosyalardır. Örneğin, /dev/sda blok cihaz dosyası, sistem diskindeki ham verilere erişim sağlar.
Docker, konteynerler içinde blok cihaz kötüye kullanımına karşı, blok cihazı okuma/yazma işlemlerini engelleyen bir cgroup politikası uygulayarak koruma sağlar. Ancak, eğer bir blok cihaz konteyner içinde oluşturulursa, bu cihaz konteyner dışından /proc/PID/root/ dizini aracılığıyla erişilebilir hale gelir. Bu erişim, işlem sahibinin hem konteyner içinde hem de dışında aynı olması gerektirir.
Sömürü örneği bu yazıdan:
Eğer ana makinenin süreçlerine erişiminiz varsa, bu süreçlerde saklanan birçok hassas bilgiye erişebileceksiniz. Test laboratuvarını çalıştırın:
Örneğin, ps auxn
gibi bir şey kullanarak süreçleri listeleyebilir ve komutlarda hassas ayrıntıları arayabilirsiniz.
Sonra, /proc/ içindeki her bir host sürecine erişebildiğiniz için, sadece env gizli anahtarlarını çalabilirsiniz:
Diğer süreçlerin dosya tanımlayıcılarına da erişebilir ve açık dosyalarını okuyabilirsiniz:
You can also kill processes and cause a DoS.
Eğer bir şekilde kapsayıcı dışındaki bir süreç üzerinde ayrıcalıklı erişiminiz varsa, nsenter --target <pid> --all
veya nsenter --target <pid> --mount --net --pid --cgroup
gibi bir şey çalıştırarak o süreçle aynı ns kısıtlamalarıyla (umarım hiç yok) bir shell çalıştırabilirsiniz.
Eğer bir konteyner Docker host networking driver (--network=host
) ile yapılandırılmışsa, o konteynerin ağ yığını Docker ana bilgisayarından izole değildir (konteyner, ana bilgisayarın ağ ad alanını paylaşır) ve konteynerin kendi IP adresi tahsis edilmez. Diğer bir deyişle, konteyner tüm hizmetleri doğrudan ana bilgisayarın IP'sine bağlar. Dahası, konteyner ana bilgisayarın gönderdiği ve aldığı tüm ağ trafiğini yakalayabilir ve manipüle edebilir tcpdump -i eth0
.
Örneğin, bunu ana bilgisayar ile metadata örneği arasındaki trafiği yakalamak ve hatta sahte trafiği oluşturmak için kullanabilirsiniz.
Aşağıdaki örneklerde olduğu gibi:
Ayrıca, ana bilgisayar içindeki localhost'a bağlı ağ hizmetlerine erişebilecek veya düğümün metadata izinlerine (bir konteynerin erişebileceğinden farklı olabilir) erişebileceksiniz.
hostIPC=true
ile, ana bilgisayarın süreçler arası iletişim (IPC) kaynaklarına, örneğin /dev/shm
içindeki paylaşılan bellek kaynaklarına erişim kazanırsınız. Bu, diğer ana bilgisayar veya pod süreçleri tarafından kullanılan aynı IPC kaynaklarının okuma/yazma işlemlerini sağlar. Bu IPC mekanizmalarını daha ayrıntılı incelemek için ipcs
komutunu kullanın.
/dev/shm'yi incele - Bu paylaşılan bellek konumundaki dosyaları kontrol edin: ls -la /dev/shm
Mevcut IPC tesislerini incele – Herhangi bir IPC tesisinin kullanılıp kullanılmadığını kontrol etmek için /usr/bin/ipcs
komutunu kullanabilirsiniz. Bunu kontrol edin: ipcs -a
Eğer sistem çağrısı unshare
yasaklanmamışsa, tüm yetenekleri geri kazanabilirsiniz:
Gönderide açıklanan ikinci teknik https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/ kullanıcı ad alanları ile bind mount'ları nasıl istismar edebileceğinizi, ev sahibi içindeki dosyaları etkilemek için (bu özel durumda, dosyaları silmek) göstermektedir.
Dünyanın en gelişmiş topluluk araçlarıyla desteklenen iş akışlarını kolayca oluşturmak ve otomatikleştirmek için Trickest kullanın. Bugün Erişim Alın:
Eğer docker exec
komutunu root olarak çalıştırabiliyorsanız (muhtemelen sudo ile), CVE-2019-5736'dan yararlanarak bir konteynerden kaçış yaparak ayrıcalıkları artırmaya çalışırsınız (istismar burada). Bu teknik temelde /bin/sh ikili dosyasını ev sahibi bir konteynerden üstüne yazacaktır, böylece docker exec komutunu çalıştıran herkes yükü tetikleyebilir.
Yükü buna göre değiştirin ve go build main.go
ile main.go dosyasını oluşturun. Ortaya çıkan ikili dosya, yürütme için docker konteynerine yerleştirilmelidir.
Yürütme sırasında, [+] Overwritten /bin/sh successfully
mesajını gösterdiği anda, ev sahibi makineden aşağıdakini çalıştırmalısınız:
docker exec -it <container-name> /bin/sh
Bu, main.go dosyasında bulunan yükü tetikleyecektir.
Daha fazla bilgi için: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Konteynerin savunmasız olabileceği diğer CVE'ler de vardır, bir listeyi https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list adresinde bulabilirsiniz.
Ad Alanları: Süreç, ad alanları aracılığıyla diğer süreçlerden tamamen ayrılmış olmalıdır, bu nedenle ad alanları nedeniyle diğer süreçlerle etkileşimde bulunarak kaçış yapamayız (varsayılan olarak IPC'ler, unix soketleri, ağ hizmetleri, D-Bus, diğer süreçlerin /proc
'u aracılığıyla iletişim kuramazlar).
Root kullanıcı: Varsayılan olarak süreci çalıştıran kullanıcı root kullanıcısıdır (ancak ayrıcalıkları sınırlıdır).
Yetenekler: Docker aşağıdaki yetenekleri bırakır: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
Sistem çağrıları: Bu, root kullanıcısının çağıramayacağı sistem çağrılarıdır (yeteneklerin eksikliği + Seccomp nedeniyle). Diğer sistem çağrıları kaçış yapmaya çalışmak için kullanılabilir.
If you are in userspace (no kernel exploit involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode):
Find the path of the containers filesystem inside the host
You can do this via mount, or via brute-force PIDs as explained in the second release_agent exploit
Find some functionality where you can indicate the path of a script to be executed by a host process (helper) if something happens
You should be able to execute the trigger from inside the host
You need to know where the containers files are located inside the host to indicate a script you write inside the host
Have enough capabilities and disabled protections to be able to abuse that functionality
You might need to mount things o perform special privileged actions you cannot do in a default docker container
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)