Linux Forensics

Что такое linux forensics: определение, основные принципы, примеры и практические советы. Изучайте фундаментальной защите информации с подробными объяснениями для начинающих специалистов.

Linux Forensics - Расследование инцидентов в Linux

Что такое Linux Forensics?

Linux Forensics — это специализированная область цифровой криминалистики, фокусирующаяся на расследовании инцидентов безопасности в операционных системах Linux. Включает анализ логов, файловой системы, процессов, сетевой активности и системных артефактов.

Основные принципы

  • Systematic Approach — системный подход
  • Evidence Preservation — сохранение доказательств
  • Timeline Analysis — анализ временных меток
  • Artifact Correlation — корреляция артефактов
  • Legal Admissibility — правовая допустимость

Архитектура Linux Forensics

1. Log Analysis

// Система анализа логов Linux
class LinuxLogAnalyzer {
  constructor() {
    this.logs = new Map();
    this.events = new Map();
    this.patterns = new Map();
    this.correlations = new Map();
  }

  // Анализ системных логов
  analyzeSystemLogs(logData) {
    const analysis = {
      id: this.generateAnalysisId(),
      logType: logData.logType, // syslog, auth, kern, mail
      timeRange: logData.timeRange,
      events: [],
      anomalies: [],
      correlations: [],
      summary: {
        totalEvents: 0,
        criticalEvents: 0,
        warningEvents: 0,
        infoEvents: 0,
      },
    };

    // Парсинг событий
    const events = this.parseEvents(logData.content);
    analysis.events = events;

    // Анализ аномалий
    const anomalies = this.findAnomalies(events);
    analysis.anomalies = anomalies;

    // Корреляция событий
    const correlations = this.correlateEvents(events);
    analysis.correlations = correlations;

    // Расчет сводки
    this.calculateSummary(analysis);

    return analysis;
  }

  // Парсинг событий
  parseEvents(logContent) {
    const events = [];
    const lines = logContent.split("\n");

    for (const line of lines) {
      if (line.trim()) {
        const event = this.parseEventLine(line);
        if (event) {
          events.push(event);
        }
      }
    }

    return events;
  }

