Зачем мне нужен setuid(0) в программе setuid-root C, которая вызывает административную программу с помощью system()?
-
20-08-2019 - |
Вопрос
Мне пришлось сделать грязный взлом Linux для кого-то, чтобы они могли запустить принтер с cupsenable printername
команда командной оболочки, будучи пользователем без прав root.Я не хотел, чтобы они могли использовать всю полноту cupsenable
синтаксис от имени root, поэтому я просто написал оболочку C, которая очищает входные данные в argv[1]
и призывает system("cupsenable sanitizedprintername")
.
Я создал программу setuid root, но даже в этом случае, cupsenable
сбой с надписью "в разрешении отказано".Затем я вставил setuid(0)
позвоните до system()
и, о чудо, это сработало.
Не обращайте внимания на то, что существует лучший способ предоставить пользователям контроль над принтером.Вероятно, есть способ получше.Что меня интересует, так это тонкости chmod u+s
против. setuid(0)
против. system()
.Почему он вел себя именно так?
Решение
От 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)
колл обошел эту защиту.