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