Что изменилось, так это то, что он /bin/sh
стал bash
или остался, dash
получив дополнительный флаг, -p
имитирующий поведение bash.
Bash требует, чтобы -p
флаг не сбрасывал привилегию setuid, как объяснено на его man-странице :
Если оболочка запущена с эффективным идентификатором пользователя (группы), не равным реальному идентификатору пользователя (группы), и опция -p не указана, файлы запуска не читаются, функции оболочки не наследуются от среды, SHELLOPTS Переменные BASHOPTS, CDPATH и GLOBIGNORE, если они появляются в среде, игнорируются, а эффективный идентификатор пользователя устанавливается равным реальному идентификатору пользователя . Если опция -p указана при вызове, поведение при запуске такое же, но эффективный идентификатор пользователя не сбрасывается.
Раньше dash
это не волновало и разрешало выполнение setuid (не делая ничего, чтобы предотвратить это). Но на dash
man-странице Ubuntu 16.04 описана дополнительная опция, похожая на bash
:
-p priv
Не пытайтесь сбросить эффективный uid, если он не совпадает с uid. Это не установлено по умолчанию, чтобы избежать неправильного использования корневыми программами setuid через system (3) или popen (3).
Эта опция не существовала ни в апстриме (которая, возможно, не реагировала на предложенный патч * ), ни в Debian 9, но присутствует в тестере Debian, который получил патч с 2018 года.
Примечание: как объяснено Стефаном Chazelas, это слишком поздно , чтобы вызвать "/bin/sh -p"
в system()
потому , что system()
работает что - то дается через /bin/sh
и так УИП уже упал. Ответ Дероберта объясняет, как с этим справиться, в коде ранее system()
.
* подробнее об истории здесь и там .
system("bash -p")
работает,sh -c "bash -p"
так что привилегии уже были удалены приbash
выполнении.system()
с повышенными привилегиями (которые, в первую очередь, не должны), в конце концов, делаютsetresuid()
раньше, что намного хуже, так как оболочка не знает, что это suid, поэтому не делает активируйте режим, в котором он не доверяет своей среде.Вероятно, оболочка по той или иной причине меняет свой действительный идентификатор пользователя на реальный идентификатор пользователя в рамках своего запуска. Вы можете проверить это, добавив:
до вашего
system()
. (На самом деле, даже в Linux вам, вероятно, нужно только установить реальные; сохраненные должны быть в порядке, если оставить их в покое. Это просто грубая сила для отладки. В зависимости от того, почему вы настроили id, вам, конечно, может понадобиться где-то сохранить реальные идентификаторы.)[Кроме того, если это не просто упражнение по изучению того, как работает setid, то есть много проблем с безопасностью, особенно при вызове оболочки. Например, существует много переменных среды, которые влияют на поведение оболочки. Предпочитаю уже существующий подход, как,
sudo
если вообще возможно.]источник