Java tem buffer overflows?


96

Java tem buffer overflows? Se sim, você pode me dar cenários?


2
Algumas funções de biblioteca (implementadas em código nativo) são conhecidas por terem bugs. Especialmente na área do Java 5, muitos exploits em 2D, perfis de som ou cor são conhecidos.
eckes de

Respostas:


108

Como as Java Strings são baseadas em matrizes de char e o Java verifica automaticamente os limites da matriz, estouros de buffer só são possíveis em cenários incomuns:

  1. Se você chamar o código nativo via JNI
  2. No próprio JVM (geralmente escrito em C ++)
  3. O interpretador ou compilador JIT não funciona corretamente (verificações de limites obrigatórias de bytecode Java)

24

Linguagens gerenciadas como Java e C # não têm esses problemas, mas as máquinas virtuais específicas (JVM / CLR / etc) que realmente executam o código podem.


5
C # em um contexto não seguro pode ter estouros de buffer. Java como uma linguagem proíbe totalmente isso (você deve alterar os idiomas via JNI para obter acesso ao ponteiro não gerenciado)
ShuggyCoUk

1
Bom ponto. Com o C # inseguro, você obviamente não está mais em uma área restrita em um mundo gerenciado confortável.
Brian Rasmussen

1
Certo, e mesmo que VOCÊ não escreva nada inseguro ou faça interoperabilidade, você pode estar usando uma biblioteca que o faz. Portanto, isso é algo a ter em atenção.
BobbyShaftoe

13

Para todos os efeitos e propósitos, não.

Java tem verificação de limites de array, que verifica se os dados não podem ser acessados ​​de uma área fora do array alocado. Quando alguém tenta acessar uma área que está além do tamanho do array, uma ArrayOutOfBoundsexceção será lançada.

Se houver uma saturação de buffer, provavelmente é devido a um bug na Java Virtual Machine e, até onde sei, não é o comportamento pretendido que está escrito nas Especificações da linguagem Java nem nas especificações da Java Virtual Machine.


10

Sim e não. Não, porque você realmente não pode criar, por engano, abrir-se para uma vulnerabilidade de estouro de buffer porque é um modelo de memória gerenciada. No entanto, pode haver vulnerabilidades de estouro de buffer na JVM e JDK. Veja este comunicado da Secunia:

http://secunia.com/advisories/25295

