Setuid (Set User ID) — это специальный атрибут прав доступа в Linux/Unix, который позволяет пользователю выполнять программу с правами владельца этой программы, а не с правами самого пользователя.

Простая аналогия:

Представьте, что в офисе есть сейф, который может открывать только начальник. Обычным сотрудникам вход запрещен. Но начальник дает секретарю особый пропуск (setuid-бит), с помощью которого секретарь может открыть сейф, хотя сам не является начальником.

Для чего нужны setuid биты?

Основные случаи использования:

  1. Смена пароля (/usr/bin/passwd)

    1
    2
    
    ls -la /usr/bin/passwd
    -rwsr-xr-x 1 root root 68208 апр  8 10:15 /usr/bin/passwd
    
    • Обычный пользователь должен менять свой пароль
    • Пароли хранятся в защищенном файле /etc/shadow, доступном только root
    • Setuid позволяет passwd временно получить права root для записи в /etc/shadow
  2. Команда sudo (/usr/bin/sudo)

    1
    2
    
    ls -la /usr/bin/sudo
    -rwsr-xr-x 1 root root 232416 фев  9  2024 /usr/bin/sudo
    
    • Позволяет выполнять команды от имени root
    • Без setuid sudo не сможет повысить привилегии
  3. Другие примеры:

    • ping — требует root для создания сетевых сокетов
    • su — переключение на другого пользователя
    • mount/umount — монтирование файловых систем

Как распознать setuid биты?

Визуальное обозначение:

1
2
3
4
5
6
7
8
# Обычный файл
-rwxr-xr-x  # нет setuid

# Файл с setuid (s вместо x в позиции владельца)
-rwsr-xr-x  # есть setuid

# Файл с setgid (s вместо x в позиции группы)
-rwxr-sr-x  # есть setgid

Буква s в позиции execute (x) означает, что установлен setuid/setgid бит.

Как просмотреть все файлы с setuid:

  1. Поиск по всей системе:

    1
    
    sudo find / -type f -perm -4000 -ls 2>/dev/null
    
  2. Только в стандартных директориях:

    1
    
    sudo find /usr/bin /usr/sbin /bin /sbin -type f -perm -4000 -ls
    
  3. С подробной информацией:

    1
    2
    3
    4
    5
    
    # С владельцем и правами
    sudo find /usr -type f -perm -4000 -exec ls -la {} \; 2>/dev/null
    
    # Или более компактно
    sudo find /usr/bin -type f -perm -4000 | xargs ls -la
    
  4. Числовое представление:

    1
    
    stat /usr/bin/sudo | grep Access
    

    Setuid бит = 4000 в восьмеричной системе (4 = setuid, 2 = setgid, 1 = sticky bit)

Как установить/убрать setuid бит:

Символический способ:

1
2
3
4
5
# Установить setuid
sudo chmod u+s /path/to/file

# Убрать setuid
sudo chmod u-s /path/to/file

Числовой способ:

1
2
3
4
5
# Установить (4755 = setuid + 755 права)
sudo chmod 4755 /path/to/file

# Убрать (755 = обычные права)
sudo chmod 755 /path/to/file

Почему это важно для безопасности?

Риски:

  1. Вредоносные программы могут использовать setuid для получения root-доступа
  2. Ошибки в setuid-программах — частая причина взломов
  3. Лишние setuid биты расширяют поверхность атаки

Аудит безопасности:

1
2
3
4
5
# Найти все setuid файлы для проверки
sudo find / -type f -perm -4000 -ls 2>/dev/null | sort

# Сравнить с "чистой" системой
# Неожиданные setuid файлы должны настораживать

Практический пример из моей практики:

Я где-то ошибся и сделал своего пользвоателя владельцем /usr/, слом судо и пока пытался починить выполнил find /usr -type d -exec chmod 755 {} \;, это не затронуло файлы. Но когда следом сделал:

1
sudo find /usr -type f -exec chmod 644 {} \;

Эта команда сбросила setuid биты на всех файлах, включая sudo, passwd и другие. Поэтому sudo опять перестал работать.

Правильно было бы:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Сначала сохранить список setuid файлов
sudo find /usr -type f -perm -4000 > /tmp/setuid_backup.txt

# Потом менять права
sudo find /usr -type f -exec chmod 644 {} \;

# И восстановить setuid биты из сохраненного списка
while read file; do
  sudo chmod 4755 "$file"
done < /tmp/setuid_backup.txt