Para tranquilizar alguns, não encontrei o bug observando explorações, não tenho motivos para acreditar que ele tenha sido explorado antes de ser divulgado (embora, é claro, não possa descartá-lo). Também não encontrei o bash
código do código.
Não posso dizer que me lembro exatamente da minha linha de pensamentos na época.
Que mais ou menos veio de alguma reflexão sobre alguns comportamentos de alguns softwares que considero perigosos (os comportamentos, não o software). O tipo de comportamento que faz você pensar: isso não soa como uma boa ideia .
Nesse caso, eu estava refletindo sobre a configuração comum do ssh que permite a passagem de variáveis de ambiente não autorizadas pelo cliente, desde que o nome comece LC_
. A idéia é que as pessoas possam continuar usando seu próprio idioma ao ssh
acessar outras máquinas. Uma boa idéia até você começar a considerar o quão complexo é o tratamento de localização, especialmente quando o UTF-8 é trazido para a equação (e ver o quanto ele é tratado por muitos aplicativos).
Em julho de 2014, eu já havia relatado uma vulnerabilidade no manuseio de localização da glibc, combinada com essa sshd
configuração, e dois outros comportamentos perigosos do bash
shell
permitiram que invasores (autenticados) invadissem servidores git, desde que pudessem fazer upload de arquivos lá e bash
fossem usados como o shell de login do usuário git unix (CVE-2014-0475).
Eu estava pensando que provavelmente era uma má ideia usar bash
como o shell de login de usuários que oferecem serviços através do ssh, já que é um shell bastante complexo (quando tudo que você precisa é apenas analisar uma linha de comando muito simples) e herdou a maioria dos erros de design de ksh. Como eu já havia identificado alguns problemas com o bash
uso nesse contexto (para interpretar ssh ForceCommand
s), fiquei pensando se havia potencialmente mais lá.
AcceptEnv LC_*
permite que qualquer variável cujo nome comece LC_
e eu tive a vaga lembrança de que as bash
funções exportadas (um recurso útil, embora perigoso no momento) usavam variáveis de ambiente cujo nome era algo parecido
myfunction()
e me perguntava se não havia algo interessante para se olhar lá.
Eu estava prestes a descartá-lo, alegando que a pior coisa que se poderia fazer seria redefinir um comando chamado, o LC_something
que não poderia ser realmente um problema, pois esses não são nomes de comando existentes, mas então comecei a me perguntar como bash
importaria essas variáveis de ambiente.
E se as variáveis fossem chamadas, LC_foo;echo test; f()
por exemplo? Então eu decidi dar uma olhada mais de perto.
UMA:
$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() { :
}
revelou que minha lembrança estava errada, pois as variáveis não foram chamadas, 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 significava que qualquer variável de ambiente poderia ser um vetor.
Foi quando percebi a extensão do problema, confirmei que ele também era explorável por HTTP ( HTTP_xxx
/ QUERYSTRING
... env vars), outros como serviços de processamento de correio, mais tarde DHCP (e provavelmente uma longa lista) e o relatei (com cuidado) .