TL; DR
A vulnerabilidade do shellshock está totalmente corrigida no
- No ramo bash-2.05b: 2.05b.10 e superior (patch 10 incluído)
- Na ramificação do bash-3.0: 3.0.19 e superior (patch 19 incluído)
- No ramo bash-3.1: 3.1.20 e superior (patch 20 incluído)
- No ramo bash-3.2: 3.2.54 e superior (patch 54 incluído)
- Na ramificação do bash-4.0: 4.0.41 e superior (patch 41 incluído)
- No ramo bash-4.1: 4.1.14 e superior (patch 14 incluído)
- No ramo bash-4.2: 4.2.50 e superior (patch 50 incluído)
- No ramo bash-4.3: 4.3.27 e superior (patch 27 incluído)
Se o seu bash mostrar uma versão mais antiga, o fornecedor do sistema operacional ainda poderá corrigi-lo por conta própria, então é melhor verificar.
E se:
env xx='() { echo vulnerable; }' bash -c xx
mostra "vulnerável", você ainda está vulnerável. Esse é o único teste relevante (se o analisador de bash ainda está exposto ao código em qualquer variável de ambiente).
Detalhes.
O bug foi na implementação inicial da função de exportação / importação introduzidos nos 5 º de agosto 1989 por Brian Fox, eo primeiro lançado em bash-1.03 cerca de um mês mais tarde, em um momento em que o bash não estava em uso tão difundido, antes da segurança era uma grande preocupação e HTTP e a web ou Linux existiam.
No ChangeLog na 1.05 :
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel)
* readline.c: rl_insert (). Optimized for large amounts
of typeahead. Insert all insertable characters at once.
* I update this too irregularly.
Released 1.03.
[...]
Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel)
* variables.c: make_var_array (), initialize_shell_variables ()
Added exporting of functions.
Algumas discussões em gnu.bash.bug e comp.unix.questions nessa época também mencionam o recurso.
É fácil entender como chegou lá.
o bash exporta as funções em ambientes como
foo=() {
code
}
E na importação, tudo o que precisa fazer é interpretar isso com o =
espaço substituído ... exceto que não deve ser cegamente interpretado.
Também está quebrado no sentido de que bash
(ao contrário do shell Bourne), variáveis e funções escalares têm um espaço de nome diferente. Na verdade, se você tiver
foo() { echo bar; }; export -f foo
export foo=bar
bash
felizmente colocará ambos no ambiente (sim entradas com o mesmo nome de variável), mas muitas ferramentas (incluindo muitos shells) não as propagarão.
Alguém poderia argumentar também que o bash deve usar um BASH_
prefixo de namespace para isso, pois isso é relevante apenas do bash para o bash. rc
usa um fn_
prefixo para um recurso semelhante.
Uma maneira melhor de implementá-lo seria colocar a definição de todas as variáveis exportadas em uma variável como:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Isso ainda precisaria ser higienizado, mas pelo menos isso não poderia ser mais explorável do que $BASH_ENV
ou $SHELLOPTS
...
Existe um patch que impede a bash
interpretação de qualquer outra coisa além da definição de função ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ), e esse é o que possui foi aplicado em todas as atualizações de segurança das várias distribuições Linux.
No entanto, o bash ainda interpreta o código e qualquer bug no interpretador pode ser explorado. Um desses erros já foi encontrado (CVE-2014-7169), embora seu impacto seja muito menor. Portanto, haverá outro patch em breve.
Até uma correção de proteção que impeça o bash de interpretar o código em qualquer variável (como usar a BASH_FUNCDEFS
abordagem acima), não teremos certeza se não estamos vulneráveis a um bug no analisador do bash. E acredito que haverá uma correção tão difícil lançada mais cedo ou mais tarde.
Edit 2014-09-28
Foram encontrados dois bugs adicionais no analisador (CVE-2014-718 {6,7}) (observe que a maioria dos shells provavelmente possui bugs no analisador para casos de canto, isso não seria uma preocupação se esse analisador não tivesse foi exposto a dados não confiáveis).
Enquanto todos os três bugs 7169, 7186 e 7187 foram corrigidos nos seguintes patches, a Red Hat pressionou pela correção de endurecimento. Em seu patch, eles mudaram o comportamento para que as funções fossem exportadas em variáveis chamadas BASH_FUNC_myfunc()
mais ou menos antecipando a decisão de design do Chet.
Mais tarde, Chet publicou essa correção como um patch oficial do bash para upgreams .
Esse patch de proteção, ou variantes, está agora disponível para a maioria das principais distribuições Linux e, eventualmente, chegou ao Apple OS / X.
Agora, isso preocupa qualquer env arbitrário que explora o analisador por esse vetor, incluindo duas outras vulnerabilidades no analisador (CVE-2014-627 {7,8}) que foram divulgadas mais tarde por Michał Zalewski (CVE-2014-6278 quase tão ruim quanto CVE-2014-6271), felizmente, depois que a maioria das pessoas teve tempo de instalar o patch de proteção
Os erros no analisador também serão corrigidos, mas não são mais um problema tão grande agora que o analisador não é mais tão facilmente exposto a entradas não confiáveis.
Observe que, embora a vulnerabilidade de segurança tenha sido corrigida, é provável que vejamos algumas mudanças nessa área. A correção inicial para CVE-2014-6271 quebrou compatibilidade com versões anteriores em que ele pára funções de importação, com .
ou :
ou /
em seu nome. Ainda podem ser declarados por bash, o que contribui para um comportamento inconsistente. Como as funções com .
e :
em seu nome são comumente usadas, é provável que um patch restaure a aceitação de pelo menos as do ambiente.
Por que não foi encontrado antes?
Isso também é algo que eu me perguntei. Eu posso oferecer algumas explicações.
Primeiro, acho que se um pesquisador de segurança (e eu não sou um pesquisador profissional de segurança) estivesse procurando especificamente por vulnerabilidades no bash, provavelmente o teria encontrado.
Por exemplo, se eu fosse um pesquisador de segurança, minhas abordagens poderiam ser:
- Veja de onde
bash
vem a entrada e o que ela faz com ela. E o meio ambiente é óbvio.
- Procure em quais locais o
bash
intérprete é chamado e em quais dados. Mais uma vez, ele se destacaria.
- A importação de funções exportadas é um dos recursos desativados quando
bash
setuid / setgid, o que o torna um local ainda mais óbvio para procurar.
Agora, suspeito que ninguém pensou em considerar bash
(o intérprete) uma ameaça ou que a ameaça poderia ter acontecido dessa maneira.
O bash
intérprete não se destina a processar entradas não confiáveis.
Os scripts do shell (não o intérprete) são frequentemente analisados de perto do ponto de vista da segurança. A sintaxe do shell é tão incômoda e existem muitas advertências na escrita de scripts confiáveis (você já viu alguém mencionando o operador split + glob ou por que você deve citar variáveis, por exemplo?) Que é bastante comum encontrar vulnerabilidades de segurança nos scripts que processam dados não confiáveis.
É por isso que você costuma ouvir que não deve escrever scripts de shell CGI ou que scripts setuid estão desativados na maioria dos Unices. Ou você deve ter cuidado extra ao processar arquivos em diretórios graváveis no mundo ( por exemplo, CVE-2011-0441 ).
O foco está nisso, nos scripts de shell, não no intérprete.
Você pode expor um interpretador de shell de dados não confiáveis (alimentação de dados estrangeiros como código shell de interpretar) via eval
ou .
ou chamando-o em arquivos do usuário fornecido, mas, em seguida, você não precisa de uma vulnerabilidade no bash
explorá-lo. É bastante óbvio que, se você estiver passando dados não autorizados para um shell interpretar, ele o interpretará.
Portanto, o shell é chamado em contextos confiáveis. Ele recebe scripts fixos para interpretar e, mais frequentemente do que não (porque é tão difícil escrever scripts confiáveis), dados fixos para processar.
Por exemplo, em um contexto da Web, um shell pode ser chamado em algo como:
popen("sendmail -oi -t", "w");
O que pode dar errado com isso? Se algo errado estiver previsto, trata-se dos dados alimentados para o sendmail, não como a própria linha de comando do shell é analisada ou que dados extras são alimentados para esse shell. Não há motivo para considerar as variáveis de ambiente que são passadas para esse shell. E se você o fizer, percebe que são todos os envios cujo nome começa com "HTTP_" ou são envios CGI bem conhecidos como SERVER_PROTOCOL
ou QUERYSTRING
nenhum dos quais o shell ou o sendmail têm algum negócio a ver.
Em contextos de elevação de privilégios, como ao executar setuid / setgid ou via sudo, o ambiente é geralmente considerado e houve muitas vulnerabilidades no passado, novamente não contra o próprio shell, mas contra coisas que elevam os privilégios sudo
(veja, por exemplo, o CVE -2011-3628 ).
Por exemplo, bash
não confia no ambiente quando setuid ou é chamado por um comando setuid (pense, mount
por exemplo, em que chama auxiliares). Em particular, ele ignora as funções exportadas.
sudo
faz limpar o ambiente: todos por padrão, exceto por uma lista branca, e se configurado para não, pelo menos listas negras alguns que são conhecidos por afetar uma concha ou de outra (como PS4
, BASH_ENV
, SHELLOPTS
...). Ele também coloca na lista negra as variáveis de ambiente cujo conteúdo começa ()
(e é por isso que o CVE-2014-6271 não permite a escalação de privilégios sudo
).
Mas, novamente, isso é para contextos em que o ambiente não é confiável: qualquer variável com qualquer nome e valor pode ser definida por um usuário mal-intencionado nesse contexto. Isso não se aplica a servidores da web / ssh ou a todos os vetores que exploram o CVE-2014-6271 em que o ambiente é controlado (pelo menos o nome das variáveis de ambiente é controlado ...)
É importante bloquear uma variável como echo="() { evil; }"
, mas não HTTP_FOO="() { evil; }"
, porque HTTP_FOO
não será chamado como comando por nenhum script ou linha de comando do shell. E o apache2 nunca definirá uma variável echo
ou BASH_ENV
.
É bastante óbvio que algumas variáveis de ambiente devem estar na lista negra em alguns contextos com base em seus nomes , mas ninguém pensou que elas deveriam estar na lista negra com base em seu conteúdo (exceto sudo
). Ou, em outras palavras, ninguém pensou que envários arbitrários poderiam ser um vetor para injeção de código.
Quanto à possibilidade de testes extensivos quando o recurso foi adicionado, eu diria que é improvável.
Quando você testa o recurso , testa a funcionalidade. A funcionalidade funciona bem. Se você exportar a função em uma bash
chamada, ela será importada em outra. Um teste muito completo pode ter detectado problemas quando uma variável e uma função com o mesmo nome são exportadas ou quando a função é importada em um código de idioma diferente daquele em que foi exportado.
Mas, para detectar a vulnerabilidade, não é um teste de funcionalidade que você precisaria fazer. O aspecto de segurança teria que ser o foco principal e você não testaria a funcionalidade, mas o mecanismo e como ela poderia ser abusada.
Não é algo que os desenvolvedores (especialmente em 1989) geralmente tenham em mente, e um desenvolvedor de shell pode ser desculpado por pensar que é improvável que seu software seja explorável em rede.