SETUID на уровне файловой системы - PullRequest
0 голосов
/ 05 декабря 2018

Предположим, мы смотрим на следующий сценарий:

Файл saymyname.c (включая пропущенные)

int main(int argc, char** argv){
    system("whoami");   
}

Сборка и установка битов прав доступа:

cake@lie> gcc saymyname.c -o saymyname
cake@lie> sudo chown root:root saymyname
cake@lie> sudo chmod u+s saymyname
cake@lie> ./saymyname
cake

Каждый ресурс под солнцем говорит мне, что установка разрешения s для столбца пользователя должна запускать программу с привилегиями владельца, а не вызывающего пользователя.Почему system("whoami"); возвращает cake?

Изменение программы для установки UID вручную следующим образом:

int main(int argc, char** argv){
    setuid(geteuid());
    system("whoami");   
}

Дает ожидаемый результат

cake@lie> ./saymyname
root

Некоторыересурсы утверждают, что биты SUID и GUID часто игнорируются.Поэтому происходит наблюдаемое поведение?Если так, есть ли способ заставить его вести себя так, как будто он был выполнен пользователем root без setuid(.)?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

ответ Георга технически корректен 1 , но стоит упомянуть, что на справочной странице system(3) прямо указано, что использование system() в программах setuid не рекомендуется:

Не используйте system () из программы с привилегиями set-user-ID или set-group-ID, потому что странные значения для некоторых переменных среды могут использоваться для нарушения целостности системы,Вместо этого используйте семейство функций exec (3), но не execlp (3) или execvp (3) .На самом деле system () не будет работать должным образом из программ с привилегиями set-user-ID или set-group-ID в системах, в которых / bin / sh является версией bash [> =] 2, поскольку bash 2 отбрасывает привилегии при запуске,(Debian использует модифицированный bash, который не делает этого, когда вызывается как sh.)

Это особенно актуально в вашем примере, когда вы вызываете whoami без полного пути.Представьте себе следующий сценарий (как непривилегированный пользователь):

> whoami cat << 'EOF'
#!/bin/not-bash :)
echo "I'm root! let's clean up some trash ..."
# rm -rf /
EOF
chmod +x whoami

PATH="${PWD}" ./saymyname

Это означает, что вместо смены системной оболочки (или использования Debian) код должен просто использовать exec(), например:

int main(int argc, char** argv){
    execl("/usr/bin/whoami", "whoami", NULL);   
}

1 более новые версии dash в Ubuntu также будут отбрасывать привилегии

0 голосов
/ 05 декабря 2018

Похоже, что bash, который выполняется system (), удаляет привилегии.В моих тестах замена символической ссылки / bin / sh, указывающей на тире (вместо bash), заставила его работать как положено.

Также с bash,

execl("/bin/bash", "bash", "-c", "whoami", NULL);

дает торт, тогда как

execl("/usr/bin/whoami", "whoami", NULL);

дает root.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...