Não consigo ver como isso pode se aplicar a sudo
.
Para os scripts setuid, a ideia é esta:
Suponha que você tenha um /usr/local/bin/myscript
que seja setuid root e comece com #! /bin/sh
. Ninguém tem acesso de gravação a /usr/local/bin
ou myscript
, mas qualquer um pode fazer:
ln -s /usr/local/bin/myscript /tmp/-i
E /tmp/-i
também se torna um script setuid e, mesmo que você ainda não tenha acesso de gravação, você terá acesso de gravação a /tmp
.
Em sistemas nos quais scripts setuid não são executados por meio de /dev/fd
, quando você executa cd /tmp && -i
, o bit setuid significa que ele será executado: /bin/sh -i
as root:
- O processo muda euid para o proprietário do arquivo
- O sistema analisa o shebang
- O sistema é executado (ainda como root),
/bin/sh -i
Agora, para esse caso em particular, o trabalho mais fácil é escrever o shebang da maneira recomendada: #! /bin/sh -
, mas, mesmo assim, há uma condição de corrida. Agora se torna:
- O processo muda euid para o proprietário do arquivo
- O sistema analisa o shebang
- O sistema é executado (ainda como root),
/bin/sh - -i
- "sh" abre o arquivo "-i" no diretório atual (bem, você poderia pensar).
Mas entre 3 e 4 acima, você tem bastante tempo para alterar "-i" ou ("qualquer arquivo", pois é um vetor de ataque diferente aqui) para algum mal "-i "arquivo que contém, por exemplo, apenas" sh "e você obtém um shell root (para um script root setuid).
Com versões mais antigas de ksh
, você nem precisou fazer isso porque em 4, ksh primeiro procurou "-i" em $PATH
, então foi o suficiente para colocar o seu mal "-i" em $PATH
( ksh
abriria aquele em vez do em /tmp
).
Todos esses vetores de ataque são corrigidos se, quando você faz: cd /tmp; -i
, o sistema o faz (ainda na chamada de sistema execve):
- atomicamente: descubra que o arquivo é setuid e abra o arquivo em algum descritor de arquivo
x
do processo. - processa as alterações do euid para o proprietário do arquivo.
- Executar
/bin/sh /dev/fd/x
-
sh
abre/dev/fd/x
, que pode se referir apenas ao arquivo que foiexecve
d.
O ponto é que o arquivo é aberto como parte do execve, então sabemos que é o código com o conteúdo confiável que será interpretado com privilégios alterados.
Agora, isso não se aplica a sudo
porque a política sudo
é baseada em path
.
Se a regra sudo
disser que você pode executar / usr / local / bin / myscript como root, então você pode fazer:
sudo /usr/local/bin/myscript
Mas você não pode fazer:
sudo /tmp/any-file
Mesmo que "qualquer arquivo" seja um link físico ou um link simbólico para /usr/local/bin/myscript
. sudo
não usa /dev/fd
AFAICT.