Зачем мне нужен setuid(0) внутри программы setuid-root C, которая вызывает административную программу с помощью system()?

Я должен был сделать грязный взлом Linux для кого-то, чтобы они могли запустить принтер с cupsenable printername команда оболочки, будучи пользователем без полномочий root. Я не хотел, чтобы они могли использовать все cupsenable синтаксис как root, поэтому я просто написал оболочку C, которая очищает входные данные в argv[1] и звонки system("cupsenable sanitizedprintername"),

Я сделал программу setuid root, но даже так, cupsenable не удалось с "отказано в разрешении". Затем я вставил setuid(0) звонить раньше system() и вот, это сработало.

Не обращайте внимания на то, что существует лучший способ предоставить пользователям контроль над принтером. Там, вероятно, есть лучший способ. Меня интересуют тонкости chmod u+s против setuid(0) против system(), Почему он так себя вел?

1 ответ

Решение

От man system:

Не использовать 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 отбрасывает привилегии при запуске.

И из man bash:

Если оболочка запущена с эффективным идентификатором пользователя (группы), не равным реальному идентификатору пользователя (группы), и -p опция не указана, файлы запуска не читаются, функции оболочки не наследуются от среды, SHELLOPTS переменная, если она появляется в среде, игнорируется, и эффективный идентификатор пользователя устанавливается равным реальному идентификатору пользователя.

Кажется твой setuid(0) Зов обошел эту защиту.

Другие вопросы по тегам