Ou veja estes avisos antigos sobre várias vulnerabilidades JDK e JRE anteriores:

  • Vulnerabilidades de estouro de buffer e inteiros no Java Runtime Environment (JRE) "unpack200" O utilitário de descompactação JAR pode levar ao aumento de privilégios https://download.oracle.com/sunalerts/1020225.1.html

    Vulnerabilidades de estouro de buffer e inteiros no Java Runtime Environment (JRE) com miniaplicativos de descompactação e aplicativos Java Web Start usando o utilitário de descompactação JAR "unpack200" podem permitir que um miniaplicativo ou aplicativo não confiável aumente privilégios. Por exemplo, um miniaplicativo não confiável pode conceder a si mesmo permissões para ler e gravar arquivos locais ou executar aplicativos locais acessíveis ao usuário que executa o miniaplicativo não confiável.

    Sun agradece, "regenrecht" trabalhar com o iDefense VCP ( http://labs.idefense.com/vcp/ ) e Chris Evans, do Google, por chamar nossa atenção para esses problemas.

  • Várias vulnerabilidades foram identificadas no Sun Java Development Kit (JDK) e Java Runtime Environment (JRE). https://security.gentoo.org/glsa/200705-23

    Uma vulnerabilidade não especificada envolvendo um "uso incorreto de classes do sistema" foi relatada pela equipe de segurança da Fujitsu. Além disso, Chris Evans, da equipe de segurança do Google, relatou um estouro de número inteiro resultando em um estouro de buffer no analisador ICC usado com arquivos JPG ou BMP e uma chamada open () incorreta para / dev / tty ao processar certos arquivos BMP.


9

Um estouro de buffer, no sentido estrito de sobrescrever a pilha ou o próprio heap, exigiria:

  1. Um bug na estrutura (eles existiram no passado e podem muito bem novamente)
  2. O uso de JNI (essencialmente, não usando mais código gerenciado)

Um estouro de buffer no sentido de que você tem código usando um buffer e seu código é responsável por analisá-lo corretamente, mas é possível deixar de fazê-lo. Por exemplo, você pode escrever um analisador XML e alguém pode fornecer a você uma solicitação malformada (ou legítima, mas incomum) que, devido ao design do seu analisador, substitui os dados previamente validados por alguma carga útil que faria com que seu aplicativo se comportasse mal.

Esta última forma é menos provável, mas uma função de limpeza de string sql mal escrita e amplamente distribuída que tivesse um problema como este seria um alvo convidativo.


4

As máquinas virtuais Java (e .Net) capturam o código que tenta gravar fora da memória reservada. Aplicativos que não lidam com isso corretamente ainda podem causar problemas de segurança. Se usuários mal-intencionados podem acionar exceções inserindo entradas inválidas, eles podem fazer ataques de negação de serviço, por exemplo.


3

Como já foi apontado, o Java tem, como linguagem, a verificação de limites em todos os acessos à memória e, se houver um erro aqui, a falha é do JVM e não do programa. No entanto, o que deve ser observado, que é um argumento semelhante para vazamentos de memória em Java; embora não seja possível destruir a pilha, uma ArrayOutOfBoundsException no lugar errado, que não é tratada corretamente, pode acabar bagunçando o seu sistema.


3

É possível que você cause um estouro de buffer em um programa Java se estiver usando o recurso Java Native Interace (JNI) para chamar código externo e o código externo tiver um problema de exploração. Isso é bastante incomum, pois a maioria dos aplicativos evita o uso de JNI sempre que possível.


3

É possível para um método gravar em entradas válidas de uma matriz que ele não pretendia, normalmente por meio de estouro de inteiro.

Por exemplo, o seguinte não é suficiente para verificar os limites:

/* !! WRONG !! */ 0 <= off && 0 <= len && off+len <= buff.length /* !! WRONG !! */

O IIRC StringBufferjá teve um bug assim, mas não havia nada de interessante que você pudesse fazer com ele.


O que é suficiente para verificar os limites?
Broam

1
@Broam: 0 <= off && 0 <= len && off <= buff.length-leneu acho. Não me cite. Parece o mesmo, mas não há estouro possível (no original off + len pode ficar negativo e, portanto, obviamente menor que o comprimento do array). Certifique-se de que nenhum programador de manutenção o "arrume" da forma óbvia. Acho o estouro de inteiro extremamente confuso. Tenho que pensar um pouco, e então surge a suspeita incômoda de que entendi errado. Mas é claro que deveria haver outro revisor e o programador original - juntos, é claro, não há como um erro passar! (não)
Tom Hawtin - tackline em

Eu tive que olhar um pouco para isso, mas você está certo. off + len poderia estourar e quebrar ... em C. Em Java , a menos que eu esteja enganado - você obteria uma exceção de estouro antes que isso ocorresse, certo?
Broam

1
Não. A aritmética inteira silenciosamente envolve. C # tem um "modo" em que uma exceção é lançada no estouro, mas não acho que seja muito usado (se você pensar em usá-lo, provavelmente pensaria em fazer as coisas certas de qualquer maneira).
Tom Hawtin - tackline

1

Um dos principais recursos do JAVA é a segurança. Os programas escritos em linguagens interpretadas não estão sujeitos à exploração de estouro de buffer, mas você sempre pode causar um estouro de buffer no próprio Interpreter. Embora seja difícil. Da mesma forma, Python também é uma linguagem interpretada e está protegida contra estouro de buffer.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.