  // Парсинг строки события
  parseEventLine(line) {
    // Упрощенный парсинг syslog
    const parts = line.split(" ");
    if (parts.length < 6) return null;

    const timestamp = parts[0] + " " + parts[1] + " " + parts[2];
    const hostname = parts[3];
    const service = parts[4].replace(":", ");
    const message = parts.slice(5).join(" ");

    return {
      timestamp: new Date(timestamp),
      hostname: hostname,
      service: service,
      message: message,
      level: this.detectLogLevel(message),
      priority: this.calculatePriority(message),
    };
  }

  // Определение уровня лога
  detectLogLevel(message) {
    if (message.includes("CRITICAL") || message.includes("FATAL")) {
      return "CRITICAL";
    } else if (message.includes("ERROR") || message.includes("ERR")) {
      return "ERROR";
    } else if (message.includes("WARNING") || message.includes("WARN")) {
      return "WARNING";
    } else if (message.includes("INFO") || message.includes("NOTICE")) {
      return "INFO";
    } else if (message.includes("DEBUG")) {
      return "DEBUG";
    } else {
      return "UNKNOWN";
    }
  }

  // Расчет приоритета
  calculatePriority(message) {
    const level = this.detectLogLevel(message);
    const priorities = {
      CRITICAL: 0,
      ERROR: 1,
      WARNING: 2,
      INFO: 3,
      DEBUG: 4,
      UNKNOWN: 5,
    };
    return priorities[level] || 5;
  }

  // Поиск аномалий
  findAnomalies(events) {
    const anomalies = [];

    // Аномальные входы в систему
    const loginAnomalies = this.findLoginAnomalies(events);
    anomalies.push(...loginAnomalies);

    // Подозрительная активность
    const suspiciousActivity = this.findSuspiciousActivity(events);
    anomalies.push(...suspiciousActivity);

    // Ошибки системы
    const systemErrors = this.findSystemErrors(events);
    anomalies.push(...systemErrors);

    return anomalies;
  }

  // Поиск аномалий входа
  findLoginAnomalies(events) {
    const anomalies = [];
    const authEvents = events.filter(
      (e) => e.service === "sshd" || e.service === "login"
    );

    // Группировка по пользователям
    const userLogins = this.groupByUser(authEvents);

    for (const [user, logins] of userLogins) {
      // Проверка на множественные неудачные попытки
      const failedLogins = logins.filter((l) =>
        l.message.includes("Failed password")
      );
      if (failedLogins.length > 5) {
        anomalies.push({
          type: "MULTIPLE_FAILED_LOGINS",
          user: user,
          count: failedLogins.length,
          severity: "HIGH",
          description: `User ${user} has ${failedLogins.length} failed login attempts`,
        });
      }

      // Проверка на входы в необычное время
      const unusualTimeLogins = this.findUnusualTimeLogins(logins);
      if (unusualTimeLogins.length > 0) {
        anomalies.push({
          type: "UNUSUAL_TIME_LOGIN",
          user: user,
          count: unusualTimeLogins.length,
          severity: "MEDIUM",
          description: `User ${user} has ${unusualTimeLogins.length} logins outside business hours`,
        });
      }
    }

    return anomalies;
  }

  // Поиск подозрительной активности
  findSuspiciousActivity(events) {
    const anomalies = [];

    // Подозрительные команды
    const suspiciousCommands = this.findSuspiciousCommands(events);
    anomalies.push(...suspiciousCommands);

    // Изменения в критических файлах
    const fileChanges = this.findFileChanges(events);
    anomalies.push(...fileChanges);

    // Сетевые аномалии
    const networkAnomalies = this.findNetworkAnomalies(events);
    anomalies.push(...networkAnomalies);

    return anomalies;
  }

  // Поиск подозрительных команд
  findSuspiciousCommands(events) {
    const anomalies = [];
    const suspiciousPatterns = [
      /wget.*http/i,
      /curl.*http/i,
      /nc.*-l.*-p/i,
      /netcat.*-l.*-p/i,
      /python.*-c/i,
      /perl.*-e/i,
      /bash.*-i/i,
      /sh.*-i/i,
    ];

    for (const event of events) {
      for (const pattern of suspiciousPatterns) {
        if (pattern.test(event.message)) {
          anomalies.push({
            type: "SUSPICIOUS_COMMAND",
            event: event,
            severity: "HIGH",
            description: `Suspicious command detected: ${event.message}`,
          });
        }
      }
    }

    return anomalies;
  }

  // Поиск изменений в файлах
  findFileChanges(events) {
    const anomalies = [];
    const criticalFiles = [
      "/etc/passwd",
      "/etc/shadow",
      "/etc/group",
      "/etc/sudoers",
      "/etc/hosts",
      "/etc/resolv.conf",
    ];

    for (const event of events) {
      for (const file of criticalFiles) {
        if (event.message.includes(file)) {
          anomalies.push({
            type: "CRITICAL_FILE_CHANGE",
            event: event,
            file: file,
            severity: "HIGH",
            description: `Critical file changed: ${file}`,
          });
        }
      }
    }

    return anomalies;
  }

  // Поиск сетевых аномалий
  findNetworkAnomalies(events) {
    const anomalies = [];
    const networkEvents = events.filter(
      (e) =>
        e.service === "network" ||
        e.message.includes("network") ||
        e.message.includes("connection")
    );

    if (networkEvents.length > 0) {
      anomalies.push({
        type: "NETWORK_ANOMALY",
        count: networkEvents.length,
        severity: "MEDIUM",
        description: `Detected ${networkEvents.length} network-related events`,
      });
    }

    return anomalies;
  }

  // Генерация ID анализа
  generateAnalysisId() {
    return (
      "LINUX-LOG-ANALYSIS-" +
      Date.now() +
      "-" +
      Math.random().toString(36).substr(2, 4)
    );
  }
}

2. Process Analysis

// Система анализа процессов Linux
class LinuxProcessAnalyzer {
  constructor() {
    this.processes = new Map();
    this.parents = new Map();
    this.children = new Map();
    this.timeline = new Map();
  }

  // Анализ процессов
  analyzeProcesses(processData) {
    const analysis = {
      id: this.generateAnalysisId(),
      timeRange: processData.timeRange,
      processes: [],
      timeline: [],
      anomalies: [],
      summary: {
        totalProcesses: 0,
        suspiciousProcesses: 0,
        zombieProcesses: 0,
        orphanProcesses: 0,
      },
    };

    // Парсинг процессов
    const processes = this.parseProcesses(processData.content);
    analysis.processes = processes;

    // Создание временной шкалы
    const timeline = this.createProcessTimeline(processes);
    analysis.timeline = timeline;

    // Поиск аномалий
    const anomalies = this.findProcessAnomalies(processes);
    analysis.anomalies = anomalies;

    // Расчет сводки
    this.calculateProcessSummary(analysis);

    return analysis;
  }

