Docker Breakout / Privilege Escalation
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
linpeas: Він також може перераховувати контейнери
CDK: Цей інструмент досить корисний для перерахунку контейнера, в якому ви знаходитесь, навіть намагатися втекти автоматично
amicontained: Корисний інструмент для отримання привілеїв, які має контейнер, щоб знайти способи втечі з нього
deepce: Інструмент для перерахунку та втечі з контейнерів
grype: Отримати CVE, що містяться в програмному забезпеченні, встановленому в образі
Якщо ви якимось чином виявите, що docker socket змонтовано всередині контейнера docker, ви зможете втекти з нього. Це зазвичай трапляється в контейнерах docker, які з якоїсь причини потребують підключення до демона docker для виконання дій.
У цьому випадку ви можете використовувати звичайні команди docker для зв'язку з демонстрацією docker:
У випадку, якщо docker socket знаходиться в несподіваному місці, ви все ще можете взаємодіяти з ним, використовуючи команду docker
з параметром -H unix:///path/to/docker.sock
Docker демон також може слухати на порту (за замовчуванням 2375, 2376) або на системах, що базуються на Systemd, взаємодія з Docker демоном може відбуватися через сокет Systemd fd://
.
Крім того, зверніть увагу на сокети виконання інших високорівневих середовищ:
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
...
Вам слід перевірити можливості контейнера, якщо він має будь-які з наступних: 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
Ви можете перевірити поточні можливості контейнера, використовуючи раніше згадані автоматичні інструменти або:
На наступній сторінці ви можете дізнатися більше про можливості linux та як їх зловживати для втечі/ескалації привілеїв:
Linux CapabilitiesПривілейований контейнер може бути створений з прапором --privileged
або шляхом вимкнення певних захистів:
--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
значно знижує безпеку контейнера, пропонуючи необмежений доступ до пристроїв та обходячи кілька захистів. Для детального розгляду зверніться до документації про повні наслідки --privileged
.
З цими дозволами ви можете просто перейти до простору імен процесу, що виконується на хості як root, наприклад init (pid:1), просто виконавши: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Перевірте це в контейнері, виконавши:
Просто з прапором привілеїв ви можете спробувати отримати доступ до диска хоста або спробувати втекти, зловживаючи release_agent або іншими способами втечі.
Перевірте наступні обходи в контейнері, виконавши:
Добре налаштовані docker контейнери не дозволять команди, такі як fdisk -l. Однак на неправильно налаштованій docker команді, де вказано прапор --privileged
або --device=/dev/sda1
з великими літерами, можливо отримати привілеї для перегляду диска хоста.
Отже, щоб захопити хост-машину, це тривіально:
І ось! Тепер ви можете отримати доступ до файлової системи хоста, оскільки вона змонтована в папці /mnt/hola
.
Усередині контейнера зловмисник може спробувати отримати подальший доступ до основної ОС хоста через записуваний том hostPath, створений кластером. Нижче наведено деякі загальні речі, які ви можете перевірити в контейнері, щоб дізнатися, чи можете ви скористатися цим вектором атаки:
Знайдіть пояснення техніки в:
Docker release_agent cgroups escapeУ попередніх експлойтах абсолютний шлях контейнера всередині файлової системи хоста розкрито. Однак це не завжди так. У випадках, коли ви не знаєте абсолютний шлях контейнера всередині хоста, ви можете використовувати цю техніку:
release_agent exploit - Relative Paths to PIDsВиконання PoC у привілейованому контейнері має надати вихід, подібний до:
Є кілька файлів, які можуть бути змонтовані, що дають інформацію про підлягаючий хост. Деякі з них можуть навіть вказувати щось, що має бути виконано хостом, коли щось трапляється (що дозволить зловмиснику втекти з контейнера). Зловживання цими файлами може дозволити:
release_agent (вже розглянуто раніше)
Однак ви можете знайти інші чутливі файли, які слід перевірити на цій сторінці:
Sensitive MountsУ кількох випадках ви виявите, що контейнер має деякий об'єм, змонтований з хоста. Якщо цей об'єм не був правильно налаштований, ви можете отримати доступ/змінити чутливі дані: Читати секрети, змінювати ssh authorized_keys…
Якщо у вас є доступ як root всередині контейнера, який має деяку папку з хоста, що змонтована, і ви втекли як неприprivileged користувач до хоста та маєте доступ для читання до змонтованої папки. Ви можете створити bash suid файл у змонтованій папці всередині контейнера та виконати його з хоста для підвищення привілеїв.
Якщо у вас є доступ як root всередині контейнера і ви втекли як непривабливий користувач на хост, ви можете зловживати обома оболонками для привілейованого підвищення всередині хоста, якщо у вас є можливість MKNOD всередині контейнера (це за замовчуванням) як пояснено в цьому пості. З такою можливістю користувач root всередині контейнера може створювати файли блочних пристроїв. Файли пристроїв - це спеціальні файли, які використовуються для доступу до базового апаратного забезпечення та модулів ядра. Наприклад, файл блочного пристрою /dev/sda надає доступ до читання сирих даних на диску системи.
Docker захищає від зловживання файлами блочних пристроїв всередині контейнерів, застосовуючи політику cgroup, яка блокує операції читання/запису блочних пристроїв. Проте, якщо файл блочного пристрою створено всередині контейнера, він стає доступним ззовні контейнера через директорію /proc/PID/root/. Цей доступ вимагає, щоб власник процесу був однаковим як всередині, так і ззовні контейнера.
Приклад експлуатації з цього опису:
Якщо ви можете отримати доступ до процесів хоста, ви зможете отримати доступ до великої кількості чутливої інформації, що зберігається в цих процесах. Запустіть тестову лабораторію:
Наприклад, ви зможете перерахувати процеси, використовуючи щось на зразок ps auxn
і шукати чутливі деталі в командах.
Тоді, оскільки ви можете доступитися до кожного процесу хоста в /proc/ ви просто можете вкрасти їхні секрети середовища, запустивши:
Ви також можете отримати доступ до дескрипторів файлів інших процесів і читати їх відкриті файли:
Ви також можете вбивати процеси і викликати DoS.
Якщо у вас якимось чином є привілейований доступ до процесу поза контейнером, ви можете виконати щось на зразок nsenter --target <pid> --all
або nsenter --target <pid> --mount --net --pid --cgroup
, щоб запустити оболонку з тими ж обмеженнями ns (сподіваємось, жодних) як у цього процесу.
Якщо контейнер був налаштований з використанням драйвера мережі Docker host networking driver (--network=host
), стек мережі цього контейнера не ізольований від Docker хоста (контейнер ділить простір імен мережі хоста), і контейнер не отримує свою власну IP-адресу. Іншими словами, контейнер прив'язує всі сервіси безпосередньо до IP-адреси хоста. Крім того, контейнер може перехоплювати ВСІ мережеві пакети, які хост надсилає та отримує на спільному інтерфейсі tcpdump -i eth0
.
Наприклад, ви можете використовувати це для перехоплення та навіть підробки трафіку між хостом та екземпляром метаданих.
Як у наступних прикладах:
Ви також зможете отримати доступ до мережевих сервісів, прив'язаних до localhost всередині хоста або навіть отримати доступ до дозволів метаданих вузла (які можуть відрізнятися від тих, до яких може отримати доступ контейнер).
З hostIPC=true
ви отримуєте доступ до ресурсів міжпроцесного спілкування (IPC) хоста, таких як спільна пам'ять у /dev/shm
. Це дозволяє читати/записувати, де ті ж самі ресурси IPC використовуються іншими процесами хоста або пода. Використовуйте ipcs
, щоб детальніше перевірити ці механізми IPC.
Перевірте /dev/shm - Шукайте будь-які файли в цьому місці спільної пам'яті: ls -la /dev/shm
Перевірте існуючі засоби IPC – Ви можете перевірити, чи використовуються якісь засоби IPC за допомогою /usr/bin/ipcs
. Перевірте це за допомогою: ipcs -a
Якщо системний виклик unshare
не заборонений, ви можете відновити всі можливості, запустивши:
Друга техніка, пояснена в пості https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/, вказує, як можна зловживати прив'язками з просторами користувачів, щоб впливати на файли всередині хоста (в цьому конкретному випадку, видаляти файли).
Використовуйте Trickest, щоб легко створювати та автоматизувати робочі процеси, підтримувані найсучаснішими інструментами спільноти. Отримайте доступ сьогодні:
У випадку, якщо ви можете виконати docker exec
як root (ймовірно, з sudo), спробуйте підвищити привілеї, втікаючи з контейнера, зловживаючи CVE-2019-5736 (експлойт тут). Ця техніка в основному перезаписує бінарний файл /bin/sh хоста з контейнера, тому будь-хто, хто виконує docker exec, може активувати payload.
Змініть payload відповідно та зберіть main.go за допомогою go build main.go
. Отриманий бінарний файл слід помістити в контейнер Docker для виконання.
Після виконання, як тільки з'явиться повідомлення [+] Overwritten /bin/sh successfully
, вам потрібно виконати наступне з хост-машини:
docker exec -it <container-name> /bin/sh
Це активує payload, який присутній у файлі main.go.
Для отримання додаткової інформації: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Існують інші CVE, до яких контейнер може бути вразливим, ви можете знайти список на https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list
Простори імен: Процес повинен бути повністю відокремлений від інших процесів через простори імен, тому ми не можемо втекти, взаємодіючи з іншими процесами через простори імен (за замовчуванням не можуть спілкуватися через IPC, unix-сокети, мережеві сервіси, D-Bus, /proc
інших процесів).
Користувач root: За замовчуванням користувач, що виконує процес, є користувачем root (однак його привілеї обмежені).
Можливості: Docker залишає такі можливості: 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
Системні виклики: Це системні виклики, які користувач root не зможе викликати (через відсутність можливостей + Seccomp). Інші системні виклики можуть бути використані для спроби втечі.
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)