Aqui está o comando que eu usei para verificar meu shell bash para o bug do Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Alguém pode explicar o comando em detalhes?
bash
shellshock
heemail
fonte
fonte
Respostas:
Esta resposta é derivada de um artigo original na Revista Fedora de Matthew Miller, licenciado sob a licença Creative Commons Attribution-Share Alike 4.0 .
Deixe-me explicar:
Isso imprimirá "OOPS" em um sistema vulnerável, mas sairá silenciosamente se o bash tiver sido corrigido.
Isso imprimirá "OOPS" em um sistema vulnerável, mas será impresso
“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 sou tentado a chamar de inteligente demais para o 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 assim:
e então você tem um novo comando. Lembre-se de que o
echo
aqui ainda não foi executado; é salvo como o que acontecerá quando executarmos nosso novo comando. Isso será importante em um minuto!Útil! Mas, digamos, por algum motivo, precisamos executar uma nova instância do bash, como um subprocesso, e queremos executar o meu novo e impressionante comando sob isso. A instrução
bash -c somecommand
faz exatamente isso: executa o comando fornecido em um novo shell:Ooh. Triste. A criança não herdou a definição da função. Mas, ele inerente ao ambiente - uma coleção de pares de valores-chave que foram exportados do shell. (Esse é um conceito completo; se você não estiver familiarizado com isso, confie em mim por enquanto.) E, ao que parece, o bash também pode exportar funções. Tão:
O que é muito bom - exceto que o mecanismo pelo qual isso é realizado é desonesto . Basicamente, como não há mágica do 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 “recebido” 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 não é realmente executa de fato . Exceto - e é por isso que estamos aqui - houve um erro no código em que a avaliação não parou quando o final da definição da função foi atingido. Apenas continua indo.
Isso nunca aconteceria quando a função armazenada em uma variável de ambiente é feita legitimamente, com
export -f
. Mas, por que ser legítimo? Um invasor pode criar qualquer variável de ambiente antiga e, se parecer com uma função, novos shells bash acharão que é!Então, no nosso primeiro exemplo:
O
env
comando executa um comando com um determinado conjunto de variáveis. Nesse caso, estamos definindox
algo que se parece com uma função. A função é apenas uma única:
, que na verdade é um comando simples, definido como não fazer nada. Mas então, após osemi-colon
que sinaliza o final da definição da função, há umaecho
comando. Isso não deveria estar lá, mas não há nada que nos impeça de fazê-lo.Em seguida, o comando fornecido para executar com este novo ambiente é um novo shell bash, novamente com um “
echo this is a test
” ou “não faça nada:
comando ", após o qual ele será encerrado, completamente inofensivo.Mas - oops! Quando esse novo shell é iniciado e lê o ambiente, ele chega à
x
variável e, como se parece com uma função, ele a avalia. A definição da função é carregada inofensivamente - e então nossa carga maliciosa também é acionada. Portanto, se você executar o procedimento acima em um sistema vulnerável, será“OOPS”
impresso de volta. Ou, um invasor pode fazer muito pior do que apenas imprimir coisas.fonte
env
não é necessário. Você pode obter o mesmo resultado (aprovação / reprovação, dependendo se Bash foi atualizado) usando o comando sem ele:x='() { :;}; echo OOPS' bash -c "echo this is a test"
. Isso ocorre porque o precedente de um comando com uma atribuição de variável passa essa variável e seu valor para o ambiente do comando (bash -c "..."
neste caso).env
é necessário ou não, é determinado pelo shell a partir do qual se executa o teste, não pelo shell que está sendo testado. (Podem ser os mesmos. Mesmo assim, estamos testando como o bash processa seu próprio ambiente.) Os shell do estilo Bourne aceitamNAME=value command
sintaxe; As conchas no estilo C (por exemplocsh
,tcsh
) não. Portanto, o teste é um pouco mais portátilenv
(às vezes, criando confusão sobre como ele funciona).Na versão sem patch de
bash
ele armazena definições de funções exportadas como variáveis de ambiente.Armazene uma função
x
como,E verifique sua definição como,
Assim, pode-se explorar isso definindo suas próprias variáveis de ambiente e interpretando-as como definições de função. Por exemplo,
env x='() { :;}'
seria tratado comoO que o comando para verificar o shellshock faz,
De
man env
,env
- execute um programa em um ambiente modificado.:
não faça nada além de sair com o status de saída0
. veja maisQuando uma nova instância do bash sem patches é lançada 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ídafonte
env test='() { echo "anything"; }' bash -c "echo otherthing"
, verá na saídaotherthing
. Isso é corrigido no patch. fique à vontade se ainda não estiver claro.unpatched bash
você pode chamar a função conforme definida, mas em um patchbash
a definição em si não existe.echo vulnerable
) não é executado. Observe que nos patches mais recentes, a função passada deve ter um prefixo específico (env 'BASH_FUNC_x()'='() { :;}; echo vulnerable' bash -c "echo this is a test"
). Alguns patches mais recentes podem ser usados em%%
vez do primeiro()
.