Venho pesquisando um pouco na Web desde que postei essa pergunta pela primeira vez.
De acordo com o descobridor original do bug, o bash anterior ao patch CVE-2014-6271 importou uma função como:
foo=() {
code
}
substituindo o sinal de igual por um espaço e interpretando-o ... o que significava que era possível interpretar além da definição da função.
O patch para o CVE-2014-6271 introduziu um modo especial da função parse_and_execute () para limitar a avaliação à definição da função, e não além dela.
No entanto, conforme explicado neste encadeamento , a variável de ambiente especialmente criada do teste de vulnerabilidade CVE-2014-7169 foi projetada para 1) confundir o analisador até a morte 2) deixar restos no buffer 3) alterar completamente o que o comando bash original faz quando combina com as sobras já existentes no buffer.
Então, para dissecar a variável de ambiente:
X='() { (a)=>\'
- O analisador analisará
() { (a)=>\
. Observe que \
faz parte da string; que é não escapando a cotação única fuga.
() {
- O analisador identifica isso como uma definição de função.
(a)=
- Isso confunde o analisador até a morte.
>\
- O analisador deixa os dois caracteres finais no buffer.
>\[NEWLINE]
- Em algum momento antes da
sh
execução do comando, uma nova linha é colocada no buffer.
>\[NEWLINE]echo date
- Quando
sh
é chamado (que provavelmente é um link simbólico para bash neste caso), ele adiciona seus argumentos de comando,, echo date
aos caracteres já existentes no buffer.
>echo date
- Como a nova linha é escapada, o bash analisará o buffer como
>echo date
, que tem o mesmo efeito que date > echo
. Um arquivo chamado echo
é criado e o stdout do date
comando é redirecionado para ele.
; cat echo
- O segundo comando simplesmente exibe o conteúdo do arquivo recém-criado.