Explorando buffer overflow em C
A velha guarda antes dos GC#
Em tempos de GC nos anos 80/90 código em alto nível como C sempre era um problema se o programador não souber o que estava fazendo com a integridade dos dados pois é crucial a necessidade de alocar da maneira mais segura possível e com tradeoff bem afiado para não desenvolver um monstro e deixar tudo a cargo do compilador que eventualmente irá deixar seu binário de aplicação lerdo.
Explorando Buffer Overflow 0x320#
Estou indo para a 3 vez em que leio esse livro ele é antigo eu gosto mais dele por como ele se aprofunda em programação C, ASM, ShellScript do que realmente hacking.
No capitulo 0x320 somos introduzido ao exemplo:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int value = 5;
char primeiro_buffer[8], segundo_buffer[8];
strcpy(primeiro_buffer, "um"); /* Coloca "one" em primeiro_buffer. */
strcpy(segundo_buffer, "dois"); /* Coloca "two" em segundo_buffer. */
printf("[BEFORE] segundo_buffer está em %p e contém '%s'\n", segundo_buffer, segundo_buffer);
printf("[BEFORE] primeiro_buffer está em %p e contém '%s'\n", primeiro_buffer, primeiro_buffer);
printf("[BEFORE] value está em %p e é %d (0x%08x)\n", &value, value, value);
printf("\n[STRCPY] copiando %d bytes para segundo_buffer\n\n", strlen(argv[1]));
strcpy(segundo_buffer, argv[1]); /* Copia o primeiro argumento para segundo_buffer. */
printf("[AFTER] segundo_buffer está em %p e contém '%s'\n", segundo_buffer, segundo_buffer);
printf("[AFTER] primeiro_buffer está em %p e contém '%s'\n", primeiro_buffer, primeiro_buffer);
printf("[AFTER] value está em %p e é %d (0x%08x)\n", &value, value, value);
}
Vamos destrinchar o código por partes:

- Aqui nós iniciamos uma variável value um inteiro com valor 5.
- E aqui o mais importante abrimos dois arrays de Strings-buffers com tamanho fixo de 8.
Logo se o tamanho do array é 8 então abaixo podemos colocar strings dentro deles podem até ser maior como na foto usamos a lib strcpy ( não recomendada ) e atribuímos Strings ao nosso buffer
Agora vamos para o meio do código:
Para simplificar o exemplo usa printf hardcoded para ser prático mas é possível ver tudo isso pelo GBD. Vamos as legendas - VERMELHO: %p esse parâmetro no printf mostra aonde está o ponteiro/endereço de memoria.
- VERDE: %s esse parâmetro mostra Strings. E por ultimo vemos aquele inteiro de valor 5 só de referencia.
Se a gente rodar o código com os parâmetros 123456789 é assim que fica o output:
Aqui nada fora do normal o segundo buffer está no ponteiro com final ==69c== com a string ‘abcdefg’ e o primeiro buffer está no ponteiro com final ==6a4== com a string ‘um’.
( Lembre desse valores vamos voltar neles )
Não é uma boa prática se referencia apenas pelo final do ponteiro mas para ser didático e como eles são do mesmo tipo de dados não vai ter muita diferença no endereço só o final.
Agora vamos para a sacanagemprimeiro é um print usando strlen para contar quantos parâmetros tem nosso argv que é passado na hora de executar o código. No nosso caso é ‘1234567890’ 10 espaços.
E embaixo usando strcpy injetamos os 10 itens para um array/buffer de apenas 8 espaços, e nos perguntamos e agora o que acontece?? ( Vamos ver na proxima foto )
Antes de mostrar o resto do codigo e o resultado nós temos que pensar como se fosse os anos 80/90 aonde não existe um GC inteligente que não deixe você rodar um codigo assim ou no caso de linguagens interpretadas pythonquebrar a execução sem terminar a execução.
Aqui é o finalzinho do código nada novo é só para nós conseguirmos ver as alterações nos valores do ponteiro.
Olha como seria uma execução normal respeitando o tamanho do array.
O valor continua normalmente no primeiro buffer e atribuímos o valor do tamanho normal ao segundo buffer.
Agora olha que incrível se a gente atribuir 10 bytes ao segundo buffer sobra os 2 bytes que literalmente sobrescreve o próximo ponteiro em memoria que pela ordem é o primeiro buffer e assim de valor string ‘um’ se torna ‘90’.
Aqui vemos como um “BUG” de um usuário mal intencionado ou apenas mal informado pode corromper não só a execução do seu programa como também pode até sobrescrever dados.#
Imagina se a gente conseguisse fazer isso no banco e adicionar 90$ a uma conta com valor 0$. Eu acredito que bancos não funcionam assim, mas eu lembro que no livro mais para frente temos um exemplo estourando buffer e criando créditos de um script em C de caça-níquel que eu achei muito dahora e talvez eu traga para o blog. ( Depende do engajamento =! esforço )