Aqui está o comando que usei para verificar meu shell bash em busca do bug do Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Alguém pode explicar o comando em detalhes?
Responder1
Esta resposta é uma derivada de umaartigo original na Revista Fedorapor Matthew Miller, licenciado sob aCreative Commons Atribuição-Compartilhamento pela mesma Licença 4.0licença.
Deixe-me explicar:
env x='() { :;}; echo OOPS' bash -c :
Isso imprimirá “OOPS” em um sistema vulnerável, mas sairá silenciosamente se o bash tiver sido corrigido.
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Isso imprimirá “OOPS” em um sistema vulnerável, mas imprimirá “this is a test”
se o bash tiver sido corrigido.
E você provavelmente já ouviu falar que isso tem algo a ver com variáveis de ambiente. Mas, por que o código nas variáveis de ambiente está sendo executado? Bem, não deveria ser - mas, por causa de um recurso que estou tentado a chamar de inteligente demais para seu próprio bem, há espaço para uma falha. Bash é o que você vê como um prompt de terminal, mas também é uma linguagem de script e tem a capacidade de definir funções. Você faz isso assim:
$ Ubuntu() { echo "Ubuntu is awesome."; }
e então você tem um novo comando. Tenha em mente que o echo
aqui ainda não foi executado; é apenas salvo como acontecerá quando executarmos nosso novo comando. Isso será importante em um minuto!
$ Ubuntu
Ubuntu is awesome.
Útil! Mas, digamos, por algum motivo, precisamos executar uma nova instância do bash, como um subprocesso, e queremos executar meu novo comando incrível sob isso. A instrução bash -c somecommand
faz exatamente isso: executa o comando fornecido em um novo shell:
$ bash -c Ubuntu
bash: Ubuntu: command not found
Ah, sim. Triste. O filho não herdou a definição da função. Mas é inerente ao ambiente - uma coleção de pares de valores-chave que foram exportados do shell. (Este é um conceito totalmente diferente; se você não está familiarizado com isso, confie em mim por enquanto.) E acontece que o bash também pode exportar funções. Então:
$ export -f Ubuntu
$ bash -c Ubuntu
Ubuntu is awesome.
O que é muito bom - exceto que o mecanismo pelo qual isso é conseguido émeio desonesto. Basicamente, como não existe mágica Linux/Unix para executar funções em variáveis de ambiente, a função de exportação na verdade apenas cria uma variável de ambiente regular contendo a definição da função. Então, quando o segundo shell lê o ambiente “de entrada” e encontra uma variável com conteúdo que se parece com uma função, ele a avalia.
Em teoria, isso éperfeitamente seguro, porque, lembre-se, definir uma função na verdade nãoexecute. Exceto — e é por isso que estamos aqui — que havia um bug no código onde a avaliação não parava quando o final da definição da função era atingido. Simplesmente continua.
Isso nunca aconteceria quando a função armazenada em uma variável de ambiente fosse feita de forma legítima, com export -f
. Mas, por que ser legítimo? Um invasor pode simplesmente criar qualquer variável de ambiente antiga e, se parecer uma função, os novos shells bash pensarão que é!
Então, em nosso primeiro exemplo:
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
O env
comando executa um comando com um determinado conjunto de variáveis. Neste caso, estamos configurando x
algo que se parece com uma função. A função é apenas um único comando :
, que na verdade é um comando simples definido como não fazer nada. Mas então, após o semi-colon
which sinalizar o fim da definição da função, há um echo
comando. Isso não deveria estar lá, mas não há nada que nos impeça de fazer isso.
Então, o comando dado para executar com este novo ambiente é um novo shell bash, novamente com um comando “ echo this is a test
” ou “não fazer nada :
”, após o qual ele será encerrado, de forma totalmente inofensiva.
Mas - opa! Quando esse novo shell inicia e lê o ambiente, ele chega à x
variável e, como se parece com uma função, avalia-a. A definição da função é carregada de forma inofensiva – e então nossa carga maliciosa também é acionada. Portanto, se você executar o procedimento acima em um sistema vulnerável, você será “OOPS”
impresso de volta. Ou um invasor pode fazer muito pior do que apenas imprimir coisas.
Responder2
Emversão sem patch debash
ele armazena definições de funções exportadas como variáveis de ambiente.
Armazene uma função x
como,
$ x() { bar; }
$ export -f x
E verifique sua definição como,
$ env | grep -A1 x
x=() { bar
}
Portanto, alguém poderia explorar isso definindo suas próprias variáveis de ambiente e interpretando-as como definições de funções. Por exemplo env x='() { :;}'
seria tratado como
x() { :;
}
O que o comando para verificar o shellshock faz,
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
De man env
,
env
- execute um programa em um ambiente modificado.:
não faça nada além de sair com status de saída0
. vermaisQuando uma nova instância do bash sem patch é iniciada como
bash -c "echo this is a test"
, a variável ambiental criada é tratada como uma função e carregada. Assim, obtém-se a saída
vulnerável isto é um teste
Observação:O eco fora da definição da função foi executado inesperadamente durante a inicialização do bash. A definição da função é apenas uma etapa para que a avaliação e a exploração aconteçam, a própria definição da função e a variável de ambiente usada são arbitrárias. O shell olha para as variáveis de ambiente, vê x, que parece atender às restrições que conhece sobre a aparência de uma definição de função, e avalia a linha, involuntariamente executando também o echo (que pode ser qualquer comando, malicioso ou não) . Veja tambémesse