Você já ouviu a expressão “ buffer overflow ”? Trata-se de uma vulnerabilidade que ganhou notoriedade em 2019, por ter possibilitado um ataque global ao WhatsApp .
Depois dos problemas causados ao conhecido aplicativo de troca de mensagens, muitas outras empresas passaram a se preocupar com a possibilidade de contarem com essa vulnerabilidade em seus sistemas.
E a preocupação é muito válida, já que muitas aplicações podem estar expostas ao buffer overflow sem tomar conhecimento, gerando uma grande possibilidade de atuação para os cibercriminosos.
Como sabemos, a transformação digital trouxe muitos benefícios para os negócios, mas também deixou as empresas muito mais dependentes da tecnologia para o desenvolvimento de suas atividades.
Com o avanço da tecnologia, seguiram também o inquérito dos cibercriminosos, que ganharam superfícies muito maiores de atuação, principalmente quando a empresa não conta com uma estratégia de cibersegurança sólida .
O problema é que ainda existe uma disparidade entre a implementação das tecnologias, que são essenciais em empresas de todos os segmentos, e colocação em prática das ações forçadas de identificação e mitigação das vulnerabilidades de segurança digital e proteção contra os possíveis invasores .
A conscientização sobre a importância da cibersegurança nas empresas e a consequente tomada de atitude para implementá-la e aprimorá-la constantemente compor o passo fundamental que está sendo tomado atualmente.
Muitos gestores têm buscado informações sobre os diferentes tipos de vulnerabilidades para impedir eficientemente a atuação cibercriminosa e fazer uma boa gestão de riscos.
Quando o assunto é a segurança das aplicações, o buffer overflow é uma das vulnerabilidades a serem lembradas, por ser muito persistente desde o início da transformação digital.
Esse tipo de vulnerabilidade sempre existe, mas ao contrário de algumas outras que tornaram-se mais raras, o buffer overflow está presente nas aplicações até hoje.
É comum encontrá-lo em linguagens como C e C++, que encerraram de uma definição prévia sobre o tamanho do buffer de memória, mas ele também está presente em outras linguagens, como o PHP.
Sendo assim, os cuidados para evitar o buffer overflow não devem se restringir a aplicações de linguagem em linguagens específicas.
Ao longo dos próximos apresentados, você vai entender o que é buffer overflow, como os cibercriminosos exploram essa vulnerabilidade e o que você pode fazer para evitá-la.
Continue a leitura!
O que é buffer overflow?
O buffer overflow ou estouro de buffer é o que acontece quando a capacidade de um buffer é sobrecarregada por um programa ao gravar dados .
Uma analogia muito utilizada para a compreensão dessa vulnerabilidade é a da xícara de café: não é possível colocar um litro de café em uma xícara com capacidade para apenas 200 ml.
Quando se tenta colocar uma quantidade maior de dados do que a capacidade do buffer, assim como acontece no caso da xícara, há uma espécie de transbordamento .
Quando, ao gravar dados em um buffer, o software “estoura” sua capacidade, ocorre a substituição de locais de memória adjacentes .
Ou seja, como muitas informações estão sendo colocadas em uma espécie de container que não conta com espaço suficiente, essas informações acabam ocupando o espaço pertencente a outras informações em containers próximos. É como se, no caso da xícara, o café fosse ocupar o lugar dos biscoitos, no prato ao lado.
O buffer overflow pode ser explorado pelos cibercriminosos com a intenção de modificar a memória de um dispositivo para controlar a execução do software .
Para entender como isso ocorre, vamos além da metáfora da xícara de café, começando pela compreensão do conceito de buffer.
O buffer, também chamado de buffer de dados (buffer de dados), é um espaço de armazenamento de memória física usado para proteger dados temporariamente no movimento de um lugar para outro.
Normalmente, os buffers ficam na memória RAM e são usados para ajudar a melhorar o desempenho dos computadores.
Tanto os discos rígidos modernos quanto diversos serviços on-line utilizam buffers para o acesso a dados de forma mais eficiente.
Um exemplo disso são os streamings de vídeos online, que recorrem ao buffer para evitar a continuidade.
Nesse caso, enquanto o vídeo está sendo transmitido, o reprodutor baixa e armazena uma parte desse vídeo de cada vez em um buffer para transmiti-lo.
Assim, quando acontece alguma pequena queda na velocidade da conexão ou uma interrupção momentânea do serviço, uma performance do streaming não é esperada.
Mas um buffer é projetado para armazenar determinada quantidade de dados que, quando é ultrapassada, provoca a substituição de dados na memória adjacente ao buffer.
Isso acontece em todos os casos em que o buffer não é projetado previamente para descartar o excesso de dados quando ele surgir.
Nesse caso, temos o buffer overflow, que pode ser explorado por um invasor para corromper o software.
Mesmo que esse processo já seja amplamente estudado na área da cibersegurança , os ataques baseados em buffer overflow continuam sendo um problema que preocupa os gestores de tecnologia.
Esse tipo de problema pode ocorrer em uma grande quantidade de aplicações, causando diversos tipos de consequências.
Um exemplo de estouro de buffer diz respeito aos dados enviados a uma impressora. Ao enviar um arquivo para ser impresso, você está lidando com dois equipamentos que possuem processos distintos, ou seja, sua impressora não conta com o mesmo padrão de processamento do seu computador.
Por isso, você precisa de um espaço em memória para armazenar os dados a serem enviados para uma impressora no tempo dela.
Todavia, esse espaço pode ser interrompido, com a colocação de mais dados do que a impressora pode comportar.
Isso pode fazer com que a sua aplicação ou sistema operacional execute comandos não desejados .
Outro exemplo de estouro de buffer ocorre quando se usa, em um formulário de login, um campo com tamanho pré-definido para a colocação do nome de usuário.
Durante um possível ataque, o invasor pode inserir nesse campo um dado com tamanho superior ao que ele é capaz de armazenar.
Dessa forma, o excedente acaba sendo armazenado fora do buffer determinado, podendo ser executado como um comando.
Temos, nesse caso, uma função na validação dos dados inseridos pelo usuário e um exemplo claro da vulnerabilidade buffer overflow.
Tipos de buffer overflow
Como vimos, o buffer overflow ocorre quando o buffer se depara com mais informação do que ele consegue armazenar.
Essa vulnerabilidade é explorada por hackers para forçar o buffer a usar outros módulos de memória. Nesse contexto, podemos enumerar os diferentes tipos de buffer overflow:
- Stack Overflow : é a categoria mais comum de buffer overflow e ataca o call stack ou a pilha de chamadas de ação em um software;
- Heap Overflow : trata-se de um tipo de ataque que tem como propósito o comprometimento da estrutura heap, ou seja, a árvore de propriedades ou piscina de memória aberta;
- Integer Overflow: trata-se de um ataque matemático, a partir de uma operação que resulta em um número muito grande a ponto de o buffer não conseguir armazená-lo;
- Unicode Overflow: Trata-se de uma categoria mais sofisticada de buffer overflow, que consiste na inserção de caracteres unicode em um sistema que espera caracteres ASCII. principalmente esses são dois padrões de caracteres que permitem a representação de texto por computadores. Mas os códigos ASCII contam apenas com caracteres de idiomas ocidentais, enquanto o unicode pode criar caracteres para quase todos os idiomas, ou seja, ele possui muito mais caracteres disponíveis, que podem ser muito maiores do que o maior caractere ASCII.
A partir das possibilidades acima, os cibercriminosos podem alimentar uma entrada de um programa deliberadamente para que o software tente armazenar dados em um buffer que não seja suficientemente grande.
Dessa maneira, porções de memória conectadas ao espaço do buffer serão substituídas , comprometendo o funcionamento da aplicação.
Caso o programa tenha um layout de memória bem definido, o hacker poderá sobrescrever setores conhecidos por conterem um código executável e substituir esse código pelo seu próprio.
Essa ação, é claro, vai comprometer totalmente a maneira como a aplicação foi projetada para funcionar.
Quando se pensa nas vias de atuação dos cibercriminosos no caso do buffer overflow, algumas linguagens de codificação surgem como mais exemplificadas a esse tipo de vulnerabilidade.
É o caso das linguagens C e C++, que não contam com proteções contra o acesso ou a substituição de dados em sua memória.
Mas é importante ter em mente que não basta evitar essas linguagens para se ver livre do buffer overflow, pois ele também pode acontecer em aplicações desenvolvidas em diversas outras linguagens.
Vamos falar sobre como evitar o buffer overflow ainda neste artigo, mas antes vamos explicar algumas das possíveis consequências dessa vulnerabilidade.
Consequências do buffer overflow
Quando ocorre a exploração de uma vulnerabilidade de buffer overflow, as consequências podem variar.
A sua aplicação pode, por exemplo, apresentar instabilidades , parar , ou, ainda, retornar com algumas informações sobre o erro.
Em outros casos, os dados gravados fora do espaço reservado podem ser portadores de comandos maliciosos, que serão executados caso não sejam detectados e devidamente tratados.
Quando essa execução acontece, são muitos os problemas desencadeados em relação à segurança da aplicação.
Um deles é a execução arbitrária de códigos com a escalação de privilégios . Ao conseguir enviar um código malicioso para explorar uma vulnerabilidade de estouro, o cibercriminoso pode tomar o controle da aplicação, enviando novos comandos a serem executados.
Esse envio de comandos pelo invasor é chamado de execução arbitrária de código . Ele acontece quando um código é injetado dentro de um buffer e executado.
Já a permissão de privilégio acontece quando a aplicação é executada em um sistema operacional com privilégios de sistema e conta com uma vulnerabilidade.
Se a investigação do cibercriminoso for bem sucedida, ele recebe um shellcode do sistema, com todos os privilégios do usuário.
Imagine o que pode ocorrer com a aplicação se esse usuário for o administrador com todos os seus privilégios sendo transferidos para o invasor.
Mas as consequências do buffer overflow não se resumem à possibilidade de execução de códigos, até porque nem toda vulnerabilidade desse tipo pode ser explorada para a execução de um código arbitrário.
Nas situações em que não é possível executar um código, o cibercriminoso pode acompanhar os ataques de negação de serviço por meio do buffer overflow.
É importante lembrar que um estouro de buffer pode ocorrer em qualquer software e, sendo assim, outros serviços podem sofrer esse tipo de ataque.
Isso porque o software pode ser uma aplicação web ou um sistema de roteamento, por exemplo.
Sistemas de roteadores, firewall e até mesmo internet das coisas podem ter vulnerabilidades de estouro de buffer.
As paralisações relacionadas à negação de serviço via buffer overflow podem ser rápidas ou duradouras, dependendo da forma como o ataque ocorrido e da estrutura de cibersegurança da empresa vítima.
É claro que os benefícios podem ser grandes e por isso é importante adotar uma estratégia que evite ao máximo as possibilidades de buffer overflow.
Falaremos sobre isso em seguida.
Como evitar o buffer overflow?
Para evitar a ocorrência das vulnerabilidades de estouro de buffer é importante pensar nesse assunto já durante o desenvolvimento das aplicações , ocorreu tanto de forma proativa quanto de forma reativa.
A prevenção proativa é a melhor e mais eficiente forma de evitar o buffer overflow e isso ocorre no desenvolvimento do próprio código.
Suponhamos que a sua aplicação possa receber em determinado campo dados de até 10 bytes. Sendo este um parâmetro, o seu código precisa garantir que somente os 10 bytes serão aceitos naquele campo.
Contar com um código que fornece o controle desses campos de entrada garantidos que não deixam um vazamento de dados excedentes.
É importante promover a revisão e validação dos códigos que estão sendo apresentados, para que tanto o buffer overflow quanto outras vulnerabilidades sejam afastadas da aplicação.
A prevenção reativa , por outro lado, diz respeito à correção ou mitigação da vulnerabilidade de transbordamento após o descobrimento da mesma.
Um bom exemplo desse tipo de atuação são os sistemas operacionais que contam com uma proteção para áreas de memória .
Eles promovem um controle de acesso a essas áreas e evitam a execução de dados registrados fora delas.
Existem diversos métodos que podem ser aplicados com o objetivo de reduzir o impacto do buffer overflow, como a implementação de DEP, ASLR ou SEHOP, além da proteção de ponteiros.
Esse tipo de proteção evita que o invasor consiga executar códigos dentro de regiões específicas, aguardando muito o impacto da vulnerabilidade.
Outra forma de prevenção reativa é a utilização de sistemas de detecção de intrusos , que monitoram uma rede por assinatura de ataques conhecidos.
É claro que esses recursos são muito bem-vindos, mas é importante aplicar também uma estratégia de prevenção proativa, estabelecendo processos de desenvolvimento seguros com etapas automatizadas de revisão do código.
Assim, a necessidade de uma abordagem reativa será mais escassa e sua aplicação ficará bem mais segura.
No caso da abordagem reativa, todos os recursos a serem adotados devem fazer parte de seu plano de resposta a incidentes que, além do buffer overflow, também devem considerar outras possibilidades de vulnerabilidades de sua aplicação. Leia nosso artigo sobre o assunto para elaborar o seu plano.
Quer amadurecer seu programa de segurança cibernética? Conheça a EcoTrust, uma plataforma CAASM (Cyber Asset Attack Surface Management) que transforma riscos cibernéticos em respostas confiáveis. Agende uma demo aqui