From 59e3e8e1ddf654e3f1adef1f99a2b1b332185253 Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 5 Aug 2025 04:31:27 +0000 Subject: [PATCH] Translated ['src/linux-hardening/privilege-escalation/docker-security/na --- .../namespaces/time-namespace.md | 86 ++++++++++++++++++- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md index cc1068360..5f504831b 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md @@ -4,7 +4,7 @@ ## Basic Information -Часовий простір у Linux дозволяє використовувати зсуви для системних монотонних і завантажувальних годинників для кожного простору. Він зазвичай використовується в контейнерах Linux для зміни дати/часу всередині контейнера та налаштування годинників після відновлення з контрольної точки або знімка. +Часовий простір у Linux дозволяє використовувати зсуви для системних монотонних і завантажувальних годинників для кожного простору. Він зазвичай використовується в контейнерах Linux для зміни дати/часу всередині контейнера та коригування годинників після відновлення з контрольної точки або знімка. ## Lab: @@ -30,13 +30,13 @@ sudo unshare -T [--mount-proc] /bin/bash 2. **Наслідок**: -- Завершення PID 1 у новому просторі призводить до очищення прапора `PIDNS_HASH_ADDING`. Це призводить до того, що функція `alloc_pid` не може виділити новий PID при створенні нового процесу, що викликає помилку "Не вдалося виділити пам'ять". +- Вихід PID 1 у новому просторі призводить до очищення прапора `PIDNS_HASH_ADDING`. Це призводить до того, що функція `alloc_pid` не може виділити новий PID при створенні нового процесу, що викликає помилку "Не вдалося виділити пам'ять". 3. **Рішення**: - Проблему можна вирішити, використовуючи параметр `-f` з `unshare`. Цей параметр змушує `unshare` створити новий процес після створення нового PID простору. -- Виконання `%unshare -fp /bin/bash%` забезпечує, що команда `unshare` сама стає PID 1 у новому просторі. `/bin/bash` та його дочірні процеси тоді безпечно містяться в цьому новому просторі, запобігаючи передчасному завершенню PID 1 та дозволяючи нормальне виділення PID. +- Виконання `%unshare -fp /bin/bash%` забезпечує, що команда `unshare` сама стає PID 1 у новому просторі. `/bin/bash` та його дочірні процеси тоді безпечно містяться в цьому новому просторі, запобігаючи передчасному виходу PID 1 та дозволяючи нормальне виділення PID. -Забезпечуючи, що `unshare` виконується з прапором `-f`, новий PID простір правильно підтримується, що дозволяє `/bin/bash` та його підпроцесам працювати без виникнення помилки виділення пам'яті. +Забезпечивши, що `unshare` виконується з прапором `-f`, новий PID простір правильно підтримується, що дозволяє `/bin/bash` та його підпроцесам працювати без виникнення помилки виділення пам'яті. @@ -59,4 +59,82 @@ sudo find /proc -maxdepth 3 -type l -name time -exec ls -l {} \; 2>/dev/null | ```bash nsenter -T TARGET_PID --pid /bin/bash ``` +## Маніпулювання часовими зсувами + +Починаючи з Linux 5.6, два годинники можуть бути віртуалізовані для кожного простору часу: + +* `CLOCK_MONOTONIC` +* `CLOCK_BOOTTIME` + +Їхні делти на кожен простір часу відкриті (і можуть бути змінені) через файл `/proc//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` виглядає так: +```json +{ +"linux": { +"namespaces": [ +{"type": "time"} +], +"timeOffsets": { +"monotonic": 86400, +"boottime": 600 +} +} +} +``` +Потім запустіть контейнер за допомогою `runc run `. + +> ЗАУВАЖТЕ: runc **1.2.6** (лютий 2025) виправив помилку "exec into container with private timens", яка могла призвести до зависання та потенційного DoS. Переконайтеся, що ви використовуєте версію ≥ 1.2.6 у виробництві. + +--- + +## Розгляди безпеки + +1. **Необхідна можливість** – Процес потребує **CAP_SYS_TIME** всередині свого простору імен користувача/часу, щоб змінити зсуви. Відмова від цієї можливості в контейнері (за замовчуванням у Docker та Kubernetes) запобігає маніпуляціям. +2. **Без змін годинника** – Оскільки `CLOCK_REALTIME` спільний з хостом, зловмисники не можуть підробити терміни дії сертифікатів, терміни дії JWT тощо лише за допомогою timens. +3. **Уникнення журналювання/виявлення** – Програмне забезпечення, яке покладається на `CLOCK_MONOTONIC` (наприклад, обмежувачі швидкості на основі часу безперервної роботи), може бути заплутаним, якщо користувач простору імен регулює зсув. Віддавайте перевагу `CLOCK_REALTIME` для часових міток, що мають значення для безпеки. +4. **Поверхня атаки ядра** – Навіть якщо `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 – Сторінка посібника по просторах імен часу: +* Блог OCI – "OCI v1.1: нові простори імен часу та RDT" (15 листопада 2023): + {{#include ../../../../banners/hacktricks-training.md}}