Estouro de buffer - Buffer overflow

Em segurança da informação e programação , um estouro de buffer , ou saturação de buffer , é uma anomalia em que um programa , enquanto grava dados em um buffer , ultrapassa os limites do buffer e sobrescreve as localizações de memória adjacentes .

Buffers são áreas da memória reservadas para armazenar dados, geralmente ao movê-los de uma seção de um programa para outra ou entre programas. Estouros de buffer geralmente podem ser disparados por entradas malformadas; se assumirmos que todas as entradas serão menores do que um certo tamanho e o buffer for criado para ter esse tamanho, então uma transação anômala que produza mais dados pode fazer com que ele grave além do final do buffer. Se isso sobrescrever dados adjacentes ou código executável, isso pode resultar em comportamento errático do programa, incluindo erros de acesso à memória, resultados incorretos e travamentos .

Explorar o comportamento de um estouro de buffer é uma exploração de segurança bem conhecida . Em muitos sistemas, o layout da memória de um programa, ou do sistema como um todo, é bem definido. Ao enviar dados projetados para causar um estouro de buffer, é possível escrever em áreas conhecidas por conter código executável e substituí-lo por código malicioso , ou sobrescrever seletivamente os dados pertencentes ao estado do programa, causando, portanto, um comportamento não pretendido pelo programador original. Os buffers são amplamente difundidos no código do sistema operacional (SO), portanto, é possível fazer ataques que realizam escalonamento de privilégios e obtêm acesso ilimitado aos recursos do computador. O famoso worm Morris em 1988 usou isso como uma de suas técnicas de ataque.

Linguagens de programação comumente associadas a estouros de buffer incluem C e C ++ , que não fornecem proteção embutida contra acesso ou sobrescrita de dados em qualquer parte da memória e não verificam automaticamente se os dados gravados em um array (o tipo de buffer embutido) estão dentro os limites dessa matriz. A verificação de limites pode evitar estouros de buffer, mas requer código adicional e tempo de processamento. Os sistemas operacionais modernos usam uma variedade de técnicas para combater estouros de buffer maliciosos, notavelmente randomizando o layout da memória ou deixando deliberadamente espaço entre os buffers e procurando ações que gravam nessas áreas ("canários").

Descrição técnica

Um estouro de buffer ocorre quando os dados gravados em um buffer também corrompem os valores dos dados em endereços de memória adjacentes ao buffer de destino devido à verificação insuficiente de limites . Isso pode ocorrer ao copiar dados de um buffer para outro sem primeiro verificar se os dados cabem no buffer de destino.

Exemplo

No exemplo a seguir expresso em C , um programa tem duas variáveis ​​adjacentes na memória: um buffer de string de 8 bytes, A, e um inteiro big-endian de dois bytes , B.

char           A[8] = "";
unsigned short B    = 1979;

Inicialmente, A contém nada além de zero bytes e B contém o número 1979.

nome variável UMA B
valor [ string nula ] 1979
valor hexadecimal 00 00 00 00 00 00 00 00 07 BB

Agora, o programa tenta armazenar a string terminada em nulo "excessive" com codificação ASCII no buffer A.

strcpy(A, "excessive");

"excessive"tem 9 caracteres e codifica para 10 bytes, incluindo o terminador nulo, mas A pode ter apenas 8 bytes. Ao não verificar o comprimento da string, ele também substitui o valor de B:

nome variável UMA B
valor 'e' 'x' 'c' 'e' 's' 's' 'i' 'v' 25856
hex 65 78 63 65 73 73 69 76 65 00

O valor de B foi agora inadvertidamente substituído por um número formado a partir de parte da cadeia de caracteres. Neste exemplo, "e" seguido por um byte zero se tornaria 25856.

A gravação de dados além do fim da memória alocada pode, às vezes, ser detectada pelo sistema operacional para gerar um erro de falha de segmentação que encerra o processo.

Para evitar que o estouro do buffer aconteça neste exemplo, a chamada para strcpypoderia ser substituída por strlcpy, que usa a capacidade máxima de A (incluindo um caractere de terminação nula) como um parâmetro adicional e garante que não mais do que esta quantidade de dados seja gravada para A:

strlcpy(A, "excessive", sizeof(A));

Quando disponível, a strlcpyfunção de biblioteca é preferida em vez de strncpyque não termine nulo o buffer de destino se o comprimento da string de origem for maior ou igual ao tamanho do buffer (o terceiro argumento passado para a função), portanto, não Apode ser nulo- terminada e não pode ser tratada como uma string C-style válida.

Exploração

As técnicas para explorar uma vulnerabilidade de estouro de buffer variam por arquitetura , sistema operacional e região de memória. Por exemplo, a exploração no heap (usada para memória alocada dinamicamente) difere marcadamente da exploração na pilha de chamadas .

Exploração baseada em pilha

Um usuário com inclinação técnica pode explorar estouros de buffer baseados em pilha para manipular o programa em seu benefício de uma das várias maneiras:

  • Substituindo uma variável local que está localizada perto do buffer vulnerável na pilha, a fim de alterar o comportamento do programa
  • Sobrescrevendo o endereço de retorno em um frame de pilha para apontar para o código selecionado pelo invasor, geralmente chamado de shellcode . Assim que a função retornar, a execução será retomada no shellcode do invasor.
  • Sobrescrevendo um ponteiro de função ou manipulador de exceção para apontar para o shellcode, que é subsequentemente executado
  • Sobrescrevendo uma variável local (ou ponteiro) de um quadro de pilha diferente, que será usado pela função que possui esse quadro posteriormente.

O invasor projeta dados para causar uma dessas explorações e, em seguida, coloca esses dados em um buffer fornecido aos usuários pelo código vulnerável. Se o endereço dos dados fornecidos pelo usuário usados ​​para afetar o estouro do buffer da pilha for imprevisível, explorar um estouro do buffer da pilha para causar a execução remota de código se torna muito mais difícil. Uma técnica que pode ser usada para explorar esse estouro de buffer é chamada de " trampolim ". Nessa técnica, um invasor encontrará um ponteiro para o buffer de pilha vulnerável e calculará a localização de seu código de shell em relação a esse ponteiro. Então, eles usarão o overwrite para pular para uma instrução já na memória que fará um segundo salto, desta vez em relação ao ponteiro; esse segundo salto ramificará a execução para o shellcode. As instruções adequadas estão frequentemente presentes em código grande. O Projeto Metasploit , por exemplo, mantém um banco de dados de opcodes adequados, embora liste apenas aqueles encontrados no sistema operacional Windows .

Exploração baseada em heap

Um estouro de buffer que ocorre na área de dados de heap é conhecido como estouro de heap e pode ser explorado de uma maneira diferente daquela dos estouros baseados em pilha. A memória no heap é alocada dinamicamente pelo aplicativo no tempo de execução e normalmente contém dados do programa. A exploração é realizada corrompendo esses dados de maneiras específicas para fazer com que o aplicativo sobrescreva estruturas internas, como ponteiros de lista vinculada. A técnica de estouro de heap canônico sobrescreve o vínculo de alocação de memória dinâmica (como os metadados malloc ) e usa a troca de ponteiro resultante para sobrescrever um ponteiro de função de programa.

A vulnerabilidade GDI + da Microsoft no tratamento de JPEGs é um exemplo do perigo que um estouro de heap pode apresentar.

Barreiras à exploração

A manipulação do buffer, que ocorre antes de ser lido ou executado, pode levar ao fracasso de uma tentativa de exploração. Essas manipulações podem mitigar a ameaça de exploração, mas não podem torná-la impossível. As manipulações podem incluir conversão para maiúsculas ou minúsculas, remoção de metacaracteres e filtragem de strings não alfanuméricas . No entanto, existem técnicas para contornar esses filtros e manipulações; código alfanumérico , código polimórfico , código de auto-modificando e ataques de retorno ao libc . Os mesmos métodos podem ser usados ​​para evitar a detecção por sistemas de detecção de intrusão . Em alguns casos, incluindo quando o código é convertido em Unicode , a ameaça da vulnerabilidade foi deturpada pelos divulgadores como apenas negação de serviço quando, na verdade, a execução remota de código arbitrário é possível.

Aspectos práticos da exploração

Em exploits do mundo real, há uma variedade de desafios que precisam ser superados para que os exploits operem de forma confiável. Esses fatores incluem bytes nulos em endereços, variabilidade na localização do shellcode, diferenças entre ambientes e várias contra-medidas em operação.

Técnica de trenó NOP

Ilustração de uma carga útil do trenó NOP na pilha.