  // Парсинг процессов
  parseProcesses(content) {
    const processes = [];
    const lines = content.split("\n");

    for (const line of lines) {
      if (line.trim()) {
        const process = this.parseProcessLine(line);
        if (process) {
          processes.push(process);
        }
      }
    }

    return processes;
  }

  // Парсинг строки процесса
  parseProcessLine(line) {
    // Упрощенный парсинг вывода ps aux
    const parts = line.split(/\s+/);
    if (parts.length < 11) return null;

    return {
      user: parts[0],
      pid: parseInt(parts[1]),
      ppid: parseInt(parts[2]),
      cpu: parseFloat(parts[3]),
      mem: parseFloat(parts[4]),
      vsz: parseInt(parts[5]),
      rss: parseInt(parts[6]),
      tty: parts[7],
      stat: parts[8],
      start: parts[9],
      time: parts[10],
      command: parts.slice(11).join(" "),
    };
  }

  // Создание временной шкалы процессов
  createProcessTimeline(processes) {
    const timeline = [];

    // Группировка по времени
    const timeGroups = this.groupByTime(processes, 300000); // 5 минут

    for (const [timeSlot, slotProcesses] of timeGroups) {
      timeline.push({
        time: timeSlot,
        processes: slotProcesses,
        count: slotProcesses.length,
      });
    }

    return timeline;
  }

  // Поиск аномалий процессов
  findProcessAnomalies(processes) {
    const anomalies = [];

    // Подозрительные процессы
    const suspiciousProcesses = this.findSuspiciousProcesses(processes);
    anomalies.push(...suspiciousProcesses);

    // Процессы с высоким потреблением ресурсов
    const highResourceProcesses = this.findHighResourceProcesses(processes);
    anomalies.push(...highResourceProcesses);

    // Процессы-зомби
    const zombieProcesses = this.findZombieProcesses(processes);
    anomalies.push(...zombieProcesses);

    // Процессы-сироты
    const orphanProcesses = this.findOrphanProcesses(processes);
    anomalies.push(...orphanProcesses);

    return anomalies;
  }

  // Поиск подозрительных процессов
  findSuspiciousProcesses(processes) {
    const anomalies = [];
    const suspiciousPatterns = [
      /nc.*-l.*-p/i,
      /netcat.*-l.*-p/i,
      /python.*-c/i,
      /perl.*-e/i,
      /bash.*-i/i,
      /sh.*-i/i,
      /wget.*http/i,
      /curl.*http/i,
    ];

    for (const process of processes) {
      for (const pattern of suspiciousPatterns) {
        if (pattern.test(process.command)) {
          anomalies.push({
            type: "SUSPICIOUS_PROCESS",
            process: process,
            severity: "HIGH",
            description: `Suspicious process detected: ${process.command}`,
          });
        }
      }
    }

    return anomalies;
  }

  // Поиск процессов с высоким потреблением ресурсов
  findHighResourceProcesses(processes) {
    const anomalies = [];

    for (const process of processes) {
      if (process.cpu > 80) {
        anomalies.push({
          type: "HIGH_CPU_PROCESS",
          process: process,
          severity: "MEDIUM",
          description: `High CPU usage: ${process.command} (${process.cpu}%)`,
        });
      }

      if (process.mem > 80) {
        anomalies.push({
          type: "HIGH_MEMORY_PROCESS",
          process: process,
          severity: "MEDIUM",
          description: `High memory usage: ${process.command} (${process.mem}%)`,
        });
      }
    }

    return anomalies;
  }

  // Поиск процессов-зомби
  findZombieProcesses(processes) {
    const anomalies = [];
    const zombieProcesses = processes.filter((p) => p.stat.includes("Z"));

    for (const process of zombieProcesses) {
      anomalies.push({
        type: "ZOMBIE_PROCESS",
        process: process,
        severity: "LOW",
        description: `Zombie process detected: ${process.command}`,
      });
    }

    return anomalies;
  }

  // Поиск процессов-сирот
  findOrphanProcesses(processes) {
    const anomalies = [];
    const pids = new Set(processes.map((p) => p.pid));
    const orphanProcesses = processes.filter(
      (p) => p.ppid === 1 && !pids.has(p.ppid)
    );

    for (const process of orphanProcesses) {
      anomalies.push({
        type: "ORPHAN_PROCESS",
        process: process,
        severity: "LOW",
        description: `Orphan process detected: ${process.command}`,
      });
    }

    return anomalies;
  }

  // Генерация ID анализа
  generateAnalysisId() {
    return (
      "LINUX-PROCESS-ANALYSIS-" +
      Date.now() +
      "-" +
      Math.random().toString(36).substr(2, 4)
    );
  }
}

3. File System Analysis

// Система анализа файловой системы Linux
class LinuxFileSystemAnalyzer {
  constructor() {
    this.files = new Map();
    this.directories = new Map();
    this.timeline = new Map();
    this.artifacts = new Map();
  }

  // Анализ файловой системы
  analyzeFileSystem(fsData) {
    const analysis = {
      id: this.generateAnalysisId(),
      mountPoint: fsData.mountPoint,
      timeRange: fsData.timeRange,
      files: [],
      directories: [],
      timeline: [],
      artifacts: [],
      anomalies: [],
      summary: {
        totalFiles: 0,
        totalDirectories: 0,
        suspiciousFiles: 0,
        deletedFiles: 0,
      },
    };

    // Парсинг файловой системы
    const parsedFS = this.parseFileSystem(fsData.content);
    analysis.files = parsedFS.files;
    analysis.directories = parsedFS.directories;

    // Создание временной шкалы
    const timeline = this.createTimeline(parsedFS);
    analysis.timeline = timeline;

    // Поиск артефактов
    const artifacts = this.findFileSystemArtifacts(parsedFS);
    analysis.artifacts = artifacts;

    // Поиск аномалий
    const anomalies = this.findFileSystemAnomalies(parsedFS);
    analysis.anomalies = anomalies;

    // Расчет сводки
    this.calculateFileSystemSummary(analysis);

    return analysis;
  }

  // Парсинг файловой системы
  parseFileSystem(content) {
    const files = [];
    const directories = [];
    const lines = content.split("\n");

    for (const line of lines) {
      if (line.trim()) {
        const entry = this.parseFileSystemEntry(line);
        if (entry) {
          if (entry.type === "FILE") {
            files.push(entry);
          } else if (entry.type === "DIRECTORY") {
            directories.push(entry);
          }
        }
      }
    }

    return { files, directories };
  }

  // Парсинг записи файловой системы
  parseFileSystemEntry(line) {
    // Упрощенный парсинг вывода find
    const parts = line.split(/\s+/);
    if (parts.length < 3) return null;

    const permissions = parts[0];
    const size = parseInt(parts[1]);
    const path = parts[2];

    const isDirectory = permissions.startsWith("d");
    const isFile = permissions.startsWith("-");

    if (!isDirectory && !isFile) return null;

    return {
      path: path,
      name: path.split("/").pop(),
      type: isDirectory ? "DIRECTORY" : "FILE",
      permissions: permissions,
      size: size,
      created: new Date(),
      modified: new Date(),
      accessed: new Date(),
    };
  }

  // Создание временной шкалы
  createTimeline(parsedFS) {
    const timeline = [];

    // Объединение файлов и директорий
    const allEntries = [...parsedFS.files, ...parsedFS.directories];

    // Сортировка по времени
    allEntries.sort((a, b) => a.modified - b.modified);

    // Группировка по времени
    const timeGroups = this.groupByTime(allEntries, 3600000); // 1 час

    for (const [timeSlot, entries] of timeGroups) {
      timeline.push({
        time: timeSlot,
        entries: entries,
        count: entries.length,
      });
    }

    return timeline;
  }

  // Поиск артефактов файловой системы
  findFileSystemArtifacts(parsedFS) {
    const artifacts = [];

    // Временные файлы
    const tempFiles = this.findTempFiles(parsedFS.files);
    artifacts.push(...tempFiles);

    // Системные файлы
    const systemFiles = this.findSystemFiles(parsedFS.files);
    artifacts.push(...systemFiles);

    // Пользовательские файлы
    const userFiles = this.findUserFiles(parsedFS.files);
    artifacts.push(...userFiles);

    // Сетевые файлы
    const networkFiles = this.findNetworkFiles(parsedFS.files);
    artifacts.push(...networkFiles);

    return artifacts;
  }

