CGroup Namespace

Reading time: 5 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Основна інформація

Cgroup namespace - це функція ядра Linux, яка забезпечує ізоляцію ієрархій cgroup для процесів, що виконуються в межах простору імен. Cgroups, скорочено від контрольних груп, є функцією ядра, яка дозволяє організовувати процеси в ієрархічні групи для управління та забезпечення обмежень на системні ресурси такі як CPU, пам'ять та I/O.

Хоча cgroup namespaces не є окремим типом простору імен, як інші, про які ми говорили раніше (PID, mount, network тощо), вони пов'язані з концепцією ізоляції простору імен. Cgroup namespaces віртуалізують вид ієрархії cgroup, так що процеси, що виконуються в cgroup namespace, мають інший вигляд ієрархії в порівнянні з процесами, що виконуються на хості або в інших просторах імен.

Як це працює:

  1. Коли створюється новий cgroup namespace, він починається з вигляду ієрархії cgroup, заснованого на cgroup процесу, що створює. Це означає, що процеси, що виконуються в новому cgroup namespace, будуть бачити лише підмножину всієї ієрархії cgroup, обмежену піддеревом cgroup, коренем якого є cgroup процесу, що створює.
  2. Процеси в межах cgroup namespace бачать свою власну cgroup як корінь ієрархії. Це означає, що з точки зору процесів всередині простору імен їхня власна cgroup виглядає як корінь, і вони не можуть бачити або отримувати доступ до cgroups поза їхнім власним піддеревом.
  3. Cgroup namespaces не забезпечують безпосередньої ізоляції ресурсів; вони лише забезпечують ізоляцію вигляду ієрархії cgroup. Контроль і ізоляція ресурсів все ще забезпечуються підсистемами cgroup (наприклад, cpu, пам'ять тощо).

Для отримання додаткової інформації про CGroups перегляньте:

CGroups

Лабораторія:

Створення різних просторів імен

CLI

bash
sudo unshare -C [--mount-proc] /bin/bash

Монтування нової інстанції файлової системи /proc, якщо ви використовуєте параметр --mount-proc, забезпечує, що новий простір монтування має точний і ізольований вигляд інформації про процеси, специфічної для цього простору.

Помилка: bash: fork: Не вдалося виділити пам'ять

Коли unshare виконується без параметра -f, виникає помилка через те, як Linux обробляє нові PID (ідентифікатори процесів) простори. Основні деталі та рішення наведені нижче:

  1. Пояснення проблеми:
  • Ядро Linux дозволяє процесу створювати нові простори за допомогою системного виклику unshare. Однак процес, який ініціює створення нового PID простору (який називається "процесом unshare"), не входить до нового простору; лише його дочірні процеси входять.
  • Виконання %unshare -p /bin/bash% запускає /bin/bash в тому ж процесі, що й unshare. Внаслідок цього /bin/bash та його дочірні процеси знаходяться в оригінальному PID просторі.
  • Перший дочірній процес /bin/bash у новому просторі стає PID 1. Коли цей процес завершується, це викликає очищення простору, якщо немає інших процесів, оскільки PID 1 має особливу роль усиновлення сирітських процесів. Ядро Linux тоді вимкне виділення PID у цьому просторі.
  1. Наслідок:
  • Завершення PID 1 у новому просторі призводить до очищення прапора PIDNS_HASH_ADDING. Це призводить до того, що функція alloc_pid не може виділити новий PID при створенні нового процесу, що викликає помилку "Не вдалося виділити пам'ять".
  1. Рішення:
  • Проблему можна вирішити, використовуючи параметр -f з unshare. Цей параметр змушує unshare створити новий процес після створення нового PID простору.
  • Виконання %unshare -fp /bin/bash% забезпечує, що команда unshare сама стає PID 1 у новому просторі. /bin/bash та його дочірні процеси тоді безпечно містяться в цьому новому просторі, запобігаючи передчасному завершенню PID 1 і дозволяючи нормальне виділення PID.

Забезпечивши, що unshare виконується з прапором -f, новий PID простір правильно підтримується, що дозволяє /bin/bash та його підпроцесам працювати без виникнення помилки виділення пам'яті.

Docker

bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash

Перевірте, в якому просторі імен знаходиться ваш процес

bash
ls -l /proc/self/ns/cgroup
lrwxrwxrwx 1 root root 0 Apr  4 21:19 /proc/self/ns/cgroup -> 'cgroup:[4026531835]'

Знайти всі простори імен CGroup

bash
sudo find /proc -maxdepth 3 -type l -name cgroup -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name cgroup -exec ls -l  {} \; 2>/dev/null | grep <ns-number>

Увійти в простір імен CGroup

bash
nsenter -C TARGET_PID --pid /bin/bash

Також ви можете входити в інше просторове ім'я лише якщо ви є root. І ви не можете входити в інше просторове ім'я без дескриптора, що вказує на нього (наприклад, /proc/self/ns/cgroup).

References

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks