Часто попадается этот системный вызов перед exec* и другими функциями. Зачем он? Чтобы это вообще сработало, нужно предположить, что код выполняется с максимальными привилегиями, т.е. эффективный uid уже равен 0, и эти привилегии потом наследуются свежезапущенным процессом. Если у меня и так euid = 0, то зачем вызывать setreuid? Или ruid обычно не равен euid?
Я такое использование часто видел в финальных частях эксплойтов. Как выглядит схема повышения привилегий при эксплойте? Очень схематично и упрощённо - вот так 1. При ruid=n, euid=n запускаем процесс ./exploit 2. Этот процесс как-то получает рутовые права, т.е. euid=0. Однако ruid при этом всё ещё остаётся равным n. 3. Обычно программы проверяют, запущены ли они из-под рута через getuid(), т.е. проверяют ruid, но не euid. Поэтому обычно эксплойт и завершается парой вызовов типа setreuid(0, 0); execve("/bin/sh", ...); чтобы запускаемая программа уже точно работала "из-под рута".
Bert Почему повышается именно euid, а не ruid? В примерах шелл кодов, которые я успел посмотреть, этот код выполняется в самом начале. Иногда весь шелл код сводится к setreuid + execve и всё. Поэтому я подумал, что процесс уже запущен под рутом, но ruid у него почему-то != 0.
Откуда берётся ruid? Он устанавливается вызовом setuid(). В основном это делает процесс login после авторизации пользователя. Откуда берётся euid? Обычно euid = ruid. Если не считать намеренных вызовов seteuid() и т.п., он может быть сменён при исполнении файла с установленным set-uid битом. Например, это надо для обеспечения возможности смены пользователем его собственного пароля. Ведь /etc/passwd доступно для записи только для рута, а для того, чтобы пользователь мог поменять _свой_ пароль, он должен суметь записать его туда. Поэтому у /bin/passwd права: $> ls -l /bin/passwd -rws--x--x 1 root root .... /bin/passwd Пользователь запускает $> /bin/passwd some_passwd Запущенный процесс будет имеет ruid пользователя, но euid=0 (точнее, ruid владельца файла, которым, в нашем случае, является root). Строго говоря, ruid определяет, кто мы есть и, соответственно, возможность выполнения привилегированных операций. А euid определяет наши права при доступе к файлам. Теперь вернёмся к шелл коду. Обычно, различные сервисы работают из-под своих специальных учётных записей. Однако иногда им необходим доступ к файлам с рутовыми правами, и тогда им выставляют set-uid бит и владельца root. Вот на такие-то программы и нацеливают эксплойты. Ты запускаешь, например, тот же /bin/passwd с огромным строкой-паролем, рассчитывая на buffer overflow. Внутри этой строки-пароля записан твой шелл код: setreuid(0,0); exec("/bin/sh"). Процесс passwd имеет ruid=n, так как запустил его ты, и euid=0, так как это определяется по правам доступа файла /bin/passwd. Если бы шелл код был просто exec("/bin/sh"), то ruid(/bin/sh) = ruid(/bin/passwd) = твой ruid. Однако, после вызова setreuid(0,0) ruid(/bin/passwd) изменяется и получаем ruid(/bin/sh) = ruid(/bin/passwd) = 0. Т.е. рутовый шелл. Надеюсь, изложил понятно. После рабочего дня короткие доходчивые фразы как-то в голову не лезут.
Quantum что-то творишь товарищь, ой чую че-то интересное, может в личку поделишься, а то жуть как любопытно! ))
EvilsInterrupt Попался на глаза шелл код, которым кто-то пытался подорвать мой фтп сервер, и я заинтересовался этим вопросом. Нарыл в сети кучу похожих шелл кодов, половина из которых содержат явные ошибки, а другая половина, судя по комментариям, вообще писана какими-то даунами. В общем, решил проконсультироваться тут с компетентными специалистами