O que mudou é que ele /bin/shse tornou bashou permaneceu, dashrecebendo uma bandeira adicional -pimitando o comportamento do bash.
O Bash exige que o -psinalizador não elimine o privilégio setuid, conforme explicado em sua página de manual :
Se o shell for iniciado com o ID do usuário (grupo) efetivo diferente do ID do usuário (grupo) real e a opção -p não for fornecida, nenhum arquivo de inicialização será lido, as funções do shell não serão herdadas do ambiente, os SHELLOPTS As variáveis BASHOPTS, CDPATH e GLOBIGNORE, se aparecerem no ambiente, são ignoradas e o ID do usuário efetivo é definido como o ID do usuário real . Se a opção -p for fornecida na chamada, o comportamento de inicialização será o mesmo, mas o ID do usuário efetivo não será redefinido.
Antes, dashnão se importava com isso e permitia a execução de setuid (sem fazer nada para evitá-lo). Mas a página dashde manual do Ubuntu 16.04 tem uma opção adicional descrita, semelhante a bash:
-p priv
Não tente redefinir o uid efetivo se ele não corresponder ao uid. Isso não está definido por padrão para ajudar a evitar o uso incorreto de programas raiz setuid via system (3) ou popen (3).
Esta opção não existia no upstream (que pode não ter sido reativo a um patch proposto * ) nem no Debian 9, mas está presente no Debian buster que obteve o patch desde 2018.
OBSERVAÇÃO: conforme explicado por Stéphane Chazelas, é tarde demais para invocar "/bin/sh -p", system()porque system()executa qualquer coisa fornecida /bin/she, portanto, o setuid já foi descartado. A resposta de derobert explica como lidar com isso, no código anterior system().
Note que o Debian costumava fazer o contrário. Ele costumava corrigir o bash para não eliminar privilégios. Se é uma melhoria é discutível. Agora, as pessoas que querem fazer um system()com privilégios elevados (o que, concedido, eles não deveriam em primeiro lugar) acabam fazendo um setresuid()antes, o que é muito pior, pois o shell não sabe que é sensível, então não ative o modo em que não confia no ambiente.
Stéphane Chazelas
8
Provavelmente, o shell está alterando seu ID do usuário efetivo de volta para o ID do usuário real como parte de sua inicialização por algum motivo ou outro. Você pode verificar isso adicionando:
antes do seu system(). (Na verdade, mesmo no Linux, você provavelmente só precisa definir os reais; os salvos devem ser bons para deixar em paz. Isso é apenas uma força bruta para depurar. Dependendo do motivo pelo qual você está definido, você pode precisar para salvar os IDs reais em algum lugar também.)
[Além disso, se este não é apenas um exercício para aprender como o setid funciona, há muitos problemas de segurança com que se preocupar, especialmente ao chamar um shell. Existem muitas variáveis de ambiente, por exemplo, que afetam o comportamento do shell. Prefira uma abordagem já existente, como sudose possível.]
Eu me concentrei no motivo da mudança, enquanto você fornecia como evitar o problema. +1
AB
Obviamente, se você realmente precisa de um local para salvar os IDs reais, o ID salvo é um local muito conveniente para isso. Especialmente se os IDs efetivos não forem root: root.
system("bash -p")
é executadosh -c "bash -p"
para que os privilégios já tenham sido eliminados quandobash
é executado.system()
com privilégios elevados (o que, concedido, eles não deveriam em primeiro lugar) acabam fazendo umsetresuid()
antes, o que é muito pior, pois o shell não sabe que é sensível, então não ative o modo em que não confia no ambiente.Provavelmente, o shell está alterando seu ID do usuário efetivo de volta para o ID do usuário real como parte de sua inicialização por algum motivo ou outro. Você pode verificar isso adicionando:
antes do seu
system()
. (Na verdade, mesmo no Linux, você provavelmente só precisa definir os reais; os salvos devem ser bons para deixar em paz. Isso é apenas uma força bruta para depurar. Dependendo do motivo pelo qual você está definido, você pode precisar para salvar os IDs reais em algum lugar também.)[Além disso, se este não é apenas um exercício para aprender como o setid funciona, há muitos problemas de segurança com que se preocupar, especialmente ao chamar um shell. Existem muitas variáveis de ambiente, por exemplo, que afetam o comportamento do shell. Prefira uma abordagem já existente, como
sudo
se possível.]fonte