LXF125:DrBrown3

Материал из Linuxformat.

Перейти к: навигация, поиск

Содержание

Сказание о трех битах

Биты режима Прослывите на работе матерым хакером, обретя знания о setuid, setgid и загадочном sticky bit.

Большинство людей знает о девяти битах, определяющих права доступа к файлу – rwxrwxrwx – но есть еще три, которые не столь известны. В этом месяце я решил вывести их на сцену. Это (слева направо):

  • Бит установки идентификатора пользователя; друзья зовут его setuid.
  • Бит установки идентификатора группы; сокращенно setgid.
  • «Липкий» бит (sticky bit).

Установить и сбросить эти биты, как и остальные биты режима, можно с помощью chmod. Например, команды

$ chmod u+s foo
$ chmod g+s foo
$ chmod +t foo

включат setuid, setgid и sticky bit соответственно. Если вы предпочитаете задавать режимы доступа восьмеричными числами, знайте, что setuid имеет значение 4000, setgid2000, а sticky bit1000. Таким образом, команда

$ chmod 4755 foo

сделает файл foo исполняемым для всех и включит бит setuid.

Битком набито

На рисунке показано, как биты выполнения перезаписываются, чтобы показать наши три бита.

Файлов, у которых setuid, setgid и sticky bit установлены, относительно немного, и встретишь их нечасто. Но их можно легко найти с помощью опции -perm команды find.

Следующая команда найдет все файлы, у которых установлен setuid на пользователя root:

$ sudo find / -perm /4000 -user root

следующая – все каталоги, у которых установлен setgid:

sudo find / -type d -perm /2000

следующая – все каталоги с установленным sticky bit:

sudo find / -type d -perm /1000

Проверьте также, есть ли хотя бы один файл со sticky bit (скорее всего, таких нет):

sudo find / -type f -perm /1000

Понимание вывода команды ls -l

В выводе команды ls -l эти биты представлены довольно необычно. Казалось бы, проще всего было добавить три символа в начало строки. Вместо этого три символа прав на исполнение замещаются, как показано на рисунке. Таким образом, бит setuid отображается как ‘s’ на месте бита прав на исполнение для владельца файла, setgid – на месте бита прав на исполнение для группы, а sticky bit отображается как ‘t’ на месте бита прав на исполнение для всех остальных.

Следующие команды помогут разобраться в этом:

$ls -l foo
-rwxr-xr-x 1 chris chris 833592 2009-08-16 11:07 foo
$ chmod u+s foo # Установим setuid
$ls- l foo
-rwsr-xr-x 1 chris chris 833592 2009-08-16 11:07 foo
$ chmod g+s foo # Установим setgid
$ls -l foo
-rwsr-sr-x 1 chris chris 833592 2009-08-16 11:07 foo
$ chmod +t foo # Установим sticky bit
$ls -l foo
-rwsr-sr-t 1 chris chris 833592 2009-08 -16 11:07 foo
$ chmod 4755 foo # setuid bit, using octal
$ls -l foo
-rwsr-xr-x 1 chris chris 833592 2009-08-16 11:07 foo

И еще одна штука, о которой знают немногие. Так как ‘s’ или ‘t’ вытесняют ‘x’, как понять, установлено для файла право на исполнение или нет? Ответ: если оно не установлено, вы увидите заглавные ‘S’ или ‘T’ вместо строчных. Например:

$ chmod 4644 foo
$ls -l foo
-rwSr--r -- 1 chris chris 833592 2009-08-16 10:51 foo

Такого быть не должно. Если программа работает в режиме setuid, она обязана быть исполняемой. Вот крайний случай:

$ chmod 7000 foo
$ls -l foo
---S--S--T 1 chris chris 833592 2009-08-16 11:07 foo

Я смог придумать только одно применение этого примера: показать нахальному сисадмину с вашей работы, что вы еще покруче него.

Setuid сияет

Теперь, разобравшись, как задать и отобразить эти расширенные права, изучим, что они, собственно, делают. А попутно рассмотрим случаи, когда эти права вам пригодятся.

Гвоздь программы – несомненно, setuid. Если установить его исполняемому файлу, он повысит действующий идентификатор пользователя процесса, выполняющего файл, до владельца программы, которым обычно является root. Обратите внимание, что у каждого процесса есть две «личности»: реальная и действующая. При принятии решений, связанных с предоставлением процессу доступа к ресурсам, используется действующая. Если бит setuid не установлен, реальная и действующая «личности» одинаковы. Значение этой простой, но элегантной возможности в Linux трудно переоценить, потому что она лежит в сердце всех утилит, отвечающих за повышение привилегий, таких как sudo.

Найти применение для setuid нетрудно. Предположим, вы написали игру (назовем ее Spacewar, хотя я боюсь, что это название уже украли в 1961 году) и хотели бы работать с файлом, содержащим таблицу из 10 рекордных результатов игроков. Конечно, просто открыть его на запись для всех нельзя – игроки сжульничают; но программа должна иметь возможность сохранять там очки от имени игрока, если он решит, что результат того достоин. Итак, вы создаете новую учетную запись пользователя; назовем его spaceman. Вы запрещаете непосредственный вход в систему с этой записи – она существует только затем, чтобы дать владельца файлу турнирной таблицы. Теперь создайте файл таблицы, позаботившись, чтобы ее владельцем стал spaceman и право на запись было только у него. Сделать это можно примерно так:

# cd /var/run
# mkdir spacewar
# cd spacewar
# touch league-table
# chown spaceman league-table
# chmod 644 league-table

Создастся файл, который смогут читать все, но изменять – только spaceman.

Вторая часть трюка – сделать так, чтобы программа запускалась с setuid на пользователя spaceman таким образом:

# cd /usr/local/bin
# chown spaceman spacewar
# chmod 4755 spacewar

Теперь запускать spacewar смогут все. При этом она выполнится с эффективными правами пользователя spaceman, а значит, сможет писать в файл турнирной таблицы.

Углубляемся в setuid

Классический пример программы с setuidpasswd, утилита, позволяющая пользователям менять пароли путем записи хэша нового пароля в /etc/shadow. Посмотрите внимательно на владельцев и права доступа в следующем примере:

$ ls -l /usr/bin/passwd /etc/shadow
-rw-r----- 1 root shadow 1262 2009-08-04 16:16 /etc/shadow
-rwsr-xr-x 1 root root 42776 2009-04-04 06:50 /usr/bin/passwd

Программа смены пароля имеет права на выполнение для всех и запускается с setuid на пользователя root, что дает ей возможность записывать данные в файл shadow.

Программы, у которых установлен setuid, особенно если их владельцем является root, должны быть надежными и устойчивыми к попыткам заставить их делать вещи, не входившие в замысел автора. Принцип наименьших привилегий предполагает, что если нужно поднять привилегии, то лучше делать это не с пользователем root, как в нашем примере со spaceman. С этими словами я насчитал в RHEL5 34 программы с установленным setuid, и владельцем каждой был root!

Бит setuid представляет собой реальную угрозу безопасности, когда используется в сочетании со сменными дисками. Это происходит так: Мистер Нехороший Человек на домашнем компьютере записывает на CD копию Bash с владельцем root и включенным setuid. Потом приносит диск на работу, вставляет его в сервер, ждет, пока он автоматически смонтируется – и вот он в консоли root. Как пресечь его злодеяния? Ну, по умолчанию только у пользователя root есть право монтировать файловые системы. Чтобы остальные пользователи могли монтировать сменные диски, в файле /etc/fstab есть запись с опцией монтирования user. Эта опция подразумевает noexec, nosuid и nodev; среди прочего, это означает что бит setuid не будет учитываться ни в одном файле в этих файловых системах.

Патент на setuid

Деннис Ритчи [Dennis Ritchie], изобретатель механизма setuid, запатентовал его в 1973 году (Патент США 4135240). Патент описывал бит через логическую схему, потому что тогда никто не был уверен, что программные реализации можно патентовать. Патент содержал фразу: «Функционально эквивалентная программная реализация признается частью описанного здесь вклада изобретателя. Для определенных целей программная реализация может быть более предпочтительной». Кстати, слово «предпочтительной» содержало ошибку. Патент можно найти на сайте http://patft.uspto.gov. Его стоит прочесть, пожалуй, только как образец искусства запутывания юристов-патентоведов. Один из самых светлых пассажей гласит: «Посредством чего вышеуказанный текущий пользователь может получить выборочный доступ к файлам вышеупомянутой компьютерной системы, владельцем которых является указанный пользователь, во время исполнения указанных команд программы». Ну, как?

Дуг Маклрой [Doug Mcllroy], бывший глава исследовательского отдела Bell Labs, в котором родился Unix, прокомментировал: «AT&t распространяла Unix, понимая, что с пользователей можно будет собирать лицензионные платежи, когда будет выдан патент на setuid. Когда это, наконец, произошло, логистические проблемы сбора мелких лицензионных платежей с сотен лицензий показались не стоящими усилий, и патент был передан в общественное достояние». И это удача, потому что воплотить Linux таким, как он есть сейчас, без постоянного нарушения этого патента было бы невозможно.

За дело берется setgid

Бит setgid в примении к исполняемому файлу похож на setuid, но он устанавливает эффективный идентификатор группы процесса в идентификатор группы исполняемого файла. Это другой способ повышения привилегий. Мне сложнее найти пример его эффективного использования, хотя, например, он применяется postdrop и postqueue, компонентами почтовой системы Postfix. Но мне всегда казалось, что setgid находится немного в стороне по сравнению с setuid, как этакий предпоследний из могикан. Однако в дополнение к основной работе у setgid есть еще одна функция, применяемая к каталогам: он изменяет правила получения группы владельца для файлов, создаваемых в каталоге. Обычное правило, конечно, таково: группа создаваемого файла есть основная группа его создателя. Если установлен бит setgid, группа файла наследуется от группы каталога. Это удобно в некоторых интересных случаях разделения групп.

Sticky bit возвращается

Во времена юности Unix sticky bit означал: сохранить образ этого исполняемого файла на устройстве подкачки после того, как его выполнение закончено, потому что есть вероятность, что скоро он понадобится снова. Он мог бы использоваться в программах вроде оболочки, редактора и компилятора C. Более быстрые диски и виртуальная память с подкачкой страниц по требованию сделали этот бит ненужным, и его карьера пошла на спад. На долгие годы о нем забыли. Однако недавно он вернулся в Linux в совершенно новом качестве. Применительно к каталогу он изменяет правила, касающиеся того, кто может удалять файлы в этом каталоге. Без sticky bit все пользователи, у которых есть права на запись в каталог, могут удалять файлы в нем (даже если они не являются их владельцами). Установка «липкого» бита меняет правила – с ним можно удалять только те файлы, владельцем которых вы являетесь. Вообще нужно было назвать его битом ограниченного удаления, но sticky bit к нему, э-э... прилипло. Классический пример его использования – временные каталоги, вроде /tmp. В отношении обычных файлов Linux этот бит ничего не меняет.

Бит Восьмеричное значение Значение для файла Значение для каталога
Setuid 4000 Файл выполняется с действующим UID владельца Игнорируется
Setgid 2000 Файл выполняется с действующим GID группы Файлы, создаваемые в каталоге, наследуют группу от группы каталога
Sticky 1000 Игнорируется Файлы в каталоге могут быть удалены только их владельцем
Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию