b8c4c21f

Подмена идентификатора


Утилиты su и sudo имеют некоторую странность, объяснить которую Мефодий пока не в состоянии. Эта же странность распространяется и на давно известную программу passwd, которая позволяет редактировать собственную учетную запись. Запускаемый процесс наследует

UID от родительского, поэтому если этот UID – не нулевой, он не в состоянии поменять его. Тогда как же su запускает для обычного пользователя суперпользовательский shell? Как passwd получает доступ к хранилищу всех учетных записей? Должен существовать механизм, позволяющий пользователю запускать процессы с идентификаторами другого пользователя, причем механизм строго контролируемый, иначе с его помощью можно натворить немало бед.

В Linux этот механизм называется подменой идентификатора и устроен очень просто. Процесс может сменить свой UID, если запустит вместо себя при помощи exec() другую программу из файла, имеющего специальный атрибут SetUID2). В этом случае UID процесса становится равным UID файла, из которого программа была запущена:

[foreigner@somewhere foreigner]$ ls -l /usr/bin/passwd /bin/su -rws--x--x 1 root root 19400 Фев 9 2004 /bin/su -rws--x--x 1 root root 5704 Янв 18 2004 /usr/bin/passwd [foreigner@somewhere foreigner]$ ls -l /etc/shadow -r-------- 1 root root 5665 Сен 10 02:08 /etc/shadow

Пример 6.11. Обычная программа passwd, использующая SetUID (html, txt)

Как и в случае с t-атрибутом, ls выводит букву "s" вместо буквы "x" в тройке "для хозяина". Точно так же, если соответствующего x-атрибута нет (что бывает редко), ls выведет "S" вместо "s". Во многих дистрибутивах Linux и /bin/su, и /usr/bin/passwd имеют установленный SetUID и принадлежат пользователю root, что и позволяет su запускать процессы с правами этого пользователя (а значит, и любого другого), а passwd – модифицировать файл /etc/shadow, содержащий в таких системах сведения обо всех учетных записях. Как правило, файлы с атрибутом SetUID доступны обычным пользователям только на выполнение, чтобы не провоцировать пользователей рассматривать содержимое этих файлов и исследовать их недокументированные возможности. Ведь если обнаружится способ заставить, допустим, программу passwd выполнить любую другую программу, то все проблемы с защитой системы от взлома будут разом решены – нет защиты, нет и проблемы.

Однако Мефодий работает с такой системой, где /usr/bin/passwd вообще не имеет атрибута SetUID. Зато эта программа принадлежит группе shadow и имеет другой атрибут, SetGID, так что при ее запуске процесс получает идентификатор группы shadow. Утилита ls выводит SetGID в виде "s" вместо "x" во второй тройке атрибутов ("для группы"). Замечания касательно "s", "S" и "x" действительны для SetGID так же, как и для SetUID:

[root@localhost root]# ls -l /usr/bin/passwd -rwx--s--x 1 root shadow 5704 Jan 18 2004 /usr/bin/passwd [root@localhost root]# ls -al /etc/tcb/methody total 3 drwx--s--- 2 methody auth 1024 Sep 22 12:58 . drwx--x--- 55 root shadow 1024 Sep 22 18:41 .. -rw-r----- 1 methody auth 81 Sep 22 12:58 shadow -rw------- 1 methody auth 0 Sep 12 13:58 shadow- -rw------- 1 methody auth 0 Sep 12 13:58 shadow.lock


Пример 6.12. Не подверженная взлому программа passwd, использующая SetGID (html, txt)

Каталог /etc/tcb в этой системе содержит подкаталоги, соответствующие входным именам всех ее пользователей. В каждом подкаталоге хранится, в числе прочего, собственный файл shadow соответствующего пользователя. Доступ к каталогу /etc/tcb на использование (а, следовательно, и ко всем его подкаталогам) имеют, кроме root, только члены группы shadow. Доступ на запись к каталогу /etc/tcb/methody и к файлу /etc/tcb/methody/shadow имеет только пользователь methody. Значит, чтобы изменить что-либо в этом файле, процесс обязан иметь UID methody и GID shadow (или нулевой UID, конечно). Именно такой процесс запускается из /usr/bin/passwd: он наследует UID у командного интерпретатора и получает GID shadow из-за атрибута SetGID. Выходит, что даже найдя в программе passwd ошибки и заставив ее делать что угодно, злоумышленник всего только и сможет, что... отредактировать собственную

учетную запись!

Оказывается, атрибут SetGID можно присваивать каталогам. В последнем примере каталог /etc/tcb/methody имел SetGID, поэтому все создаваемые в нем файлы получают GID, равный GID самого каталога – auth. Используется это разнообразными процессами идентификации, которые, не будучи суперпользовательскими, но входя в группу auth и shadow, могут прочесть информацию из файлов /etc/tcb/входное_имя/shadow.

Вполне очевидно, что подмена идентификатора распространяется на программы, но не работает для сценариев. В самом деле, при исполнении сценария процесс запускается не из него, а из программы-интерпретатора. Файл со сценарием передается всего лишь как параметр командной строки, и подавляющее большинство интерпретаторов просто не обращают внимания на атрибуты этого файла. Интерпретатор наследует UID у родительского процесса, так что если он и обнаружит SetUID у сценария, поделать он все равно ничего не сможет.


Содержание раздела