O problema é que system("ls")
executaria o executável com o nome ls
que encontrar primeiro no conjunto do usuário PATH
.
Este ls
não precisa necessariamente listar o conteúdo de um diretório. Em vez disso, poderia ser um script como este:
#!/bin/sh
cat /etc/shadow
Digamos que você coloque esse script em algum lugar em um diretório abaixo do seu diretório pessoal, por exemplo, /home/datashark/bin
e adicione isso ao seu PATH
:
PATH="/home/datashark/bin:$PATH"
Se você executar agora ls
, não receberá uma listagem de diretórios, em vez disso, receberá uma mensagem de erro:
cat: /etc/shadow: Permission denied
Mas se você executar bad_ls
, a system("ls")
-call também procurará um executável chamado ls
em seu PATH
e localizará e /home/datashark/bin/ls
em vez de /bin/ls
. Como bad_ls
é executado com permissões de raiz elevadas, o script chamado ls
(em determinados sistemas - veja abaixo) também é executado com permissões de raiz elevadas e o comando cat /etc/shadow
, que imprimirá o conteúdo de /etc/shadow
.
Portanto, é uma má idéia para o root permitir que usuários normais executem bad_ls
desde que ele tenha privilégios de SUID, porque ele executaria qualquer programa chamado ls
que vem primeiro no usuário PATH
.
Nota:
Isso não funciona em todos os sistemas Linux. Por exemplo, de acordo com man 3 system
, ele não funcionará em sistemas em que /bin/sh
seja vinculado a um (não corrigido) bash
da versão 2 ou mais recente (2.0 foi lançado em 1996). bash
descarta privilégios na inicialização. Isso não afeta somente o script ls
, mas também a chamada system()
antes, pois system()
passa o comando para /bin/sh
.
Pode funcionar em outras distribuições que não usam bash
como /bin/sh
. Ao contrário das informações declaradas no projeto, o Ubuntu (como Debian e provavelmente a maioria dos derivados de ambos) usa dash
e não bash
as /bin/sh
e vem fazendo isso desde a versão 6.10 (a partir de 2006! Veja esta página no Wiki do Ubuntu . Parece que com as versões recentes do Ubuntu (pelo menos 16.04) dash
e, portanto, /bin/sh
são corrigidos para descartar automaticamente as permissões SUID (Procure "priv" em man dash
).