Docker Escape

ID
Techniques Name
Minimal Linux Capabilities
1
Mount the host filesystem
SYS_ADMIN
2
Use a mounted docker socket
No capability is required
3
Process Injection
SYS_PTRACE
4
Adding a malicious kernel module
SYS_MODULE
5
Reading secrets from the host
DAC_READ_SEARCH
6
Overriding files on host
DAC_READ_SEARCH, DAC_OVERRIDE
7
Abusing notify on release
SYS_ADMIN, DAC_OVERRIDE
Recon
Once we are in the container, we can perform capability discovery to determine which privileges are allowed in the container. The container capabilities can be viewed by reading the content of the main container process (PID = 1) status from within the container:
CapInh— Inheritable capabilities (разрешения, которые могут наследовать потомки).CapPrm— Permitted capabilities (разрешения, которые могут использоваться задачей).CapEff— Effective capabilities (текущие действующие разрешения).CapBnd— Bounding capabilities (ограничивающие привилегии. до Linux 2.6.25 ограничивающий набор был общесистемным атрибутом, общим для всех потоков, предназначенным для описания набора, за пределы которого разрешения расширяться не могут. В настоящее время это набор для каждой задачи и является лишь частью логики execve).CapAmb— Ambient capabilities (окружающие привилегии. добавлены, чтобы легче предоставлять разрешения не-root пользователю, без использования setuid или файловых разрешений).
Decode:
Privileged + hostPID
With these permissions you can just move to the namespace of a process running in the host as root like init (pid:1) just running:
nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Docker socket
Arbitrary Mounts
Побег из контейнера используя CAP_SYS_MODULE
Создадим два файла: reverse_shell.c и Makefile
Содержимое файла reverse_shell.c:
Большое пояснение
Данный модуль ядра вызывает программу пространства пользователя /bin/bash из ядра с помощью call_usermodehelper. argv — это список аргументов в массиве. Первый элемент — это программа (/bin/bash), которое мы хотим выполнить, и за ней следует список аргументов. Последний элемент является терминатором NULL, который указывает на конец списка.
envp — следующая необходимая переменная. Это массив окружения, представляющий собой список параметров, определяющий среду выполнения для приложения пользовательского пространства. В этом примере мы определили один параметр HOME для оболочки, и этот список заканчивается терминирующей записью NULL, как и argv.
Последний аргумент call_usermodehelper — UMH_WAIT_EXEC. Это необходимо для того, чтобы указать, что запрашивающий хочет дождаться запуска приложения пользовательского пространства, но не завершить его.
Наконец, мы используем IP-адрес 172.17.0.1 в качестве IP-адреса прослушивателя, поэтому этот модуль попытается сделать обратное подключение к этому IP-адресу через порт 4444. Данный ip-адрес может отличаться, но в моем случае это 172.17.0.1. Проверить ваш ip-адрес интерфейса docker0 можно командой ip a или ifconfig docker0.
Конец большого пояснения
Содержимое Makefile:
Запустите команду make в репозитории, на выходе вы должны получить .ko файл.
Запустите контейнер с --privileged флагом в deteached режиме и скопируйте туда .ko файл:
Запустите еще один терминал и начните прослушивание на порту 4444 с помощью утилиты netcat:
А теперь самое время загрузить наш модуль ядра внутри контейнера :)
Last updated