Файлові дозволи на Linux

Всім привіт. Ми активно вливаємося в роботу і вже у січні готуємо багато потужних запусків. Серед інших, оголошено набір на новий потік курсу, що полюбився всім «Адміністратор Linux». Напередодні запуску зазвичай ділимося перекладом корисного матеріалу.

Файлові дозволи на Linux

Файлові дозволи пропонують безпечну альтернативу файлам SUID, що виконуються, але можуть здатися трохи заплутаними на перший погляд.


Всі ми знаємо, що двійкові файли SUID є поганим рішенням з погляду безпеки. На щастя, якщо вашому додатку потрібні деякі обмежені привілеї, існує більш ефективний спосіб, що називається файловими дозволами.

Я заощаджу вам час, якщо ви хочете уникнути докладного прочитання статті вище: по суті, файлові дозволи дозволяють процесам, які запускаються від імені root-користувача і, отже, мають право щось робити, зберігати певні можливості, обмежені цим списком, коли вони скидають привілеї та запускаються непривілейованим користувачем. Це означає, що якщо зловмиснику вдасться скомпрометувати процес за допомогою переповнення буфера або іншого експлойту, він не зможе скористатися нічим, крім певних мінімальних привілеїв, які дійсно потрібні процесу.

Дозволи відмінно підходять для сервісів, які зазвичай завжди запускаються від імені root-користувача, але як щодо утиліт командного рядка? На щастя, це також підтримується за умови, що у вас встановлені правильні утиліти. Якщо ви використовуєте Ubuntu, вам, наприклад, знадобиться пакет libcap2-bin. Вам також потрібно буде запустити не архаїчне ядро ​​(починаючи з версії 2.6.24).

Ці функції дозволяють пов'язувати дозволи з файлами, що виконуються аналогічно налаштуванню біта SUID, але тільки для певного набору дозволів. Утиліта setcap використовується для додавання та видалення дозволів із файлу.

Перший крок – вибрати потрібні вам дозволи. Для цієї статті я припускаю, що існує інструмент діагностики мережі tracewalk, який має вміти використовувати необроблені сокети. Зазвичай для цього потрібно, щоб програма запускалася від імені root-користувача, але при перегляді списку з'ясовується, що потрібен лише дозвіл CAP_NET_RAW.

Припускаючи, що ви знаходитесь у каталозі, де розташований двійковий файл tracewalk, ви можете додати цей дозвіл наступним чином:

sudo setcap cap_net_raw=eip tracewalk

Поки проігноруйте суфікс =eip для дозволу, я розповім про це за пару секунд. Зверніть увагу, що ім'я дозволу у нижньому регістрі. Тепер ви можете перевірити, чи правильно ви налаштували дозволи, за допомогою:

setcap -v cap_new_raw=eip tracewalk

Або ви можете вивести список усіх дозволів, встановлених для даного файлу:

getcap tracewalk

Для довідки, ви також можете видалити всі дозволи з файлу за допомогою:

setcap -r tracewalk

На цьому етапі ви повинні мати можливість запускати виконуваний файл як непривілейований користувач, і він повинен мати можливість працювати з необробленими сокетами, але не мати інших привілеїв, якими володіє root-користувач.

Отже, що означає цей дивний суфікс =eip? Тут знадобиться частка розуміння природи дозволів. Кожен процес має три набори дозволів. ефективні, успадковані та доступні (effective, inheritable та permitted):

  • Ефективні (Effective) дозволи - це ті, які визначають, що процес може насправді робити. Наприклад, він не може мати справу з необробленими сокетами, якщо CAP_NET_RAW не в ефективному наборі.
  • Доступні (Permitted) дозволи – це ті, які дозволено мати процесу, якщо він запитує їх за допомогою відповідного виклику. Вони не дозволяють процесу фактично щось робити, якщо він не був спеціально написаний для запиту зазначеного дозволу. Це дозволяє писати процеси для додавання особливо важливих дозволів у ефективний набір лише на той період, коли вони справді потрібні.
  • Наслідувані (Inheritable) дозволи – це ті, які можуть бути успадковані у доступному наборі породженого дочірнього процесу. Під час операції fork() або clone() дочірньому процесу завжди дається копія дозволів батьківського процесу, оскільки в цей момент він все ще виконує той же файл, що виконується. Наслідуваний набір використовується, коли exec() (або аналог) викликається для заміни виконуваного файлу іншим. На цьому етапі доступний набір процесу маскується наслідуваним набором для отримання доступного набору, який використовуватиметься для нового процесу.

Таким чином, утиліта setcap дозволяє нам додавати дозволи цих трьох наборів незалежно для цього виконуваного файлу. Зверніть увагу, що значення груп інтерпретується трохи по-різному для доступу до файлів:

  • Доступні файлові дозволи – це ті, які завжди доступні для виконуваного файлу, навіть якщо батьківський процес, який викликав його, не мав їх. Раніше їх називали "примусовими" дозволами.
  • успадковані файлові дозволи визначають додаткову маску, яка також може використовуватися для видалення дозволів з набору процесу, що викликає. Вони застосовуються на додаток до наслідуваного набору процесу, тому дозвіл успадковується тільки в тому випадку, якщо вона існує в обох наборах.
  • Ефективні файлові дозволи насправді є лише один біт, а не набір, і якщо він встановлений, то це означає, що весь доступний набір також копіюється в ефективний набір нового процесу. Це може бути використане для додавання дозволів до процесів, які не були спеціально написані для їхнього запиту. Оскільки це один біт, якщо ви встановлюєте його для будь-якої роздільної здатності, він повинен бути встановлений для всіх дозволів. Ви можете думати про нього як про легасі биті, тому що він використовується, щоб дозволити використання дозволів для додатків, які їх не підтримують.

При вказівці дозволів через setcap три літери e, i и p відносяться до ефективному, успадкованому та доступному множин відповідно. Отже, більш рання специфікація:

sudo setcap cap_net_raw=eip tracewalk

… вказує, що дозвіл CAP_NET_RAW має бути додано до доступних та успадкованих наборів і що також має бути встановлений ефективний біт. Це замінить будь-які раніше встановлені дозволи у файлі. Щоб встановити відразу кілька дозволів, використовуйте список через кому:

sudo setcap cap_net_admin,cap_net_raw=eip tracewalk

Посібник із дозволів обговорює все це докладніше, але, сподіваюся, цей пост трохи демістифікував те, що відбувається. Залишилося згадати лише кілька застережень та хитрощів.

По-перше, файлові можливості не працюють із симлінками - ви повинні застосувати їх до самого двійкового файлу (тобто до мети симлінка).

По-друге, вони не працюють з скриптами, що інтерпретуються. Наприклад, якщо ви маєте скрипт Python, якому ви хочете призначити дозвіл, ви повинні призначити його самому інтерпретатору Python. Очевидно, що це потенційна проблема безпеки, тому що тоді всі скрипти, що виконуються з цим інтерпретатором, матимуть зазначений дозвіл, хоча це все ж таки значно краще, ніж зробити SUID. Найбільш поширений обхідний шлях, мабуть, полягає в написанні окремого файлу, що виконується на C або аналогу, який може виконувати необхідні операції і викликати його зі скрипту. Це схоже на підхід, який використовується Wireshark, який використовує двійковий файл /usr/bin/dumpcap для виконання привілейованих операцій:

$ getcap /usr/bin/dumpcap 
/usr/bin/dumpcap = cap_net_admin,cap_net_raw+eip

По-третє, файлові дозволи відключаються, якщо ви використовуєте змінне середовище LD_LIBRARY_PATH зі зрозумілих причин безпеки(1). Те ж саме стосується і LD_PRELOAD, наскільки я знаю.

1. Оскільки зловмисник, очевидно, може підмінити одну із стандартних бібліотек та використовувати LD_LIBRARY_PATH, щоб змусити свою бібліотеку викликатися у перевагу перед системною, і, отже, мати власний довільний код, що виконується з тими ж привілеями, що і додаток, що викликає.

На цьому все. Детально про програму курсу, можна буде дізнатися на вебінарі, що пройде 24 січня.

Джерело: habr.com

Додати коментар або відгук