LINUX.ORG.RU

Как работает подмена идентификатора?

 


0

1

Всем привет! Немного не понятно как работает подмена идентификатора. Например, я использую sudo, чтобы запустить программу от рута. Т.е нужно изменить UID, на UID рута. Для этого наш процесс пользуется /etc/passwd с атрибутами SetUID. В книжке написано:

«Процесс может сменить свой UID, если запустит вместо себя при помощи exec() другую программу из файла, имеющего атрибут SetUID.Тогда UID процесса станет равным UID файла.»

Что значит запустит из файла? С SetGID безопаснее как написано, но чем безопаснее?

Спасибо!


Значит с помощью системного вызова exec() процесс попросит ОС считать из файла программу в память и заменить ей себя. Если на файле стоит бит SUID и/или SGID, Effective UID/GID получившегося процесса станет таким, как UDI/GID владельца файла. Real UID останется старым.

selivan ★★★
()

Безопаснее позволить пользователю запускать от имени другого пользователя(как правило, root) только определённый набор файлов, чем выдать пользователю возможность перелогиниваться в другого пользователя и запускать от его имени любые процессы.

Но это тоже не лучщий подход, уже давно есть POSIX capabilities, позволяющие ещё более тонко выдать права на исполнение функций, доступных только суперпользователю.

selivan ★★★
()

Выше объяснили практику. А я поясню теорию. Дело в том, что SUID бит наследуется процессами. Соответственно sudo проверяет, что тебе можно запускать приложение от того или иного пользователя и создаёт субпроцесс.

Отдельно стоит root. Если ты запустишь id от рута ты узнаешь, что его идентификатор 0. Это особый идентификатор. Дело в том, что проверки для него не осуществляются вообще. И это не от имени пользователя зависит, а именно от идентфикатора.

Можешь создать пользователя с любым другим именем. Если у него 0 идентификатор, то он рут.

ziemin ★★
()
Ответ на: комментарий от selivan

Спасибо за ответы!!

Это я понимаю, я не понимаю, что значит программу считать из файла? Вот есть /etc/passwd, там бит стоит, но что оттуда можно считать? Просто вот я вбиваю sudo процесс, что происходит дальше?

aarexer
() автор топика
Ответ на: комментарий от aarexer

Просто вот я вбиваю sudo процесс, что происходит дальше?

sh делает fork() и затем exec(«sudo», «процесс»). Запускается бинарник /usr/bin/sudo (ну или хз, где он лежит в твоей системе). У этого бинарника установлен бит SUID, поэтому UID процесса менятся на 0.

sudo спрашивает у тебя пароль и проверяет его по базе данных (/etc/passwd). затем по файлу /etc/sudoers проверяет, что ты имеешь право выполнять указанную команду. Если пароль верный, и в /etc/sudoers тебе разрешения есть, оно делает exec(«процесс»). В ином случае, посылает тебя на хрен.

anonymous
()
Ответ на: комментарий от anonymous

sudo спрашивает у тебя пароль и проверяет его по базе данных (/etc/passwd)

Пардон, ошибся. Пароли проверяются не по /etc/passwd, а по /etc/shadow. По /etc/passwd они проверялись в стародавние времена.

anonymous
()
Ответ на: комментарий от aarexer

0. Шелл распарсивает аргументы команды: раскрывает переменные, шаблоны имён файлов, выполняет встроенные подкоманды, если такие есть
1. Шелл ищет, что такое sudo: built-in ключевое слово, alias или файл в PATH
2. Шелл находит sudo, например, в /usr/bin/sudo
3. Шелл делает какой-то из системных вызовов семейства fork()
4. Родительский и дочерний процессы получают разные коды выхода от fork(). Тот, кто оказался дочерним, запускает вызов семейства exec() с аргументом /usr/bin/sudo
5. Если у пользователя, запустившего шелл, есть права на исполнение /usr/bin/sudo, операционная система загружает вмсето дочернего процесса программу из файла /usr/bin/sudo
6. Т. к. на /usr/bin/sudo стоит SUID-бит, получившийся процесс будет иметь Effective UID пользователя-владельца файла, то есть root
7. Запущенный с помощью fork() процесс унаследует от родителя все дескрипторы открытых файлов, в том числе 0,1 и 2, отвечающие за привязку ввода/вывода к соотв. консоли. После выполнения exec() дескрипторы также сохранятся. Также сохранится environment - переменные и их значения.
8. Программа sudo, запущенная с RUID=user и EUID=root, в свою очередь парсит переданные ей шеллом аргументы. Один(часто первый) из них - программа, которую оно так же как шелл ищёт в PATH; все последующие - её аргументы
9. sudo считывает настройки из /etc/sudoers
10. В настройках проверяется, имеет ли право пользователь запускать эту программу от имени другого пользователя(как правило, root)
11. Если можно - будет запрошен пароль или другой способ аутентификации пользователя(отпечаток пальца, фото морды лица) в соответствии с настройками linux pam в etc/pam.d/sudo. Или нет, если в sudoers стоит NOPASSWD
12. Предоставленные для аутентификации данные будут проверены с помощью linux PAM. Будут сделаны соотв. системные вызовы. Пароль может храниться в /etc/shadow в захешированном виде, может запрашиваться из LDAP, может откуда-то ещё
13. Если аутентификация ОК, будет сделан системный вызов семейства setuid(), чтобы сменить uid процесса, а потом - exec(), чтобы загрузить соотв. программу. Ей будут переданы все оставшиеся аргументы, которые не имели отношения к самому sudo. Т. к. RUID=0 благодаря SUID-биту, sudo имеет право сделать setuid() и стать любым другим пользователем. Прохождение аутентификации при этом не требуется, то есть пользователю может быть запрещён вход в систему, но с помощью sudo мы можем выполнять от его лица команды

Когда я говорю «вызов семейства fork()», имеется в виду, что в linux есть несколько системных вызовов, с похожей функциональностью и названиями. Какой именно будет использован - зависит от реализации, но общая идея та же.

selivan ★★★
()
Последнее исправление: selivan (всего исправлений: 2)
Ответ на: комментарий от anonymous

У этого бинарника установлен бит SUID, поэтому UID процесса менятся на 0

Задачка: sudo chmod +s /usr/bin/bash; запускаем баш, смотрим, что скажет id; запускаем bash -p и опять смотрим на вывод id.

man getuid
man geteuid
man setuid
naszar
()
Ответ на: комментарий от naszar

Шарик, ты балбес

man getuid
man geteuid
man setuid

Лол. Ты мне собрался устройство юниксового DAC рассказывать что ли? Иди сам поучи, я эти вещи знал еще в ту пору, когда ты про LOR не слышал даже.

Задачка

Задачка: объяснить TCу, как работает механизм, не опускаясь припадков с посыланиями в «man setuid». Как? Справишься? Или будешь тут растекаться мыслью по дереву про отличия effective, real и saved ID, пока не вынесешь собеседнику мозг, вместо того, чтобы изложить суть?

anonymous
()

Спасибо, парни!

aarexer
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.