  // Поиск временных файлов
  findTempFiles(files) {
    const artifacts = [];
    const tempPatterns = [/\.tmp$/i, /\.temp$/i, /temp/i, /cache/i, /tmp/i];

    for (const file of files) {
      for (const pattern of tempPatterns) {
        if (pattern.test(file.name) || pattern.test(file.path)) {
          artifacts.push({
            type: "TEMP_FILE",
            file: file,
            description: `Temporary file: ${file.name}`,
          });
        }
      }
    }

    return artifacts;
  }

  // Поиск системных файлов
  findSystemFiles(files) {
    const artifacts = [];
    const systemPatterns = [/\.so$/i, /\.a$/i, /\.ko$/i, /\.bin$/i];

    for (const file of files) {
      for (const pattern of systemPatterns) {
        if (pattern.test(file.name)) {
          artifacts.push({
            type: "SYSTEM_FILE",
            file: file,
            description: `System file: ${file.name}`,
          });
        }
      }
    }

    return artifacts;
  }

  // Поиск пользовательских файлов
  findUserFiles(files) {
    const artifacts = [];
    const userPatterns = [
      /home/i,
      /Documents/i,
      /Desktop/i,
      /Downloads/i,
      /Pictures/i,
    ];

    for (const file of files) {
      for (const pattern of userPatterns) {
        if (pattern.test(file.path)) {
          artifacts.push({
            type: "USER_FILE",
            file: file,
            description: `User file: ${file.name}`,
          });
        }
      }
    }

    return artifacts;
  }

  // Поиск сетевых файлов
  findNetworkFiles(files) {
    const artifacts = [];
    const networkPatterns = [
      /\.log$/i,
      /\.pcap$/i,
      /\.cap$/i,
      /network/i,
      /net/i,
    ];

    for (const file of files) {
      for (const pattern of networkPatterns) {
        if (pattern.test(file.name) || pattern.test(file.path)) {
          artifacts.push({
            type: "NETWORK_FILE",
            file: file,
            description: `Network file: ${file.name}`,
          });
        }
      }
    }

    return artifacts;
  }

  // Генерация ID анализа
  generateAnalysisId() {
    return (
      "LINUX-FS-ANALYSIS-" +
      Date.now() +
      "-" +
      Math.random().toString(36).substr(2, 4)
    );
  }
}

Основные компоненты Linux Forensics

1. Log Analysis

  • System Logs — системные журналы
  • Auth Logs — журналы аутентификации
  • Kernel Logs — журналы ядра
  • Application Logs — журналы приложений

2. Process Analysis

  • Process Tree — дерево процессов
  • Resource Usage — использование ресурсов
  • Command Analysis — анализ команд
  • Timeline Analysis — анализ временных меток

3. File System Analysis

  • File Analysis — анализ файлов
  • Directory Analysis — анализ директорий
  • Permission Analysis — анализ разрешений
  • Artifact Analysis — анализ артефактов

Best Practices

1. Evidence Collection

  • Live Response — живой ответ
  • Memory Dump — дамп памяти
  • Disk Image — образ диска
  • Network Capture — захват сети

2. Analysis

  • Timeline Analysis — анализ временных меток
  • Correlation — корреляция данных
  • Pattern Recognition — распознавание паттернов
  • Anomaly Detection — обнаружение аномалий

3. Documentation

  • Chain of Custody — цепочка хранения
  • Analysis Notes — заметки анализа
  • Findings Report — отчет о находках
  • Legal Documentation — правовая документация

Заключение

Linux Forensics — это специализированная область цифровой криминалистики, которая требует:

  • Глубокого понимания — операционной системы Linux
  • Системного подхода — к анализу данных
  • Специализированных инструментов — для анализа
  • Правовых знаний — для обеспечения допустимости доказательств

Помните: Linux Forensics — это не разовое мероприятие, а постоянный процесс. Регулярно обновляйте инструменты, следите за новыми угрозами и адаптируйте методы анализа.


Совет: Начните с анализа системных логов, затем переходите к анализу процессов и файловой системы. Не забывайте о создании временных шкал и корреляции данных!