Para tranquilizar alguns, não encontrei o bug observando exploits,
não há razão para acreditar que ele tenha sido explorado antes de ser divulgado
(embora, claro, eu não possa descartá-lo). Eu não achei por
olhando para o código de bash
.
Eu não posso dizer que me lembro exatamente da minha linha de pensamento na época.
Isso mais ou menos veio de alguma reflexão sobre alguns comportamentos de algum software eu acho perigoso (os comportamentos, não o Programas). O tipo de comportamento que faz você pensar: isso não parece uma boa ideia .
Neste caso, eu estava refletindo sobre a configuração comum de
ssh que permite passar variáveis de ambiente não-analizadas de
o cliente desde que seu nome comece com LC_
. A ideia é tão
que as pessoas possam continuar usando seu próprio idioma quando ssh
ing
outras máquinas. Uma boa ideia até começar a considerar
como a manipulação de localização complexa é especialmente quando o UTF-8 é
trazido para a equação (e vendo o quão mal é tratado por
muitas aplicações).
Em julho de 2014, eu já havia reportado uma vulnerabilidade em
manipulação de localização glibc que combinada com esse sshd
config, e dois outros comportamentos perigosos do bash
shell
atacantes permitidos (autenticados) para invadir servidores git
desde que eles pudessem fazer upload de arquivos e bash
foi
usado como o shell de login do usuário git unix (CVE-2014-0475).
Eu estava pensando que provavelmente era uma má idéia usar bash
como login
shell de usuários oferecendo serviços sobre o ssh, dado que é bastante
um shell complexo (quando tudo que você precisa é apenas analisar uma linha de comando muito simples) e herdou a maioria dos misdesigns do ksh.
Desde que eu já havia identificado alguns problemas com bash
sendo
usado nesse contexto (para interpretar ssh ForceCommand
s), eu estava
perguntando se havia potencialmente mais lá.
AcceptEnv LC_*
permite qualquer variável cujo nome comece
com LC_
e eu tive a lembrança vaga de que bash
exportou
funções (um perigoso embora no momento recurso útil) foram
usando variáveis de ambiente cujo nome era algo como
myfunction()
e queria saber se não havia algo
interessante olhar para lá.
Eu estava prestes a demiti-lo, alegando que a pior coisa que
poderia fazer seria redefinir um comando chamado LC_something
o que não poderia ser um problema, já que eles não existem
nomes de comandos, mas depois comecei a me perguntar como bash
importou essas variáveis de ambiente.
E se as variáveis fossem chamadas LC_foo;echo test; f()
, por exemplo? Então decidi dar uma olhada mais de perto.
A:
$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() { :
}
revelou que minha lembrança estava errada em que as variáveis
não foram chamados myfunction()
mas myfunction
(e é o
valor que começa com ()
).
E um teste rápido:
$ env 'true;echo test; f=() { :;}' bash -c :
test
bash: error importing function definition for 'true;echo test; f'
confirmou minha suspeita de que o nome da variável não foi higienizado, e o código foi avaliado na inicialização .
Pior, muito pior, o valor também não foi higienizado:
$ env 'foo=() { :;}; echo test' bash -c :
test
Isso significa que qualquer variável de ambiente pode ser um vetor.
Foi quando percebi a extensão do problema, confirmei que era
explorável sobre HTTP também ( HTTP_xxx
/ QUERYSTRING
... env vars), outros como serviços de processamento de mensagens, DHCP posterior (e provavelmente uma lista longa) e
informou (com cuidado).