Um NOP-sled é a técnica mais antiga e mais amplamente conhecida para explorar estouros de buffer de pilha. Ele resolve o problema de encontrar o endereço exato do buffer, aumentando efetivamente o tamanho da área de destino. Para fazer isso, seções muito maiores de pilha estão corrompidos com o não-op instrução de máquina. No final dos dados fornecidos pelo invasor, após as instruções no-op, o invasor coloca uma instrução para realizar um salto relativo para o topo do buffer onde o shellcode está localizado. Esta coleção de autônomos é conhecida como "NOP-sled" porque se o endereço de retorno for substituído por qualquer endereço dentro da região autônoma do buffer, a execução "deslizará" para o autônomo até que seja redirecionado para o código malicioso real pelo salto no final. Essa técnica exige que o invasor adivinhe onde está o NOP-sled na pilha, em vez do código de shell comparativamente pequeno.

Por causa da popularidade desta técnica, muitos fornecedores de sistemas de prevenção de intrusão irão procurar por esse padrão de instruções de máquina autônoma na tentativa de detectar o shellcode em uso. É importante observar que um trenó NOP não contém necessariamente apenas as instruções tradicionais da máquina sem operação; qualquer instrução que não corrompa o estado da máquina a um ponto em que o shellcode não seja executado pode ser usada no lugar do no-op assistido por hardware. Como resultado, tornou-se prática comum para escritores de exploits compor o trenó autônomo com instruções escolhidas aleatoriamente que não terão nenhum efeito real na execução do shellcode.

Embora esse método melhore muito as chances de um ataque ser bem-sucedido, ele apresenta problemas. Os exploits que usam esta técnica ainda devem contar com um pouco de sorte para adivinhar os deslocamentos na pilha que estão dentro da região do trenó NOP. Uma suposição incorreta geralmente resultará na falha do programa de destino e pode alertar o administrador do sistema sobre as atividades do invasor. Outro problema é que o trenó NOP requer uma quantidade muito maior de memória para armazenar um trenó NOP grande o suficiente para ser útil. Isso pode ser um problema quando o tamanho alocado do buffer afetado é muito pequeno e a profundidade atual da pilha é rasa (ou seja, não há muito espaço do final do quadro da pilha atual até o início da pilha). Apesar de seus problemas, o NOP-sled costuma ser o único método que funcionará para uma determinada plataforma, ambiente ou situação e, como tal, ainda é uma técnica importante.

O salto para o endereço armazenado em uma técnica de registro

A técnica de "salto para registrar" permite a exploração confiável de estouros de buffer de pilha sem a necessidade de espaço extra para um NOP-sled e sem ter que adivinhar os deslocamentos da pilha. A estratégia é sobrescrever o ponteiro de retorno com algo que fará com que o programa salte para um ponteiro conhecido armazenado dentro de um registro que aponta para o buffer controlado e, portanto, para o shellcode. Por exemplo, se o registro A contém um ponteiro para o início de um buffer, qualquer salto ou chamada que receba esse registro como um operando pode ser usado para obter o controle do fluxo de execução.

Uma instrução de ntdll.dll para chamar a DbgPrint()rotina contém o opcode da máquina i386 para jmp esp.

Na prática, um programa pode não conter intencionalmente instruções para saltar para um determinado registro. A solução tradicional é encontrar uma instância não intencional de um opcode adequado em um local fixo em algum lugar da memória do programa. Na figura E à esquerda está um exemplo de uma instância não intencional da jmp espinstrução i386 . O opcode para esta instrução é FF E4. Esta sequência de dois bytes pode ser encontrada em um deslocamento de um byte desde o início da instrução call DbgPrintno endereço 0x7C941EED. Se um invasor sobrescrever o endereço de retorno do programa com este endereço, o programa irá primeiro pular 0x7C941EED, interpretar o opcode FF E4como a jmp espinstrução e então saltar para o topo da pilha e executar o código do invasor.

Quando essa técnica é possível, a gravidade da vulnerabilidade aumenta consideravelmente. Isso ocorre porque a exploração funcionará de forma confiável o suficiente para automatizar um ataque com uma garantia virtual de sucesso quando ele for executado. Por esse motivo, essa é a técnica mais comumente usada em worms da Internet que exploram vulnerabilidades de estouro de buffer de pilha.

Este método também permite que o shellcode seja colocado após o endereço de retorno sobrescrito na plataforma Windows. Como os executáveis ​​são baseados principalmente em endereço 0x00400000e x86 é uma arquitetura Little Endian , o último byte do endereço de retorno deve ser nulo, o que encerra a cópia do buffer e nada é escrito além disso. Isso limita o tamanho do shellcode ao tamanho do buffer, que pode ser excessivamente restritivo. As DLLs estão localizadas na memória alta (acima 0x01000000) e, portanto, têm endereços que não contêm bytes nulos, portanto, esse método pode remover bytes nulos (ou outros caracteres não permitidos) do endereço de retorno sobrescrito. Usado dessa forma, o método costuma ser chamado de "trampolim de DLL".

Contramedidas de proteção

Várias técnicas têm sido usadas para detectar ou evitar estouros de buffer, com várias desvantagens. A maneira mais confiável de evitar ou prevenir estouros de buffer é usar proteção automática no nível do idioma. Esse tipo de proteção, no entanto, não pode ser aplicado ao código legado e, muitas vezes, as restrições técnicas, comerciais ou culturais exigem uma linguagem vulnerável. As seções a seguir descrevem as opções e implementações disponíveis.

Escolha da linguagem de programação

Assembly e C / C ++ são linguagens de programação populares que são vulneráveis ​​ao estouro de buffer, em parte porque permitem acesso direto à memória e não são fortemente tipadas . C não fornece proteção embutida contra acesso ou substituição de dados em qualquer parte da memória; mais especificamente, ele não verifica se os dados gravados em um buffer estão dentro dos limites desse buffer. As bibliotecas C ++ padrão fornecem muitas maneiras de armazenar dados em buffer com segurança, e a Biblioteca de Modelos Padrão (STL) do C ++ fornece contêineres que podem, opcionalmente, realizar a verificação de limites se o programador chamar explicitamente para verificações ao acessar os dados. Por exemplo, uma vectorfunção de membro de at()executa uma verificação de limites e lança uma out_of_range exceção se a verificação de limites falhar. No entanto, C ++ se comporta exatamente como C se a verificação de limites não for chamada explicitamente. Técnicas para evitar estouros de buffer também existem para C.

Linguagens fortemente tipadas e não permitem acesso direto à memória, como COBOL, Java, Python e outras, evitam que ocorra estouro de buffer na maioria dos casos. Muitas linguagens de programação diferentes de C / C ++ fornecem verificação de tempo de execução e, em alguns casos, até verificação de tempo de compilação que pode enviar um aviso ou gerar uma exceção quando C ou C ++ sobrescreveria dados e continuasse a executar instruções adicionais até que resultados errôneos sejam obtidos, o que pode ou pode não causar o travamento do programa. Exemplos de tais linguagens incluem Ada , Eiffel , Lisp , Modula-2 , Smalltalk , OCaml e tais derivados C-como ciclone , oxidação e D . Os ambientes de bytecode Java e .NET Framework também exigem verificação de limites em todos os arrays. Quase todas as linguagens interpretadas protegerão contra estouros de buffer, sinalizando uma condição de erro bem definida. Freqüentemente, quando um idioma fornece informações de tipo suficientes para fazer a verificação de limites, é fornecida uma opção para habilitá-lo ou desabilitá-lo. A análise de código estático pode remover muitos limites dinâmicos e verificações de tipo, mas implementações ruins e casos estranhos podem diminuir significativamente o desempenho. Os engenheiros de software devem considerar cuidadosamente as compensações entre custos de segurança e desempenho ao decidir qual linguagem e configuração do compilador usar.

Uso de bibliotecas seguras

O problema de estouros de buffer é comum nas linguagens C e C ++ porque elas expõem detalhes de representação de baixo nível de buffers como contêineres para tipos de dados. Estouros de buffer devem, portanto, ser evitados mantendo um alto grau de correção no código que executa o gerenciamento de buffer. Também tem sido recomendado evitar funções de biblioteca padrão que não tenham limites verificados, como gets, scanfe strcpy. O worm Morris explorou uma getschamada em fingerd .

Bibliotecas de tipos de dados abstratos bem escritas e testadas, que centralizam e executam automaticamente o gerenciamento de buffer, incluindo a verificação de limites, podem reduzir a ocorrência e o impacto de estouros de buffer. Os dois principais tipos de dados de bloco de construção nessas linguagens em que ocorre comumente buffer overflows são strings e arrays; portanto, as bibliotecas que evitam estouros de buffer nesses tipos de dados podem fornecer a grande maioria da cobertura necessária. Ainda assim, a falha em usar essas bibliotecas seguras corretamente pode resultar em estouros de buffer e outras vulnerabilidades; e, naturalmente, qualquer bug na própria biblioteca é uma vulnerabilidade potencial. Implementações de biblioteca "seguras" incluem "The Better String Library", Vstr e Erwin. O OpenBSD do sistema operacional biblioteca C fornece os strlcpy e strlcat funções, mas estes são mais limitadas do que as implementações de biblioteca de segurança completos.

Em setembro de 2007, foi publicado o Relatório Técnico 24731, elaborado pelo comitê de padrões C; ele especifica um conjunto de funções que são baseadas na string da biblioteca C padrão e nas funções de E / S, com parâmetros adicionais de tamanho de buffer. No entanto, a eficácia dessas funções com o objetivo de reduzir estouros de buffer é discutível; requer intervenção do programador por chamada de função que é equivalente à intervenção que poderia tornar seguro o estouro de buffer de funções de biblioteca padrão análogo mais antigo.

Proteção contra estouro de buffer

A proteção contra estouro de buffer é usada para detectar os estouros de buffer mais comuns, verificando se a pilha não foi alterada quando uma função retorna. Se tiver sido alterado, o programa sai com uma falha de segmentação . Três destes sistemas são Libsafe, e os StackGuard e ProPolice gcc remendos.

A implementação da Microsoft do modo Data Execution Prevention (DEP) protege explicitamente o ponteiro para o Structured Exception Handler (SEH) de ser sobrescrito.

Uma proteção de pilha mais forte é possível dividindo a pilha em duas: uma para dados e outra para retornos de função. Essa divisão está presente na linguagem Forth , embora não tenha sido uma decisão de design baseada na segurança. Independentemente disso, essa não é uma solução completa para buffer overflows, pois dados confidenciais além do endereço de retorno ainda podem ser substituídos.

Proteção de ponteiro

Os estouros de buffer funcionam manipulando ponteiros , incluindo endereços armazenados. O PointGuard foi proposto como uma extensão do compilador para evitar que invasores sejam capazes de manipular ponteiros e endereços de forma confiável. A abordagem funciona fazendo com que o compilador adicione código para ponteiros de codificação XOR automaticamente antes e depois de serem usados. Teoricamente, como o invasor não sabe qual valor será usado para codificar / decodificar o ponteiro, ele não pode prever para onde ele apontará se o sobrescrever com um novo valor. PointGuard nunca foi lançado, mas a Microsoft implementou uma abordagem semelhante começando no Windows XP SP2 e Windows Server 2003 SP1. Em vez de implementar a proteção de ponteiro como um recurso automático, a Microsoft adicionou uma rotina de API que pode ser chamada. Isso permite um melhor desempenho (porque não é usado o tempo todo), mas sobrecarrega o programador para saber quando é necessário.

Como o XOR é linear, um invasor pode manipular um ponteiro codificado sobrescrevendo apenas os bytes inferiores de um endereço. Isso pode permitir que um ataque seja bem-sucedido se o invasor conseguir tentar a exploração várias vezes ou concluir um ataque fazendo com que um ponteiro aponte para um dos vários locais (como qualquer local dentro de um trenó NOP). A Microsoft adicionou uma rotação aleatória ao seu esquema de codificação para lidar com essa deficiência nas substituições parciais.

Proteção de espaço executável

A proteção do espaço executável é uma abordagem à proteção contra estouro de buffer que impede a execução de código na pilha ou heap. Um invasor pode usar buffer overflows para inserir código arbitrário na memória de um programa, mas com proteção de espaço executável, qualquer tentativa de executar esse código causará uma exceção.

Algumas CPUs suportam um recurso chamado NX ("No eXecute") ou XD ("eXecute Disabled") bit, que em conjunto com o software, pode ser usado para marcar páginas de dados (como aquelas contendo a pilha e o heap) como legíveis e gravável, mas não executável.

Alguns sistemas operacionais Unix (por exemplo , OpenBSD , macOS ) vêm com proteção de espaço executável (por exemplo, W ^ X ). Alguns pacotes opcionais incluem:

Variantes mais recentes do Microsoft Windows também oferecem suporte à proteção de espaço executável, chamada de Prevenção de Execução de Dados . Os add-ons proprietários incluem:

  • BufferShield
  • StackDefender

A proteção do espaço executável geralmente não protege contra ataques de retorno à libc ou qualquer outro ataque que não dependa da execução do código do invasor. No entanto, em sistemas de 64 bits que usam ASLR , conforme descrito abaixo, a proteção do espaço executável torna muito mais difícil executar esses ataques.

Randomização do layout do espaço de endereço

A randomização do layout do espaço de endereço (ASLR) é um recurso de segurança do computador que envolve organizar as posições das áreas de dados principais, geralmente incluindo a base do executável e a posição das bibliotecas, heap e pilha, aleatoriamente no espaço de endereço de um processo.

A randomização dos endereços de memória virtual nos quais funções e variáveis ​​podem ser encontradas pode tornar a exploração de um estouro de buffer mais difícil, mas não impossível. Ele também força o invasor a adaptar a tentativa de exploração ao sistema individual, o que frustra as tentativas de worms da Internet . Um método semelhante, mas menos eficaz, é realocar processos e bibliotecas no espaço de endereço virtual.

Inspeção profunda de pacotes

O uso de inspeção profunda de pacotes (DPI) pode detectar, no perímetro da rede, tentativas remotas muito básicas de explorar estouros de buffer por meio de assinaturas de ataque e heurísticas . Eles são capazes de bloquear pacotes que têm a assinatura de um ataque conhecido, ou se uma longa série de instruções de não operação (conhecidas como NOP-sled) for detectada, elas já foram usadas quando a localização da carga útil do exploit é ligeiramente variável .

A varredura de pacotes não é um método eficaz, pois só pode impedir ataques conhecidos e há muitas maneiras de codificar um NOP-sled. Shellcode utilizado por atacantes pode ser feito alfanumérico , metamórfica , ou auto-modificando para evitar a detecção por scanners de pacotes heurísticos e sistemas de detecção de intrusão .

Testando

Verificar estouros de buffer e corrigir os bugs que os causam ajuda a prevenir estouros de buffer. Uma técnica automatizada comum para descobri-los é o fuzzing . O teste de casos extremos também pode revelar estouros de buffer, assim como a análise estática. Uma vez que um estouro de buffer potencial é detectado, ele deve ser corrigido; isso torna a abordagem de teste útil para software que está em desenvolvimento, mas menos útil para software legado que não é mais mantido ou suportado.

História

Estouros de buffer foram compreendidos e parcialmente documentados publicamente já em 1972, quando o Computer Security Technology Planning Study estabeleceu a técnica: "O código que executa esta função não verifica os endereços de origem e destino de maneira adequada, permitindo que partes do monitor sejam sobrepostas por usuário. Isso pode ser usado para injetar código no monitor que permitirá ao usuário assumir o controle da máquina. " Hoje, o monitor seria referido como kernel.

A primeira exploração hostil documentada de um estouro de buffer foi em 1988. Foi uma das várias explorações usadas pelo worm Morris para se propagar pela Internet. O programa explorado era um serviço em Unix denominado finger . Mais tarde, em 1995, Thomas Lopatic redescobriu independentemente o estouro do buffer e publicou suas descobertas na lista de discussão de segurança Bugtraq . Um ano depois, em 1996, Elias Levy (também conhecido como Aleph One) publicou na revista Phrack o artigo "Smashing the Stack para diversão e lucro", uma introdução passo a passo para explorar vulnerabilidades de estouro de buffer baseado em pilha.

Desde então, pelo menos dois grandes worms da Internet exploraram estouros de buffer para comprometer um grande número de sistemas. Em 2001, o worm Code Red explorou um estouro de buffer no Internet Information Services (IIS) 5.0 da Microsoft e, em 2003, o worm SQL Slammer comprometeu máquinas executando o Microsoft SQL Server 2000 .

Em 2003, estouros de buffer presentes em jogos Xbox licenciados foram explorados para permitir que software não licenciado, incluindo jogos homebrew , rodasse no console sem a necessidade de modificações de hardware, conhecidas como modchips . O PS2 Independence Exploit também usou um estouro de buffer para conseguir o mesmo para o PlayStation 2 . O hack Twilight fez o mesmo com o Wii , usando um buffer overflow em The Legend of Zelda: Twilight Princess .

Veja também

Referências

links externos