Overflow

1. Overflow

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 19/09/2012 - 20:09h

olá, pessoal, bem comecei aestudar buffer overflow, e achei um exemplo de código :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* Altere o PATH conforme o local que se encontra o arquivo bugado, bem
como o tamanho que iremos usar p/ sobrescrever o buffer */

#define PATH "Vulnerable"
#define A 0x41
#define TAMANHO 700

main()
{
int i;
char *buffer = (char *)malloc(TAMANHO);

memset(buffer, A, TAMANHO-1);
printf("Enchendo o buffer com caracter A !\n");
execl(PATH,"Vunereble",buffer, NULL);
}

Quando ocorre o overflow ele sobrescreve o ponto de retorno ne? nessa hora como eu faço para o meu código ser executado?

isso só funciona em programas na linha de comando? e caso ele tenha interface gráfica? é possível fazer isso?


  


2. Re: Overflow

Paulo
paulo1205

(usa Ubuntu)

Enviado em 19/09/2012 - 23:32h

Buffer overflow é simplesmente guardar mais dados num buffer (tipicamente um array de tamanho fixo) do que o que ele está preparado para armazenar. Um buffer overflow, portanto, pode acontecer até mesmo sem querer, por um erro de programação não percebido, e sem depender de qualquer tipo de ataque intencional provenienete de uma fonte externa.

No entanto, por causa de detalhes da arquitetura do processador, o overflow de um buffer pode servir de porta de entrada para ataques que induzam a um comportamento errôneo de um programa em execução. Esse comportamento errôneo pode até ser inócuo, mas geralmente provoca interrupção de serviços, corrupção de dados e, em alguns casos, pode permitir a um atacante executar código arbitrário na máquina atacada, usando privilégios e/ou credenciais que concedidos ao programa no qual o buffer overflow foi provocado.

No código que você postou não existe buffer overflow, como você pode observar pela alocação de uma determinada quantidade de bytes e pelo preenchimento da memória alocada com exatamente essa quantidade de bytes. No entanto, ele parece com a tentativa de explorar uma potencial vulnerabilidade residente num outro programa, através da execução de um programa externo (indicado na macro PATH) com um argumento que ele não conseguirá tratar ou que será encaminhado para um terceiro programa que não conseguirá tratá-lo.

Um programa vulnerável a buffer overflow normalmente tem um bloco de código com a seguinte cara.

void get_msg_from_external_source(socket_t external_source){
char msg_buffer[EXPECTED_MSG_MAX_SIZE]; /* Buffer de tamanho fixo, alocado na pilha *
* do processador (não via malloc(), que *
* usaria outra faixa de memória). A pilha *
* é a mesma região que guarda o endereço *
* de retorno, para o qual o programa des- *
* viará quando a função terminar. */
int msg_len;

/* Primeiros bytes indicam o tamanho do restante da mensagem. */
recv(external_source, &msg_len, sizeof msg_len, 0);

/* PROBLEMA AQUI: note que ele vai tentar receber o restante da mensagem, *
* de acordo com a quantidade de bytes informada anteriormente, mas sem *
* verificar se essa quantidade excede o valor de EXPECTED_MSG_MAX_SIZE. */
recv(external_source, msg_buffer, msg_len, 0);

/* ... */
}


Uma variação sujeita ao mesmo problema seria código que, em lugar de ter um indicador de tamanho máximo enviado a priori, usasse um marcador de final de mensagem, e ficasse acrescendo dados ao final do buffer até enxergar esse marcador, mas sem verificar se o tamanho do buffer já foi ultrapassado.

Note que a fonte externa de dados não necessariamente é um socket, mas pode ser qualquer coisa que forneça dados ao programa em tempo de execução.

A técnica clássica para usar o buffer overflow para ganhar acesso é enviar bytes correspondentes a código em linguagem de máquina de alguma coisa arbitrária que se queira executar. Geralmente esse código vai próximo ao início do buffer e é relativamente curto (algo como apenas um poucos bytes, suficientes para conseguir acionar alguma função que permita continuar o ataque de modo mais sofisticado e controlado numa etapa posterior). O restante do buffer e o início do overflow propriamente dito podem ser preenchidos com qualquer coisa, até atingir a posição de memória na pilha em que é guardado o endereço de retorno da função. Nesso momento, então, os bytes enviados têm de ser tais que provoquem um desvio para o bloco de código arbitrário que acabou de ser enviado no momento em que o endereço de retorno for retirado da pilha pelo procedimento de retorno da função.

Um bom ataque baseado em buffer overflow, portanto, exige um conhecimento razoável (que pode ser obtido de várias formas, desde engenharia reversa até o exame do código fonte, no caso de programas open source) sobre a disposição de dados na função que for posta sob ataque, e também sobre a arquitetura do sistema em que o programa sob ataque estiver sendo executado. É extremamente improvável que um ataque para obtenção de acesso remoto numa aplicação rodando sobre Windows funcione da mesma maneira se perpetrado sobre a mesma aplicação quando ela estiver sobre Linux.

Note que hoje em dia os processadores têm mecanismos para evitar ataques desse tipo. Normalmente, um segmento ou página de memória que contém dados modificáveis, tal como a pilha, é marcada nos processadores modernos como não-executável, e eventuais tentativas de fazer com que o programa faça desvio do fluxo de execução para dentro desses segmentos provocará o imediato disparo de uma exceção de falha de segmentação.


3. Re: Overflow

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 20/09/2012 - 17:58h

É, na verdade esse era o código do ataque...
então essa técnica não é muito recomendada? e também pelos exemplos que já vi, são falhas 'bobas' para que um programa grande ter...






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts