Членство в групі та встановлення / встановлення жорстких процесів


10

Процеси, які деескалюють привілеї через setuid()і setgid(), схоже, не успадковують членство в групі встановленого uid / gid.

У мене є серверний процес, який повинен бути виконаний як root, щоб відкрити привілейований порт; після цього він деескалює до конкретного непривілейованого uid / gid, 1 - наприклад, користувача foo(UID 73). Користувач fooє членом групи bar:

> cat /etc/group | grep bar
bar:x:54:foo

Отже, якщо я ввійду як foo, я можу прочитати файл /test.txtіз цими характеристиками:

> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar  8 16:22 /test.txt

Однак наступна програма C (компілюється std=gnu99) при запуску root:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main (void) {
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}   

Завжди у звітах у дозволі відмовлено . Я гадаю, що це пов'язане з тим, що це процес без входу в систему, але це певна зміна способів роботи дозволів.


1. Що часто є SOP для серверів, і я думаю, що це повинно бути обійти, оскільки я знайшов повідомлення про те, що хтось робить це з apache - apache додано в аудіогрупу і, очевидно, потім може використовувати звукову систему. Звичайно, це, швидше за все, відбувається у вилці, а не в оригінальному процесі, але насправді в моєму контексті справа однакова (це дочірній процес, розщеплений після встановленого виклику).


Перемикайте setuid()/ setgid()дзвінки навколо.
фонбранд

@vonbrand ROTFL Мені здалося, що я маю на собі лопатку для обличчя - але такий же результат, тому я відредагую питання про усунення червоної оселедця.
золотинок

1
Якщо ви використовуєте setgid(54)замість setgid(73)(як у /etc/groups, група barмає gid 54), чи це працює?
lgeorget

@lgeorget Звичайно, але це перемагає мету. Процес потребує власного GID з інших причин, а також, ці файли повинні мати дозволи, які вони мають. Ось чому необхідне членство в множині груп - наприклад, що робити, якщо у вас є два користувачі, які повинні це зробити. Зауважте, ви не можете setuid()знову після того, як ви це зробите ... але, хммм ... я думаю, ви можете з seteuid()...
goldilocks

1
Моє запитання полягало у тому, щоб бути впевненим, що десь немає іншої прихованої тонкої проблеми. :-)
lgeorget

Відповіді:


14

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

  • його UID
  • його ГІД
  • додаткові його групи
  • його можливості.

Дивіться, man 7 credentialsщоб отримати більш детальний огляд. Отже, у вашому випадку проблема полягає в тому, що ви правильно встановили UID та GID, але не встановили додаткові групи процесу. І група barмає GID 54, немає 73, тому вона не розпізнається як група, в якій знаходиться ваш процес.

Ви повинні робити

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>

int main (void) {
    gid_t supplementary_groups[] = {54};

    setgroups(1, supplementary_groups);
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}  

1
Це було цікаве питання, яке заслуговує на більшу суму, оскільки воно може бути корисним для багатьох людей там. :-)
lgeorget

Тож у мене виникли подібні проблеми із послідовними портами. Я реалізував це для dialoutгрупи, і це спрацювало вперше.
tl8

0

Гаразд, трошки полазив по мережі. Спочатку я думав, що APUE візьме на себе всі відповіді, але помилився. І моя копія (старе видання) працює, так що ... Посібник з адміністрації Unix та Linux, глава 5, виглядає багатообіцяюче, але я цього не отримав (просто копія перших двох видань, також на роботі).

Невеликі ресурси, які я знайшов (google для "daemon write unix"), всі говорять про важливі кроки, як, наприклад, відмежуватися від tty тощо. Але нічого про UID / GID. Як не дивно, навіть у великій колекції HOWTO на http://tldp.org не здається деталей. Тільки excetion Джейсон Шорти напише Linux Daemon - частина I . Повна інформація про те, як SUID / SGID та все, що працює, - це демістифікований SUID Чена, Вагнера та Діна (стаття в USENIX 2002). Але будьте обережні, у Linux є додатковий UID, FSUID (див. Примітки щодо несумісності Wolter Unix: Налаштування функцій UID для обговорення).

Демонізувати процес, безумовно, не для слабкого серця. Загальні міркування щодо безпеки наведені в безпечному програмуванні D. Wheeler для Linux та Unix HOWTO - Створення захищеного програмного забезпечення . Systemd обіцяє спростити більшу частину цього (і, таким чином, зменшивши місце для помилок, які призводять до проблем із безпекою), дивіться посібник із демона .


1
Питання не в демонізації. Ви переплутали біт SUID (надаючи процесу дозволу власника його виконуваного файлу) setuid(), що дозволяє процесу змінювати його UID довільно. Зазвичай SUID призначений для того, щоб дозволити ескалацію дозволів (непривілейований -> привілей), тоді як setuid()можна зробити лише зворотне.
золотинок
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.