User Namespace
Reading time: 7 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Basic Information
User namespace - це функція ядра Linux, яка забезпечує ізоляцію відображень ідентифікаторів користувачів і груп, дозволяючи кожному user namespace мати власний набір ідентифікаторів користувачів і груп. Ця ізоляція дозволяє процесам, що працюють у різних user namespaces, мати різні привілеї та власність, навіть якщо вони мають однакові числові ідентифікатори користувачів і груп.
User namespaces особливо корисні в контейнеризації, де кожен контейнер повинен мати свій незалежний набір ідентифікаторів користувачів і груп, що дозволяє покращити безпеку та ізоляцію між контейнерами та хост-системою.
How it works:
- Коли створюється новий user namespace, він починається з порожнього набору відображень ідентифікаторів користувачів і груп. Це означає, що будь-який процес, що працює в новому user namespace, спочатку не матиме привілеїв поза межами namespace.
- Відображення ідентифікаторів можуть бути встановлені між ідентифікаторами користувачів і груп у новому namespace та тими, що в батьківському (або хост) namespace. Це дозволяє процесам у новому namespace мати привілеї та власність, що відповідають ідентифікаторам користувачів і груп у батьківському namespace. Однак відображення ідентифікаторів можуть бути обмежені до конкретних діапазонів і підмножин ідентифікаторів, що дозволяє точно контролювати привілеї, надані процесам у новому namespace.
- У межах user namespace процеси можуть мати повні привілеї root (UID 0) для операцій всередині namespace, при цьому маючи обмежені привілеї поза межами namespace. Це дозволяє контейнерам працювати з можливостями, подібними до root, у своєму власному namespace без повних привілеїв root на хост-системі.
- Процеси можуть переміщатися між namespaces, використовуючи системний виклик
setns()
, або створювати нові namespaces, використовуючи системні викликиunshare()
абоclone()
з прапоромCLONE_NEWUSER
. Коли процес переміщується в новий namespace або створює його, він почне використовувати відображення ідентифікаторів користувачів і груп, пов'язані з цим namespace.
Lab:
Create different Namespaces
CLI
sudo unshare -U [--mount-proc] /bin/bash
Монтування нової інстанції файлової системи /proc
, якщо ви використовуєте параметр --mount-proc
, забезпечує, що новий простір монтування має точний та ізольований вигляд інформації про процеси, специфічної для цього простору.
Помилка: bash: fork: Не вдалося виділити пам'ять
Коли unshare
виконується без параметра -f
, виникає помилка через те, як Linux обробляє нові PID (ідентифікатори процесів) простори. Основні деталі та рішення наведені нижче:
- Пояснення проблеми:
- Ядро Linux дозволяє процесу створювати нові простори за допомогою системного виклику
unshare
. Однак процес, який ініціює створення нового PID простору (називається "unshare" процесом), не входить до нового простору; лише його дочірні процеси входять. - Виконання
%unshare -p /bin/bash%
запускає/bin/bash
в тому ж процесі, що йunshare
. Відповідно,/bin/bash
та його дочірні процеси знаходяться в оригінальному PID просторі. - Перший дочірній процес
/bin/bash
у новому просторі стає PID 1. Коли цей процес завершується, це викликає очищення простору, якщо немає інших процесів, оскільки PID 1 має особливу роль усиновлення сирітських процесів. Ядро Linux тоді вимкне виділення PID у цьому просторі.
- Наслідок:
- Завершення PID 1 у новому просторі призводить до очищення прапора
PIDNS_HASH_ADDING
. Це призводить до того, що функціяalloc_pid
не може виділити новий PID при створенні нового процесу, що викликає помилку "Не вдалося виділити пам'ять".
- Рішення:
- Проблему можна вирішити, використовуючи параметр
-f
зunshare
. Цей параметр змушуєunshare
створити новий процес після створення нового PID простору. - Виконання
%unshare -fp /bin/bash%
забезпечує, що командаunshare
сама стає PID 1 у новому просторі./bin/bash
та його дочірні процеси тоді безпечно містяться в цьому новому просторі, запобігаючи передчасному завершенню PID 1 та дозволяючи нормальне виділення PID.
Забезпечивши, що unshare
виконується з прапором -f
, новий PID простір правильно підтримується, що дозволяє /bin/bash
та його підпроцесам працювати без виникнення помилки виділення пам'яті.
Docker
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
Щоб використовувати простір імен користувача, демон Docker потрібно запустити з --userns-remap=default
(в Ubuntu 14.04 це можна зробити, змінивши /etc/default/docker
, а потім виконавши sudo service docker restart
)
Перевірте, в якому просторі імен знаходиться ваш процес
ls -l /proc/self/ns/user
lrwxrwxrwx 1 root root 0 Apr 4 20:57 /proc/self/ns/user -> 'user:[4026531837]'
Можна перевірити мапу користувачів з контейнера docker за допомогою:
cat /proc/self/uid_map
0 0 4294967295 --> Root is root in host
0 231072 65536 --> Root is 231072 userid in host
Або з хоста за допомогою:
cat /proc/<pid>/uid_map
Знайти всі простори імен користувачів
sudo find /proc -maxdepth 3 -type l -name user -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name user -exec ls -l {} \; 2>/dev/null | grep <ns-number>
Увійти в простір користувача
nsenter -U TARGET_PID --pid /bin/bash
Також ви можете входити в інший простір процесів лише якщо ви root. І ви не можете входити в інший простір без дескриптора, що вказує на нього (наприклад, /proc/self/ns/user
).
Створити новий простір користувача (з відображеннями)
unshare -U [--map-user=<uid>|<name>] [--map-group=<gid>|<name>] [--map-root-user] [--map-current-user]
# Container
sudo unshare -U /bin/bash
nobody@ip-172-31-28-169:/home/ubuntu$ #Check how the user is nobody
# From the host
ps -ef | grep bash # The user inside the host is still root, not nobody
root 27756 27755 0 21:11 pts/10 00:00:00 /bin/bash
Відновлення можливостей
У випадку з просторами користувачів, коли створюється новий простір користувачів, процес, який входить до простору, отримує повний набір можливостей у цьому просторі. Ці можливості дозволяють процесу виконувати привілейовані операції, такі як монтування файлових систем, створення пристроїв або зміна власності файлів, але тільки в контексті його простору користувачів.
Наприклад, коли у вас є можливість CAP_SYS_ADMIN
у просторі користувачів, ви можете виконувати операції, які зазвичай вимагають цієї можливості, такі як монтування файлових систем, але тільки в контексті вашого простору користувачів. Будь-які операції, які ви виконуєте з цією можливістю, не вплинуть на хост-систему або інші простори.
warning
Тому, навіть якщо отримання нового процесу всередині нового простору користувачів дасть вам всі можливості назад (CapEff: 000001ffffffffff), ви насправді можете використовувати лише ті, що пов'язані з простором (монтування, наприклад), але не всі. Отже, цього саме по собі недостатньо, щоб втекти з контейнера Docker.
# There are the syscalls that are filtered after changing User namespace with:
unshare -UmCpf bash
Probando: 0x067 . . . Error
Probando: 0x070 . . . Error
Probando: 0x074 . . . Error
Probando: 0x09b . . . Error
Probando: 0x0a3 . . . Error
Probando: 0x0a4 . . . Error
Probando: 0x0a7 . . . Error
Probando: 0x0a8 . . . Error
Probando: 0x0aa . . . Error
Probando: 0x0ab . . . Error
Probando: 0x0af . . . Error
Probando: 0x0b0 . . . Error
Probando: 0x0f6 . . . Error
Probando: 0x12c . . . Error
Probando: 0x130 . . . Error
Probando: 0x139 . . . Error
Probando: 0x140 . . . Error
Probando: 0x141 . . . Error
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.