Exportações do GNU Bash funções do shell em variáveis de ambiente que incluem as definições da função:
$ function foo { echo bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { echo bar
}
Quando uma nova instância de Bash é gerada, ela procura por variáveis de ambiente que correspondam a um determinado padrão. O conteúdo dessas variáveis é automaticamente importado como funções do shell. Como Stéphane Chazelas explica , uma vez que este recurso foi introduzido no Bash 1.03, a importação de funções foi feita simplesmente substituindo o = na entrada correspondente no matriz de variáveis de ambiente e a interpretação do resultado como uma definição de função. Antes do o patch que CVE-2014-6271 , a variável de ambiente foi interpretada em sua totalidade, incluindo quaisquer comandos que seguem o corpo da função real. O patch introduz dois modos especiais para a função parse_and_execute() , SEVAL_FUNCDEF e SEVAL_ONECMD . Quando a função é chamada com SEVAL_FUNCDEF , ela deve impedir a interpretação de comandos que não sejam definições de função. O sinalizador SEVAL_ONECMD deve impedir que a função seja avaliada mais do que um único comando.
A variável de ambiente especialmente criada de Tavis Ormandy faz algo sutilmente diferente. Ele é projetado para confundir o analisador e corromper o buffer usado para armazenar os comandos a serem avaliados. Restos da variável de ambiente no buffer altere a interpretação do comando subsequente . Este problema relacionado recebeu o identificador CVE CVE-2014-7169 .
Os constituintes da definição de variável de ambiente X='() { (a)=>\' são:
-
() {, que é interpretado pelo analisador como o início de uma definição de função -
(a)=tem a intenção de confundir o analisador e fazer com que ele deixe restos da variável de ambiente no buffer -
>\é a carga real que resta no buffer
O objetivo da carga útil é alterar a interpretação do comando executado no subshell chamado por sh -c "echo date"; . Obviamente, isso pressupõe que /bin/sh seja um link simbólico para bash . Quando a cadeia de comandos especificada como um operando para -c é colocada no buffer, o conteúdo do buffer é:
>\[0xA]echo date
O [0xA] é um caractere de nova linha ASCII, que normalmente atuaria como um separador de comando, mas agora é ignorado pelo \ da carga útil. Como resultado, o conteúdo do buffer é interpretado como
>echo date
Porque Bash permite que os operadores de redirecionamento precedam comandos , isso é equivalente a
date > echo
Isso simplesmente faz com que o comando date seja executado com sua saída padrão redirecionada para um arquivo chamado echo . O cat echo restante não faz parte da exploração, apenas demonstra que agora existe um arquivo chamado echo contendo a saída de date .
Quanto ao motivo pelo qual a string (a)= confunde o analisador neste caso, parece que está relacionado a ele aparecer como uma definição de função aninhada (malformada). O demonstra isso mais claramente:
$ X='() { function a a>\' bash -c echo
$ ls echo
echo