Resumo

  • O CGI podia transformar um cabeçalho HTTP remoto em variável de ambiente; o Bash vulnerável reconhecia ali uma função e podia executar texto posterior ao fechamento da definição.
  • A exposição remota dependia do caminho inteiro, não da simples presença do Bash: dados externos precisavam alcançar o ambiente antes de uma invocação direta ou indireta do shell.
  • A correção inicial foi incompleta; o encerramento exigiu pacotes posteriores, menos herança de ambiente, remoção de chamadas desnecessárias ao shell e renovação comprovada do estado em execução.

Um cabeçalho HTTP descreve uma requisição. Uma variável de ambiente descreve o contexto de um processo. Uma função contém código. No Shellshock, essas três categorias se encontraram em poucos passos e o dado ganhou um verbo que sua origem não autorizava.

A primeira transformação era parte do CGI. A RFC 3875 permite que campos de cabeçalho HTTP sejam apresentados como metavariáveis com prefixo HTTP_. Em Unix, as metavariáveis chegam ao script como variáveis de ambiente de mesmo nome. O mecanismo transportava dados; sozinho, não executava comandos.

O Bash fornecia a transformação seguinte. Para exportar funções a outra instância, colocava uma definição no ambiente. Versões vulneráveis reconheciam esse formato ao iniciar, mas podiam continuar analisando além do fim da função. O texto adicional passava a ser tratado como comando.

O caminho completo era: cabeçalho remoto, metavariável CGI, ambiente herdado, início do Bash, importação e execução. A ausência de qualquer elo fechava essa rota. Por isso, contar máquinas com Bash produzia uma medida ruim. CERT/CC e Red Hat registraram como exemplos scripts CGI, certos arranjos SSH de comando restrito e alguns fluxos de clientes DHCP. A mesma versão podia estar inerte em um servidor e diretamente exposta em outro.

O CVE-2014-6271 tornou-se público em 24 de setembro de 2014. O CERT/CC publicou sua nota no dia seguinte e informou exploração ativa. Em 26 de setembro, a Red Hat alertou que o primeiro reparo era incompleto; o CVE-2014-7169 cobriu comportamento restante, e outros problemas próximos receberam identificadores próprios. “Atualizado” precisava significar pacote exato mais resultado de teste, não apenas uma tarefa fechada.

A mudança decisiva estreitou o contrato de importação. Pacotes corrigidos passaram a usar um espaço de nomes reconhecível, como BASH_FUNC_nome(), para funções exportadas. Houve impacto de compatibilidade, mas o ambiente comum deixou de conceder o mesmo significado executável a um nome ordinário.

Ainda restava o código vivo. A Red Hat recomendou reiniciar serviços que usavam funções exportadas; usuários podiam precisar entrar novamente, e sessões screen ou tmux podiam preservar definições antigas. A versão no inventário não provava qual executável um processo persistente chamaria.

A resposta tinha de mapear invocações. Qual serviço público monta o ambiente? Qual auxiliar chama Bash? Sob qual usuário? Que processo pai sobreviveu à atualização? Enquanto o pacote era distribuído, o proprietário local precisava poder desativar um CGI, limpar o ambiente em uma fronteira de confiança ou trocar um invólucro de shell por execução direta.

Shellshock não condena variáveis de ambiente. Ele mostra que o nome “metadado” não limita o poder que o receptor atribui ao valor. Controle começa ao localizar o instante em que o dado adquire capacidade de agir.

Fontes