“Dirty COW” é uma vulnerabilidade grave do kernel Linux que foi descoberta recentemente; mas esteve presente no código por mais de 9 anos. Oficialmente, classificada como CVE-2016-5195, a vulnerabilidade foi descoberta pelo especialista de segurança e membro integrante do desenvolvimento do Linux, Phil Oester. Em resumo, essa falha do kernel Linux permite, remotamente ou localmente, a elevação de privilégios de um usuário normal para um usuário “root”. Entretanto, as principais distribuições Linux já divulgaram (algumas ainda divulgarão em breve) a correção para seus sistemas. Mas, o quão prejudicial vulnerabilidades como essa podem ser?
Contextualizando
“Bug” ou falha no sistema, na linguagem computacional, é um erro no funcionamento normal de um programa ou aplicativo, admitida ou desconhecida pelo programador. A partir disso posso dizer que “o programa” é o kernel Linux. E “o programador” é a comunidade de desenvolvedores do Linux. Contudo, todo código do kernel Linux apenas sofre alterações críticas e importantes mediante aprovação do Linus Torvalds – criador e principal mantenedor do kernel Linux.
Linus Torvalds – A mente por trás do Linux
Muito além do kernel – conheça todos os elementos que formam a estrutura do sistema Linux
Por ouro lado, uma vulnerabilidade, no contexto da segurança da informação, é uma fragilidade que permite um atacante comprometer a integridade da informação de um sistema. Ou seja, existindo uma falha (“bug”) no sistema; a vulnerabilidade existe instantaneamente. Entretanto, o atacante precisa descobri-la para poder explorá-la; e, assim, ter acesso a informação privilegiada.
Diante disso, informo que a falha no kernel Linux, batizada de “Dirty COW”, estar presente no kernel a mais de 9 anos. Pela sua longevidade, ela está sendo considerada como uma das mais sérias que o Linux já teve. O agravante é que, agora, ela pode estar sendo explorada por diversos usuários maliciosos (a falha foi descoberta). E é, praticamente, certo que se você estiver usando qualquer versão do kernel Linux ou Android lançada na última década, você esteja vulnerável.
Mas, vamos com calma… a falha já foi corrigida há duas semanas pelos mantenedores do kernel oficial do Linux (upstream). Já as distribuições Linux estão no processo de liberar suas atualizações que empacotam a correção. A Red Hat classificou a vulnerabilidade como “importante”.
9 anos… isso mesmo?!
O “boom” dessa notícia não foi somente por conta da gravidade da falha e da, provável, exploração em grande escala por atacantes ao redor do mundo. Foi, inclusive, pelo período muito longo presente no kernel Linux. Até mesmo um site foi criado, e com logomarca, para dar destaque à falha. Uma maneira de massificar o assunto. Veja AQUI.
Aí… você pode se perguntar: “Por tanto tempo assim e ninguém sabia da sua existência antes?“.
Conforme, divulgação oficial da correção da falha no kernel Linux, o Linus disse:
“[…] este é um ‘bug’ antigo que foi, na verdade, corrigido (‘pessimante, por sinal) uma vez por mim há 11 anos atrás; conforme atualização ‘4ceb5db9757a’ (“Fix get_user_pages() race for write access”). Mas, foi desfeita devido a problemas na arquitetura s390[…]”
Em outras palavras, o Linus sabia da falha e aplicou uma correção. Contudo, teve que reveter a correção por conta de incompatibilidades encontradas em outras plataformas. E… acabou deixando a falha em “segundo plano” :/
Essa situação, para muitos na comunidade, causa controvérsias perante a postura do Linus quanto à descoberta de falhas de segurança no Kernel. Linus, em discussões passadas, já chegou a dizer que “falhas de seguranças devem ser vistas como falhas “normais” do sistema. Além disso, devem ser tratadas e corrigidas sem precisar de tanto alarde sobre elas“. Para uns tantos outros integrantes da comunidade Linux isso é visto como não dar a devida importância na descoberta de falhas de segurança no sistema.
Em resumo, a falha estava presente no kernel Linux durante 9 anos. Porém, ainda não tinha sido explorada, em grande escala (os atacantes ainda não tinham explorado a vulnerabilidade), durante esse tempo.
“Dirty COW”
A falha, batizada de “Dirty COW”, reside no subsistema de memória do kernel Linux. Esse subsistema é responsável, entre outras funções, pelas operações de cópias virtuais de um processo na memória (Copy-on-write “COW”). Tecnicamente, a “COW” é uma estratégia de otimização usada em programação para realocar recursos, que são inicialmente diferentes, num único espaço de memória.
Essa estratégia é utilizada para reduzir a duplicação desnecessária de objetos de memória. Partindo do exemplo do Konstantin (redator do Linux.com); se você é um programador, o trecho de código a seguir tornará claro as coisas para você:
Mesmo que duas variáveis sejam criadas, ambas apontam para o mesmo objeto de memória (uma única cópia somente-leitura para ambos)! Pois, não há necessidade de alocar mais recursos para dois valores idênticos. Em seguida, o sistema operacional aguarda até que o valor do objeto seja modificado:
Neste ponto, será alocado memória para esse novo objeto. Depois, será lido os conteúdos originais do objeto que está sendo duplicado ( uso da técnica “COW” – cada processo receberá uma cópia do endereço de memória compartilhada anteriormente). Assim, o sistema operacional estará apto para escrever o conteúdo modificado para a área recém alocada na memória (no caso, o incremento na variável ‘b’).
Para fazer esse processo, é implementado no kernel o que é chamado de ‘race condition‘. Isso permite que o processo de leitura dos objetos, até a escrita do novo dado, seja feita através de uma transação atômica, travando o estado do sistema de forma que a condição inicial não possa ser modificada até que a ação seguinte seja concluída. Ou seja, evitar que quando o sistema operacional estiver lendo os dados do objeto, para escrever em outra área de memória, nenhum outro processo venha modificar os dados da primeira área de memória 😉
Isso tudo é feito constantemente no sistema operacional. E é nesse processo que a falha existia!
A falha ‘Dirty COW’ modifica uma ‘race condition’ para “enganar” o mapeamento de memória escrevendo o conteúdo modificado no intervalo de memória original em vez da área recém alocada. De acordo com o exemplo das variáveis, em vez de modificar a área de memória pertencente ao “B”, uma alteração seria feita na área da “A”.
Em resumo, essa operação permite que os usuários locais não privilegiados possam usar um exploit para escrever e ter acesso a partes do sistema que são de outros usuários ou mesmo do usuário “root”. Mais detalhes aqui.
Na prática
Imagine um usuário sem privilégios no sistema (usuário não “root”) ser capaz de ler/modificar o binário “/bin/bash” (shell), a fim de iniciar uma sessão shell modificada/alterada?
Isso não deve acontecer!! Por isso, apenas uma conta privilegiada (no caso, a “root”) deve ser capaz de modificar este ou outros arquivos críticos do sistema – caso contrário, qualquer usuário malicioso poderia substituir o binário e a “festa” tava feita… capturar sua senha quando se logar no sistema, por exemplo. Em resumo, qualquer arquivo que esteja protegido, por técnicas de controle de acesso, poderá ser comprometido se a falha “Dirty COW” for explorada 🙁
A ‘race condition’ descrita acima permite que o atacante ignore esta estrutura de permissões, pois “engana” a técnica COW para modificar uma área original somente-leitura, em vez de suas cópias duplicadas. Em outras palavras, um ataque elaborado poderá realmente substituir o “/bin/bash” para uma versão maliciosa.
Literalmente, para ver “na prática” a falha sendo explorada você pode baixar e compilar diversos códigos na linguagem C que foram disponibilizados AQUI para Provas de Conceitos (PoCs) – termo utilizado para denominar um modelo prático que possa provar o conceito (teórico) estabelecido por uma pesquisa ou artigo técnico.
Meu sistema está vulnerável?
Em 19 de Outubro (2016), essa vulnerabilidade foi divulgada. Infelizmente, essa falha existia há muito tempo – pelo menos desde 2007, com o kernel versão 2.6.22. Provalvemente, a grande maioria dos servidores, que não recebem mais atualizações ou ainda não foram feitas, estarão em risco.
Felizmente, a maioria das grandes distribuições já lançou uma correção;
Para descobrir se estar vulnerável, verifique a versão do kernel usada atualmente:
Se sua versão é mais ANTIGA do que as seguintes, você está vulnerável:
CentOS
Em algumas versões do CentOS é possível verificar se há alguma vulnerabilidade no sistema rodando o script oferecido pela RedHat. Baixe-o e execute-o, conforme passos abaixo:
Se o sistema estiver vulnerável, uma mensagem como essa será mostrada:
SUE Enterprise
As versões SUSE Linux Enterprise 11 e 12 estão vulneráveis!
Arch Linux
Verifique a versão do kernel usada atualmente:
Se sua versão é mais ANTIGA do que as seguintes, você está vulnerável:
Como se proteger?
Para maioria dos sistemas, a correção é simples: basta atualizar o sistema e reiniciar o servidor.
Ubuntu/Debian
No caso do Debian, é preciso ter o repositório security habilitado no source.list
CentOS
Para versões 6 e 7, você pode atualizar o sistema ou somente o pacote do kernel:
OpenSUSE
A comunidade do openSUSE liberou patchs de correção para essa falha. Para executá-la, execute no terminal:
Depois, reinicie a máquina para a correção surgir efeito!
Arch Linux
Como segue a metologia Rolling Release, apenas atualize seu sistema normalmente!
Reflexões
O quão prejudicial essa falha pode ser?
Milhares de sistemas Linux foram afetados (e ainda podem estar vulneráveis, devido a impossibilidade de obtenção de atualizações ou pelo tempo de liberação de patchs de segurança definido por cada comunidade mantenedora de uma distribuição Linux). E, de fato, ser visto como uma das maiores falhas, existentes no kernel Linux (até o momento), não é tão radical assim.
Um sinal de alerta foi ligado, tanto para a comunidade desenvolvedora, liderada pelo Linus Torvalds (criador do Linux), quanto para usuários e profissionais administradores de sistemas Linux.
Muito além do kernel – conheça todos os elementos que formam a estrutura do sistema Linux
Negligenciar uma falha, ou remediar apenas quando o problema realmente existe, deve ser evitado. O Linux já domina grande fatia de máquinas servidoras e supercomputadores. Inclusive em sistemas embarcados, através da tecnologia IoT. Assim, sua grandiosidade deve ser mantida. O foco na prevenção de falhas, ou num processo bem definido para detecção/reparo delas, deve ser mantido e estar atrelado a todo o ciclo de desenvolvimento do kernel Linux. Esforços como o “Kernel Self Protection Project” podem ajudar a reduzir o impacto de alguns desses bugs, pois é um projeto que foca na prevenção e não na remediação dos bugs.
Já na visão do usuário, é importante que não haja descuidos na preservação de um sistema sempre atualizado. Principalmente, para profissionais administradores de sistemas Linux que devem manter a infraestrutura segura e em pleno funcionamento. Inclusive, com a diminuição de brechas para possíveis ataques. Pois, não basta a comunidade, que desenvolve e mantém o kernel Linux sempre atualizado, divulgar novas versões se o usuário/profissional não tem o cuidado de manter seu sistema sempre seguro.
Passo a passo completo para manter um sistema Linux seguro
Nenhum sistema é 100% seguro! E o Linux não seria a exceção dessa regra. Entretanto, a metodologia de desenvolvimento de um software livre permite ações importantes no tratamento de erros, bem como: detectar a falha, torná-la pública e realizar a correção. Ou seja, uma comunidade em torno do desenvolvimento de um software livre aprimora o resultado final desse processo; no caso o software.
Portanto, qualquer mitigação para o “Dirty COW” e outros bugs deve ser feita constantemente. É preciso considerar uma estratégia de defesa para manter os atacantes o mais longe possível; para não serem capazes de executar código malicioso no seu computador. Assim, para chegar a essas falhas de kernel, os atacantes devem primeiro “superar” as barreiras de um firewall, um sistema de prevenção contra intrusões (IDS), dos filtros da Web e proteções RBAC, por exemplo. Se essas estratégias não são implantadas no seu sistema, “o caminho” vai ficar mais fácil 😉