Linux не работает suid

Обновлено: 03.07.2024

Предисловие. Некогда в июне 2001 года в журнале «Системный администратор» (Sys Admin Magazine, June 2001, Volume 10, Number 6) была опубликована статья Томаса Акина «Danger of SUID Shell Scripts», которая не теряет своей актуальности и сегодня. К сожалению, в конце лета 2007 года журнал перестал выходить. По неизвестным мне причинам сайт журнала также прекратил существование — точнее он сейчас переадресовывает посетителей на другой. Было бы здорово, если бы сайт просто «заморозили», сохранив архив всех накопившихся материалов, который бесспорно представил бы собой кладезь полезной практической информации для специалистов сферы ИТ. В Сети можно найти скудные копии статьи, о которой идет речь; у меня же нашелся бумажный вариант оригинала и я хочу представить вольный перевод с небольшим дополнением. Некоторые моменты статьи мне кажутся несколько глупыми (например, использование временных файлов), некоторые — непривычными (оболочки, которые использует автор), но в целом я уверен — в статье есть на что обратить внимание, взять на заметку и не забывать.

Опасность использования SUID в сценариях командной оболочки

Уровень сложности: простой

Некоторые соглашения. SUID-программы, SUID-приложения — исполняемые файлы, имеющие атрибут setuid (в дополнение к атрибуту исполнения).
SUID-сценарии, SUID-скрипты — аналогично, сценарии командного интерпретатора, имеющие атрибут setuid в дополнение к атрибуту выполнения.
Unix-система — Unix или любая Unix-подобная операционная система.

Данная статья предпринимает попытку пройтись по тонкой границе между полным раскрытием и созданием эксплойта. Целью является иллюстрация работы SUID-приложений, чтобы помочь остальным избежать распространенных ошибок при написании своих программ. Примеры, приведенные в статье, достаточно разобраны для того, чтобы помочь понять каждую опасность, но нет гарантии, что все будет работать именно так, как показано, в случае попытки злонамеренного использования.

Обычно, сценарии и программы в Unix выполняются с правами пользователя, который их запустил. Вот почему простые пользователи не могут изменить свои пароли путем прямой правки файла /etc/passwd (Unix-системы не хранят более в данном файле пароли, а только информацию об учетных записях — прим.); у них нет прав на запись в /etc/passwd и ни одна команда, выполненная ими, не сможет этого сделать. Однако, SUID-программы перекрывают нормальные права доступа и всегда выполняются с правами владельца программы. Следовательно, пользователи могут с помощью команды /usr/bin/passwd менять свои пароли. Программа /usr/bin/passwd имеет атрибут SUID и пользователя root как владельца. Она всегда выполняется с правами пользователя root:

% ls -l `which passwd`
-rwsr-xr-x 1 root root 23688 Jan 6 2007 /usr/bin/passwd

Когда начинающие администраторы открывают для себя атрибут SUID они видят его как панацею и незамедлительно начинают его использовать для программ и сценариев, чтобы упростить себе работу. К сожалению, очень часто они поступают неверно.

Работая с администраторами, которые недавно познакомились с атрибутом SUID, часто можно встретить сценарии, подобные этому:

% ls change-pass
-rwsr-x--- 1 root helpdesk
37 Feb 26 16:35 change-pass

Данный простенький скрипт призван разрешить службе поддержки (группа helpdesk) сбрасывать пароли пользователей, что является довольно частой задачей. Сценарию присвоен атрибут SUID и суперпользователь установлен в качестве владельца. Члены группы helpdesk могут читать и запускать данный сценарий на выполнение. который полон «дыр» безопасности подобно решету. В рамках статьи будут рассмотрены семь из них, а также варианты, как их избежать.

Первоочередной проблемой является использование C-shell. Сценарии этой оболочки уязвимы к манипуляциям с переменными окружения. Для того, чтобы использовать это как преимущество, взломщик может скомпроментировать учетную запись службы поддержки и получить оболочку с правами суперпользователя следующим образом:

% env TERM='`cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755/tmp/sh`' change-pass
Урок первый — никогда не используйте C-shell для SUID-сценариев

Переписав скрипт с применением Korn shell помогает избежать характерной для C-shell проблемы, однако сценарий все еще уязвим к манипуляциям с переменной окружения PATH. Использование относительного пути к программе дает возможность злоумышленнику запустить свое приложение вместо штатного /usr/bin/passwd:
% export PATH='/tmp'
% echo "cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755/tmp/sh" > /tmp/passwd
% ./change-pass

Переменная PATH была изменена и теперь команда change-pass вызовет /tmp/passwd вместо /usr/bin/passwd.

Урок второй — необходимо всегда вручную устанавливать переменную окружения PATH и использовать абсолютные пути

Теперь PATH в безопасности и используются абсолютные пути, но если присмотреться можно заметить, что сценарий может изменить пароль любого пользователя даже root. Мы ведь не хотим, чтобы кто-либо из службы поддержки (или взломщик) с помощью нашего скрипта изменить пароль суперпользователя.

Урок третий — необходимо понимать работу задействованных программ

Теперь сценарий завершит своб работу, если кто-то введет root в качестве аргумента. Однако что же произойдет, если не передать аргументов вовсе? Будет вызван passwd, соответственно, без аргументов. В таком случае программа меняет пароль текущего пользователя (инициировавшего запуск), то есть root (не забывайте, что сразу после запуска SUID сделал свое дело и изменил текущего пользователя на root — прим.). В контексте исполняемого файла с атрибутом SUID текущим пользователем всегда будет владелец этого файла. Таким образом, все еще существует возможность сбросить пароль суперпользователя, вызвав change-pass и не передав ни одного аргумента. Отсюда уточнение к третьему уроку — понимайте работу программ в сценарии, особенно то, как они обрабатывают аргументы.
Урок четвертый — не используйте временный файлы или (в случае неизбежной необходимости их применения) не помещайте их в доступные на запись остальным места

В текущем варианте не используются временные файлы (сразу бы так — прим.), но по-прежнему атакующий может использовать трюк с точкой с запятой — символом-разделителем. С помощью «;» можно в одну строку записать несколько команд, которые будут выполнены по очереди. Зная это взломщик может написать:
% change-pass "user;cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755 /tmp/sh"
/usr/bin/passwd user;cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755 /tmp/sh

Каждая из этих комманд будет выполнена, предоставляя оболочку с правами суперпользователя. Для предотвращения подобных проблем нужно убедиться, что пользовательских ввод не содержит точек с запятой или любых других мета-символов.

Теперь из ввода будут убраны символы пробела, \, $, /, ;, (, ), |, >, <, & и табуляции.

Урок пятый — не доверяйте и проверяйте весь пользовательский ввод, исключайте мета-символы

Другая распространенная уязвимость связана с внутренним разделителем полей (internal field separator, IFS) командной оболочки. IFS определяет символ, разделяющий команды. Обычно, таким является символ пробела, табуляции или новой строки. Наш сценарий вызывает программу используя полный путь /usr/bin/passwd. Замена IFS на «/» командой

заставит сценарий вызывать не /usr/bin/passwd, а вместо этого выполнить по порядку usr, bin и passwd. Теперь злоумышленник может создать скрипт с названием usr, который создает оболочку с правами root, а наш SUID-сценарий выполнит его.

Урок шестой — всегда определяйте IFS вручную

К сожалению, мы все еще не в безопасности. Сценариям командой оболочки присущи условия возникновения «гонок», которые мы не можем побороть даже написанием качественных скриптов. Проблема заключается в том, что выполнение сценария происходит в два этапа. Сначала система запускает еще один экземпляр оболочки. Затем новый процесс читает содержимое файла сценария и исполняет его. Подобно ситуации с временными файлами в четвертом уроке атакующий может эксплуатировать временные задержки и использовать момент между созданием новой оболочки и чтением скрипта. Создав символическую ссылку на SUID-сценарий
вызывая сценарий по ссылке и быстро подменяя содержимое
% ./rootme &
% rm rootme && echo "cp /bin/sh /tmp/sh;chown root /tmp/sh;chmod 4755 /tmp/sh" > rootme

возможно выполнить что угодно от имени root. Применяя такую технику шансы на успех крайне малы, но существуют методики и программы, которые повышают вероятность успеха и помогают автоматизировать процесс. Существует два способа защититься от подобного рода атак. Первый — не использовать SUID-сценарии командной оболочки. Вторым обладают некоторые системы (например, Solaris), который заключается в предотвращении возникновения условий «гонок» путем передачи описателя открытого файла сценария командной оболочке, избегая таким образом необходимости в переоткрытии и чтении файла SUID-скрипта.

Урок седьмой — не используйте SUID-сценарии

Даже после всей проделанной работы практически невозможно написать безопасный SUID-сценарий командной оболочки (это невозмножно на большинстве систем). Из-за указанных выше проблем некоторые системы (например, Linux) не поощряют установку атрибута SUID на командные сценарии. Существует три более безопасных способа получить функциональность SUID: программа-обертка на языке C, скрипт на Perl или программа подобная sudo. Начинающим в безопасном программировании следует использовать sudo или Perl-программу. Suidperl имеет втроенные механизмы защиты от ошибок программиста, описанных в статье. Дополнительную информацию о безопасном программировании с использованием атрибута SUID можно найти в книге «Practical UNIX & Internet Security» (O'Reilly & Associates) или статье «Writing Safe Setuid Programs».

вычитал что если у исполняемого файла выставвит флаг suid chmod u+s то выполнятся будет не от имени текущего пользователя а от имени хозяина файла.

только ни фига такое не рабоатает.

подскажите пожалуста какие хитрости существуют которые я не учел. потому что я уже

сделал как написано

S-бит - установка для пользователя
Все процессы в Linux выполняются с некоторым идентификатором пользователя (user-ID). Это позволяет управлять доступом процесса к ресурсам системы, файлам и т.п. Но для каждого процесса можно установить два user-ID: фактический и эффективный. Правами доступа к файлам заведует именно эффективный user-ID. Сохраните следующий скрипт idinfo и сделайте его выполнимым (chmod 755 idinfo):


Выполнив скрипт можно узнать текущие значения эффективного, фактического и группового user-ID (например для пользователя Alice):

effective user-ID:
alice
real user-ID:
alice
group ID:
users
Когда этот скрипт запустит Текс, то он увидит что-то подобное. Вывод этого скрипта зависит только от того, кто его запускает и никак не связан с тем, кто является владельцем файла.
По соображениям безопасности s-бит применим только для бинарных файлов, но не для скриптов (за исключением скриптов на языке Perl). Поэтому создадим простую С-программу, которая будет вызывать наш скрипт:

Скомпилируем программу:
"gcc -o suidtest -Wall suidtest.c"
и установим для ее владельца s-бит:


>chmod 4755 suidtest
или
>chmod u+s suidtest

>ls -l suidtest
-rwsr-xr-x 1 alice users 4741 Jan 1 21:53 suidtest
>whoami
tux
running now /home/alice/idinfo .
effective user-ID:
alice
real user-ID:
tux
group ID:
users

Когда владельцем SUID-программы является root то можно устанавливать и фактический и эффективный user-ID используя функцию setreuid().

Прием с подстановкой user-ID часто используется для того, чтобы дать обычным пользователям доступ к некоторым функциям администратора системы. Например, если вы имеет права root, то можете модифицировать нашу программу suidtest.c чтобы разрешить любому пользователю запускать скрипты ppp-on/ppp-off на вашей машине.

Знаю что suid бит не работает для скриптов , но 'sh' - полноценный ELF-ник.

В порядке эксперемента под root-ом:

Без suid-ного бита не работает , возвращаю суйдный бит chmod u+s /tmp/ping , и работает из под юзерских прав т.е. в данном случае suid-ный бит действует , но почему не работает для 'sh' , закралось подозрение что сам 'sh' обладает правами root-а ,но процессы порожденые им не наследуют эти права. Если это так можно-ли решить эту проблему ?

Можно настроить sudo , чтобы она выполняла ЛЮБУЮ команду ОПРЕДЕЛЁННОГО пользователя без запроса пароля ? Можно настроить sudo , чтобы она выполняла ЛЮБУЮ команду ОПРЕДЕЛЁННОГО пользователя без запроса пароля ?

Сори за совсем ламерский запрос , конечно можно всё работает.

Тем неменее если у кого-то есть мысли почему не работал пример с suid-ним битом , было бы очень интересно послушать

sisqo, а не смонтирован ли /tmp с опцией nosuid? Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог sisqo, а не смонтирован ли /tmp с опцией nosuid?

Нет , '/tmp' вообще не монтируется отдельно она находится на корневом разделе '/'

Знаю что suid бит не работает для скриптов , но 'sh' - полноценный ELF-ник.

Две идеи:
Первая, сделай вот так
/tmp/sh -p
(запусти интерпретатор)
и напечатай там
whoami

Знаю что suid бит не работает для скриптов , но 'sh' - полноценный ELF-ник.

$ ln -s /bin/bash /tmp/sh
olden@gremlin:

$ ls -l /bin/bash
-rwxr-xr-x 1 root root 625228 2004-12-19 18:53 /bin/bash
olden@gremlin:

$ ls -l /tmp/sh
lrwxrwxrwx 1 olden olden 9 2007-04-21 19:49 /tmp/sh -> /bin/bash
olden@gremlin:

$ sudo chmod uu+s /tmp/sh
olden@gremlin:

$ /tmp/sh -c 'touch /tmp/test'
olden@gremlin:

$ ls -l /tmp/test
-rw-r--r-- 1 root olden 0 2007-04-21 19:54 /tmp/test
olden@gremlin:

$ /tmp/sh -c 'touch /usr/test'
olden@gremlin:

$ ls -l /usr/test
-rw-r--r-- 1 root olden 0 2007-04-21 19:54 /usr/test
olden@gremlin:

$ rm /usr/test
rm: удалить защищенный от записи пустой обычный файл `/usr/test'? y
rm: невозможно удалить `/usr/test': Permission denied
olden@gremlin:


В этой статье мы расскажем о специальных разрешениях, которые работают с файлами и каталогами, которые называются Stickybit, SUID и SGID.

Sticky работает только для каталогов.

Если пользователь хочет создать или удалить файл / каталог в каком-либо каталоге, ему нужно разрешение на запись в этот каталог.

Разрешение на запись в каталог дает пользователю право создавать файл, а также право удалять его.

Этот каталог обладает всеми правами на всех трех уровнях, поскольку все пользователи должны создавать/удалять свои временные файлы.

Но так как пользователи имеют разрешение на запись в этот каталог, они могут удалить любой файл в этом каталоге.

Разрешения этого файла не влияют на удаление.

Но с установленным в каталоге стики битом любой может создать в нем файл / каталог, но может удалить только свои собственные файлы.

Файлы, принадлежащие другим пользователям, не могут быть удалены.

Вы можете заметить, что тег t добавлен в каталог /tmp, и это означает, что для этого каталога установлен бит.

В Linux стики бит может быть установлен командой chmod.

Вы можете использовать тег + t, чтобы добавить, и тег -t, чтобы удалить бит.

Примечание. В ОС Unix stickybit имеет другое назначение, но мы не обсуждаем его здесь.

Что такое SUID бит и как его установить

Когда исполняемый файл запускается, он запускается под управлением пользователя, который его выполнил.

Это означает, что когда пользователь student запускает команду ls, соответствующий процесс будет выполняться под управлением пользователя student.

Бит SUID, также известный как бит установки идентификатора пользователя, перезаписывает это поведение.

Если в программе установлен бит SUID, то эта программа будет работать как владелец этого файла, независимо от того, кто его выполняет.

У команды passwd в Linux установлен бит SUID.

С установленным битом SUID, когда обычный пользователь (скажем, student) запускает команду passwd, команда запускается с владельцем «root», а не с учетной записью student, поскольку root является владельцем этого файла.

Это необходимо, потому что пароли хранятся в файле /etc/shadow, который не имеет разрешения на групповом или другом уровне.

Вы должны понимать, что все пользователи не могут получить разрешение на чтение или запись этого файла по соображениям безопасности; в противном случае они будут читать / изменять пароли других пользователей.

Таким образом, это вызывает проблему: если у пользователей нет прав доступа к этому файлу, как они будут изменять свои собственные пароли?

SUID немного решает проблему.

У команды passwd установлен бит SUID, поэтому, когда обычные пользователи выполняют эту команду, они запускают ее под владельцем root, то есть владельцем команды passwd.

Как установить и сбросить бит SUID

Следует отметить, что бит SUID работает только с файлами.

Чтобы установить бит SUID на файл, используйте команду chmod следующим образом

Числовой метод для изменения разрешений также может быть использован.

Предположим, что если обычные разрешения для файла равны 744, то с установленным битом SUID они станут 4744.

Бит SUID имеет значение 4.

Как SGID Bit работает с файлами и каталогоми

В отличие от бита SUID, бит SGID работает как с файлами, так и с каталогами, но в обоих случаях он имеет различное значение.

По файлам:

Для файла он имеет значение, аналогичное значению бита SUID, то есть когда любой пользователь выполняет файл с установленным битом SGID, он всегда будет выполняться с владельцем группы этого файла, независимо от того, кто его запускает.

Например, файл /sbin/netreport имеет установленный бит SGID, который можно увидеть в «s» вместо «x» в разрешениях группы.

Этот файл имеет групповое владение группой root.

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

По каталогам:

Теперь поговорим о SGID в каталогах.

SGID для каталогов используется для создания совместных каталогов.

Чтобы понять бит SGID для каталогов, рассмотрим следующий сценарий:

Предположим, что три пользователя Джек, Джонс и Дженни вместе работают над каким-то проектом.

Все они принадлежат к группе под названием javaproject.

Для выполнения проекта им необходимо предоставить общий доступ ко всем файлам, связанным с проектом.

Все они должны видеть файлы друг друга.

Это можно сделать, просто предоставив разрешение на чтение на уровне группы.

Здесь возникает проблема: когда файл создается, он принадлежит к основной группе пользователя, создавшего файл.

Таким образом, когда разные пользователи создают свои файлы в этом каталоге, эти файлы не будут принадлежать группе javaproject group.

Что мы делаем для решения нашей проблемы, так это то, что мы устанавливаем группу каталога /javaproject равной группе javaproject, и устанавливаем бит SGID.

Когда в каталоге установлен бит SGID, все файлы и каталоги, созданные в нем, имеют групповое владение группой, связанной с этим каталогом.

Это означает, что после установки бита SGID в каталоге /javaproject все файлы и каталоги, создаваемые в этом каталоге, будут принадлежать группе «javaproject».

Более того, это поведение является рекурсивным, то есть в каталогах, созданных в этом каталоге, также будет установлен бит SGID.

Права у нового каталога также будут такими же, как и у каталога /javaproject.

Бит SGID может быть установлен командой chmod следующим образом:

Теперь, когда пользователь jones создает файл в этом каталоге, он создается под владельцем группы javaproject.

Числовое значение, соответствующее биту SGID, равно 2. Поэтому, чтобы численно добавить бит SGID, используйте следующую команду:

Читайте также: