Por que a capacidade de definir funções em uma variável ambiental não é um risco à segurança?

9

Pelo que entendi, geralmente é considerado seguro permitir que qualquer pessoa forneça informações que serão armazenadas em uma variável ambiental. A vulnerabilidade do shellshock é um problema aqui, pois significa que o código no final de uma definição de função dentro de uma variável ambiental será executado quando uma nova instância do bash for iniciada e você obviamente não deseja que ninguém execute nenhum código que deseje no seu servidor . Aparentemente, as definições de função aparentemente não representam um risco à segurança e são permitidas porque precisam ser explicitamente chamadas para que seu código seja executado.

Minha pergunta é por que um usuário mal-intencionado não pode simplesmente definir uma função, contendo seu código malicioso como um comando comum, lse esperar que o script (ou o que estiver sendo executado) use esse comando em algum momento?

Um exemplo do que tenho em mente:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...
Reed Espinosa
fonte

Respostas:

10

É um risco de segurança. Geralmente, é por isso que você não pode fazer isso ao alternar para outro contexto (controle remoto de um sistema, alteração de usuários etc.).

Se você tiver a capacidade de criar qualquer variável de ambiente que desejar, existem inúmeras maneiras possíveis de executar código arbitrário.
Tome $LD_PRELOADcomo exemplo. Se você tiver a capacidade de definir essa variável, poderá substituir as funções da biblioteca e inserir seu código nele. Você pode definir a $DISPLAYvariável e redirecionar a tela X à qual o programa se conecta para obter o controle do aplicativo.

É por isso que coisas como sudotira o ambiente de todas as variáveis. sudopermite apenas algumas variáveis ​​selecionadas. E, dessas variáveis, as higieniza (passa pela $TERMvariável, mas não ocorre se contiver caracteres incomuns).

Patrick
fonte
Uau, eu sempre me perguntei por que alguns scripts enormes que eu faço no BASH teriam falhas estranhas quando iniciadas com o sudo, principalmente em caminhos, o que me levou a procurar por iniciações do sudo e bloqueá-las, mas eu nunca soube o porquê disso. um problema, obrigado pela boa explicação re sudo retirando variáveis ​​ambientais.
Lizardx
3

Eu diria que sim, quando bash é seu / bin / sh. Não é um recurso do shell bourne, e aposto que também não é um recurso do posix shell, na verdade eles podem querer proibi-lo expressamente.

O Bash é realmente mais um shell derivado do korn, do que um shell bourne, apesar do nome, e é o único shell do tipo Korn que possui o recurso, e na minha opinião é o recurso do kitchensink que não tem virtudes práticas. Os desenvolvedores que evitam os recursos do bash para padrões, como o shell bourne, o posix shell ou o subconjunto ksh88 que os shells modernos têm em comum, ou seja, se comprometeram com boas práticas e idiomas padrão, ficam chocados quando o software está ligado linux e mac e agora potencialmente vulnerável, pois os autores da exploração são livres para usar os 'bashismos', apesar de suas intenções. Quanto à compatibilidade aprimorada, quando invocada como / bin / sh, sobre outros derivados do shell korn, é apenas se / bin / sh é seu shell de login ou shell interativo quando o bash se comporta mais como um shell bourne do que com um shell korn,

Vou tentar convencê-lo de que é um recurso de pia de cozinha, com dois casos: você é um desenvolvedor incorporado, que cria dispositivos como roteadores, armazenamento conectado à rede e um primeiro ambiente maior, significa mais memória, mais custo, menos lucros, portanto, se esse era um motivo para considerar o uso desse recurso do bash, você não deveria usar os recursos FPATH e autoload, ksh88? em vez de passar toda a função byte por byte no ambiente? Você pode até considerar analisar e remover o ambiente por atacado, antes que ele chegue a um shellscript que possa interpretar mal uma variável, como filtrar ^ $ (. *) $ E similares ...

Isso ressalta o que é único nisso, não importa qual é a variável e o script não precisa fazer referência ou usar a variável, ela ainda pode estar vulnerável.

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

Para tudo sob o sol, o acima é tão seguro quanto o script perl, você não está usando nenhuma variável, como você pode interpretar mal alguma? Mudando para

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

Também não ajuda, isso não tem nada a ver com ENV ou algo assim - todo mundo fica queimado porque o bash precisa ser único. O fato de que o bash versão 2 tem o problema, para mim prova que ninguém nunca usa esse recurso para seus aplicativos, porque, caso contrário, ele não deveria estar escondido por tanto tempo. E o pior é que não há como evitar esse recurso . Aqui está um exemplo com: com 'su -', que, se você perguntasse a alguém, a explicação seria descartar o ambiente, verificar a página de manual e você encontrará apenas 99,9%. Eu testei da maneira certa, já que neste sistema / bin / sh é o shell de login do root e / bin / sh é bash MAS , neste exemplo eu tentopara proteger meu .bash_profile. Renomeei meu existente para root (que está ativado), mas meu pensamento era se su, então possivelmente sudo, de qualquer maneira, mudei para isso:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

Então, na verdade, estou lançando o ambiente completamente e usando um ambiente mínimo e executando um shell que não deveria ter o problema, no lugar do processo atual. Em seguida, no lugar do exemplo padrão, tente:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

Isso ilustra como isso não tem nada a ver com a análise de uma função específica, e uma exploração pode se referir e usar a função. Você pode imaginar a função com lógica para testar se o root é etc. Nesse caso, é apenas uma forma modificada de uma função para iconificar ou encaixar uma janela de terminal, usando uma sequência de escape, isso é bastante padrão, então depois de clicar para desiconificar, eu veja dockshock - mas e daí? Agora tente o seguinte:

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

E adivinha? A janela é sugada para a doca. Aqui está o que parece depois ..

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

Então, muito, muito por isso! As funções exportadas têm prioridade sobre os scripts rc. Você não pode evitar.

Dan LaBell
fonte
1
O POSIX permitia funções exportáveis ​​no rascunho 2 e as proibia posteriormente. O recurso é insano.
mikeserv