Time Namespace
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.
Basic Information
Часовий простір у Linux дозволяє використовувати зсуви для системних монотонних і завантажувальних годинників для кожного простору. Він зазвичай використовується в контейнерах Linux для зміни дати/часу всередині контейнера та коригування годинників після відновлення з контрольної точки або знімка.
Lab:
Create different Namespaces
CLI
sudo unshare -T [--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
Перевірте, в якому просторі імен знаходиться ваш процес
ls -l /proc/self/ns/time
lrwxrwxrwx 1 root root 0 Apr 4 21:16 /proc/self/ns/time -> 'time:[4026531834]'
Знайти всі простори часу
sudo find /proc -maxdepth 3 -type l -name time -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name time -exec ls -l {} \; 2>/dev/null | grep <ns-number>
Увійти в простір часу
nsenter -T TARGET_PID --pid /bin/bash
Маніпулювання часовими зсувами
Починаючи з Linux 5.6, два годинники можуть бути віртуалізовані для кожного простору часу:
CLOCK_MONOTONIC
CLOCK_BOOTTIME
Їхні делти на кожен простір часу відкриті (і можуть бути змінені) через файл /proc/<PID>/timens_offsets
:
$ sudo unshare -Tr --mount-proc bash # -T creates a new timens, -r drops capabilities
$ cat /proc/$$/timens_offsets
monotonic 0
boottime 0
Файл містить два рядки – по одному для кожного годинника – з зсувом у наносекундах. Процеси, які мають CAP_SYS_TIME в часовому просторі, можуть змінювати значення:
# advance CLOCK_MONOTONIC by two days (172 800 s)
echo "monotonic 172800000000000" > /proc/$$/timens_offsets
# verify
$ cat /proc/$$/uptime # first column uses CLOCK_MONOTONIC
172801.37 13.57
Якщо вам потрібно, щоб настінний годинник (CLOCK_REALTIME
) також змінювався, вам все ще потрібно покладатися на класичні механізми (date
, hwclock
, chronyd
, …); він не є просторовим.
unshare(1)
допоміжні прапори (util-linux ≥ 2.38)
sudo unshare -T \
--monotonic="+24h" \
--boottime="+7d" \
--mount-proc \
bash
Довгі параметри автоматично записують обрані дельти в timens_offsets
одразу після створення простору імен, що заощаджує ручне echo
.
Підтримка OCI та Runtime
- OCI Runtime Specification v1.1 (листопад 2023) додала спеціальний тип простору імен
time
та полеlinux.timeOffsets
, щоб контейнерні движки могли запитувати віртуалізацію часу у переносимий спосіб. - runc >= 1.2.0 реалізує цю частину специфікації. Мінімальний фрагмент
config.json
виглядає так:
{
"linux": {
"namespaces": [
{"type": "time"}
],
"timeOffsets": {
"monotonic": 86400,
"boottime": 600
}
}
}
Потім запустіть контейнер за допомогою runc run <id>
.
ЗАУВАЖТЕ: runc 1.2.6 (лютий 2025) виправив помилку "exec into container with private timens", яка могла призвести до зависання та потенційного DoS. Переконайтеся, що ви використовуєте версію ≥ 1.2.6 у виробництві.
Розгляди безпеки
- Необхідна можливість – Процес потребує CAP_SYS_TIME всередині свого простору імен користувача/часу, щоб змінити зсуви. Відмова від цієї можливості в контейнері (за замовчуванням у Docker та Kubernetes) запобігає маніпуляціям.
- Без змін годинника – Оскільки
CLOCK_REALTIME
спільний з хостом, зловмисники не можуть підробити терміни дії сертифікатів, терміни дії JWT тощо лише за допомогою timens. - Уникнення журналювання/виявлення – Програмне забезпечення, яке покладається на
CLOCK_MONOTONIC
(наприклад, обмежувачі швидкості на основі часу безперервної роботи), може бути заплутаним, якщо користувач простору імен регулює зсув. Віддавайте перевагуCLOCK_REALTIME
для часових міток, що мають значення для безпеки. - Поверхня атаки ядра – Навіть якщо
CAP_SYS_TIME
видалено, код ядра залишається доступним; підтримуйте хост в актуальному стані. Linux 5.6 → 5.12 отримав кілька виправлень помилок timens (NULL-deref, проблеми з підписом).
Контрольний список посилення безпеки
- Відмовтеся від
CAP_SYS_TIME
у вашому профілі за замовчуванням контейнерного виконання. - Підтримуйте виконання в актуальному стані (runc ≥ 1.2.6, crun ≥ 1.12).
- Закріпіть util-linux ≥ 2.38, якщо ви покладаєтеся на допоміжні програми
--monotonic/--boottime
. - Аудит програмного забезпечення в контейнері, яке читає uptime або CLOCK_MONOTONIC для логіки, критично важливої для безпеки.
Посилання
- man7.org – Сторінка посібника по просторах імен часу: https://man7.org/linux/man-pages/man7/time_namespaces.7.html
- Блог OCI – "OCI v1.1: нові простори імен часу та RDT" (15 листопада 2023): https://opencontainers.org/blog/2023/11/15/oci-spec-v1.1
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.