CIS Controls

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

CIS Controls - Критические контроли безопасности

Что такое CIS Controls?

CIS Controls (Center for Internet Security Controls) — это набор из 18 критических контролей безопасности, разработанный для защиты организаций от наиболее распространенных киберугроз. Основан на анализе реальных атак и лучших практиках.

Ключевые особенности

  • 18 контролей в 3 группах (Basic, Foundational, Organizational)
  • Приоритизированный подход к внедрению
  • Практические рекомендации
  • Регулярное обновление

Группы контролей

Basic Controls (1-6) - Базовые контроли

Критически важные контроли для всех организаций

Foundational Controls (7-16) - Основные контроли

Контроли для построения надежной защиты

Organizational Controls (17-18) - Организационные контроли

Контроли для управления и мониторинга

Детальное описание контролей

Control 1: Inventory and Control of Enterprise Assets

Инвентаризация и контроль корпоративных активов

Цель

Активно управлять (отслеживать, исправлять и контролировать) всеми корпоративными активами (конечные точки, серверы, включая облачные серверы, и маршрутизаторы), подключенными к инфраструктуре, чтобы знать, что нужно защищать.

Ключевые подконтроли

  • 1.1 — Установить активное управление активами
  • 1.2 — Использовать пассивное управление активами
  • 1.3 — Использовать DHCP для автоматического назначения IP-адресов
  • 1.4 — Поддерживать точную инвентаризацию активов

Примеры реализации

// Система инвентаризации активов для CIS Control 1
class AssetInventorySystem {
  constructor() {
    this.assets = new Map();
    this.scanners = [];
    this.lastScan = null;
  }

  // Активное сканирование активов
  async performActiveScan(networkRange) {
    const results = [];

    for (const ip of this.generateIPRange(networkRange)) {
      try {
        const asset = await this.scanAsset(ip);
        if (asset) {
          results.push(asset);
          this.assets.set(asset.ip, asset);
        }
      } catch (error) {
        console.log(`Failed to scan ${ip}: ${error.message}`);
      }
    }

    this.lastScan = new Date();
    return results;
  }

  // Сканирование отдельного актива
  async scanAsset(ip) {
    const asset = {
      ip: ip,
      hostname: null,
      os: null,
      services: [],
      lastSeen: new Date(),
      status: "unknown",
    };

    // Попытка получить hostname
    try {
      asset.hostname = await this.getHostname(ip);
    } catch (error) {
      // Hostname не найден
    }

    // Сканирование портов
    asset.services = await this.scanPorts(ip);

    // Определение ОС
    asset.os = await this.detectOS(ip);

    // Определение статуса
    asset.status = this.determineStatus(asset);

    return asset;
  }

  // Генерация диапазона IP-адресов
  generateIPRange(cidr) {
    const [network, prefix] = cidr.split("/");
    const prefixLength = parseInt(prefix);
    const hostBits = 32 - prefixLength;
    const hostCount = Math.pow(2, hostBits) - 2; // Исключаем сеть и broadcast

    const ips = [];
    const [a, b, c, d] = network.split(".").map(Number);

    for (let i = 1; i <= hostCount; i++) {
      const ip = this.intToIP((a << 24) | (b << 16) | (c << 8) | d | i);
      ips.push(ip);
    }

    return ips;
  }

  // Преобразование числа в IP-адрес
  intToIP(int) {
    return [
      (int >>> 24) & 0xff,
      (int >>> 16) & 0xff,
      (int >>> 8) & 0xff,
      int & 0xff,
    ].join(".");
  }

  // Получение hostname
  async getHostname(ip) {
    return new Promise((resolve, reject) => {
      const { exec } = require("child_process");
      exec(`nslookup ${ip}`, (error, stdout, stderr) => {
        if (error) {
          reject(error);
          return;
        }

        const lines = stdout.split("\n");
        for (const line of lines) {
          if (line.includes("name =")) {
            const hostname = line.split("name =")[1].trim().replace(".", ");
            resolve(hostname);
            return;
          }
        }

        reject(new Error("Hostname not found"));
      });
    });
  }

  // Сканирование портов
  async scanPorts(ip) {
    const commonPorts = [
      22, 23, 25, 53, 80, 110, 143, 443, 993, 995, 3389, 5432, 3306,
    ];
    const openPorts = [];

    for (const port of commonPorts) {
      if (await this.isPortOpen(ip, port)) {
        openPorts.push({
          port: port,
          service: this.getServiceName(port),
          status: "open",
        });
      }
    }

    return openPorts;
  }

  // Проверка открытости порта
  async isPortOpen(ip, port) {
    return new Promise((resolve) => {
      const net = require("net");
      const socket = new net.Socket();

      socket.setTimeout(1000);

      socket.on("connect", () => {
        socket.destroy();
        resolve(true);
      });

      socket.on("timeout", () => {
        socket.destroy();
        resolve(false);
      });

      socket.on("error", () => {
        resolve(false);
      });

      socket.connect(port, ip);
    });
  }

  // Получение имени сервиса по порту
  getServiceName(port) {
    const services = {
      22: "SSH",
      23: "Telnet",
      25: "SMTP",
      53: "DNS",
      80: "HTTP",
      110: "POP3",
      143: "IMAP",
      443: "HTTPS",
      993: "IMAPS",
      995: "POP3S",
      3389: "RDP",
      5432: "PostgreSQL",
      3306: "MySQL",
    };

    return services[port] || "Unknown";
  }

  // Определение ОС
  async detectOS(ip) {
    // Упрощенное определение ОС по открытым портам
    const services = await this.scanPorts(ip);
    const openPorts = services.map((s) => s.port);

    if (openPorts.includes(3389)) {
      return "Windows";
    } else if (openPorts.includes(22)) {
      return "Linux/Unix";
    } else {
      return "Unknown";
    }
  }

  // Определение статуса актива
  determineStatus(asset) {
    if (asset.services.length === 0) {
      return "offline";
    } else if (asset.services.some((s) => s.port === 22 || s.port === 3389)) {
      return "managed";
    } else {
      return "unmanaged";
    }
  }

  // Получение отчета об активах
  getAssetReport() {
    const report = {
      totalAssets: this.assets.size,
      managedAssets: 0,
      unmanagedAssets: 0,
      offlineAssets: 0,
      lastScan: this.lastScan,
      assets: [],
    };

    for (const [ip, asset] of this.assets) {
      report.assets.push(asset);

      switch (asset.status) {
        case "managed":
          report.managedAssets++;
          break;
        case "unmanaged":
          report.unmanagedAssets++;
          break;
        case "offline":
          report.offlineAssets++;
          break;
      }
    }

    return report;
  }
}

Control 2: Inventory and Control of Software Assets

Инвентаризация и контроль программных активов

Цель

Активно управлять (отслеживать, исправлять и контролировать) всеми программными активами на корпоративной сети, чтобы знать, что нужно защищать.

Ключевые подконтроли

  • 2.1 — Установить активное управление программными активами
  • 2.2 — Использовать пассивное управление программными активами
  • 2.3 — Установить политику разрешенного программного обеспечения
  • 2.4 — Использовать программное обеспечение только из доверенных источников

Примеры реализации

// Система управления программными активами для CIS Control 2
class SoftwareAssetManagement {
  constructor() {
    this.software = new Map();
    this.allowedSoftware = new Set();
    this.blockedSoftware = new Set();
    this.trustedSources = new Set();
  }

  // Сканирование установленного ПО
  async scanInstalledSoftware() {
    const software = [];

    // Сканирование Windows (через WMI)
    if (process.platform === "win32") {
      software.push(...(await this.scanWindowsSoftware()));
    }

    // Сканирование Linux (через dpkg/rpm)
    if (process.platform === "linux") {
      software.push(...(await this.scanLinuxSoftware()));
    }

    // Сканирование macOS (через system_profiler)
    if (process.platform === "darwin") {
      software.push(...(await this.scanMacOSSoftware()));
    }

    return software;
  }

  // Сканирование ПО в Windows
  async scanWindowsSoftware() {
    return new Promise((resolve, reject) => {
      const { exec } = require("child_process");
      const command =
        "wmic product get name,version,vendor,installdate /format:csv";

      exec(command, (error, stdout, stderr) => {
        if (error) {
          reject(error);
          return;
        }

        const lines = stdout.split("\n");
        const software = [];

        for (const line of lines) {
          if (line.includes(",")) {
            const parts = line.split(",");
            if (parts.length >= 4) {
              software.push({
                name: parts[1]?.trim(),
                version: parts[2]?.trim(),
                vendor: parts[3]?.trim(),
                installDate: parts[4]?.trim(),
                platform: "Windows",
              });
            }
          }
        }

        resolve(software);
      });
    });
  }

  // Сканирование ПО в Linux
  async scanLinuxSoftware() {
    return new Promise((resolve, reject) => {
      const { exec } = require("child_process");

      // Попытка использовать dpkg (Debian/Ubuntu)
      exec("dpkg -l", (error, stdout, stderr) => {
        if (!error) {
          const software = this.parseDpkgOutput(stdout);
          resolve(software);
          return;
        }

        // Попытка использовать rpm (Red Hat/CentOS)
        exec("rpm -qa", (error, stdout, stderr) => {
          if (!error) {
            const software = this.parseRpmOutput(stdout);
            resolve(software);
            return;
          }

          reject(new Error("No package manager found"));
        });
      });
    });
  }

  // Парсинг вывода dpkg
  parseDpkgOutput(output) {
    const lines = output.split("\n");
    const software = [];

    for (const line of lines) {
      if (line.startsWith("ii")) {
        const parts = line.split(/\s+/);
        if (parts.length >= 3) {
          software.push({
            name: parts[1],
            version: parts[2],
            vendor: "Unknown",
            installDate: "Unknown",
            platform: "Linux",
          });
        }
      }
    }

    return software;
  }

  // Парсинг вывода rpm
  parseRpmOutput(output) {
    const lines = output.split("\n");
    const software = [];

    for (const line of lines) {
      if (line.includes("-")) {
        const lastDash = line.lastIndexOf("-");
        const name = line.substring(0, lastDash);
        const version = line.substring(lastDash + 1);

        software.push({
          name: name,
          version: version,
          vendor: "Unknown",
          installDate: "Unknown",
          platform: "Linux",
        });
      }
    }

    return software;
  }

  // Сканирование ПО в macOS
  async scanMacOSSoftware() {
    return new Promise((resolve, reject) => {
      const { exec } = require("child_process");
      const command = "system_profiler SPApplicationsDataType -json";

      exec(command, (error, stdout, stderr) => {
        if (error) {
          reject(error);
          return;
        }

        try {
          const data = JSON.parse(stdout);
          const software = [];

          if (data.SPApplicationsDataType) {
            for (const app of data.SPApplicationsDataType) {
              software.push({
                name: app._name,
                version: app.version,
                vendor: app.obtained_from,
                installDate: app.lastModified,
                platform: "macOS",
              });
            }
          }

          resolve(software);
        } catch (parseError) {
          reject(parseError);
        }
      });
    });
  }

  // Проверка соответствия ПО политике
  checkSoftwareCompliance(software) {
    const violations = [];

    for (const app of software) {
      // Проверка на заблокированное ПО
      if (this.isBlockedSoftware(app.name)) {
        violations.push({
          type: "blocked_software",
          software: app.name,
          severity: "HIGH",
          description: `Blocked software detected: ${app.name}`,
        });
      }

      // Проверка на неразрешенное ПО
      if (
        !this.isAllowedSoftware(app.name) &&
        !this.isSystemSoftware(app.name)
      ) {
        violations.push({
          type: "unauthorized_software",
          software: app.name,
          severity: "MEDIUM",
          description: `Unauthorized software detected: ${app.name}`,
        });
      }

      // Проверка на устаревшие версии
      if (this.isOutdatedSoftware(app)) {
        violations.push({
          type: "outdated_software",
          software: app.name,
          version: app.version,
          severity: "MEDIUM",
          description: `Outdated software detected: ${app.name} ${app.version}`,
        });
      }
    }

    return violations;
  }

  // Проверка на заблокированное ПО
  isBlockedSoftware(name) {
    return this.blockedSoftware.has(name.toLowerCase());
  }

  // Проверка на разрешенное ПО
  isAllowedSoftware(name) {
    return this.allowedSoftware.has(name.toLowerCase());
  }

  // Проверка на системное ПО
  isSystemSoftware(name) {
    const systemSoftware = [
      "microsoft visual c++",
      "microsoft .net",
      "windows update",
      "intel",
      "amd",
      "nvidia",
      "realtek",
      "broadcom",
    ];

    return systemSoftware.some((sys) => name.toLowerCase().includes(sys));
  }

  // Проверка на устаревшее ПО
  isOutdatedSoftware(software) {
    // Упрощенная проверка на устаревшие версии
    const outdatedPatterns = [
      /java.*[0-7]\./i,
      /flash.*[0-9]\./i,
      /adobe.*[0-9]\./i,
    ];

    return outdatedPatterns.some((pattern) =>
      pattern.test(software.name + " " + software.version)
    );
  }

  // Добавление ПО в список разрешенных
  addAllowedSoftware(name) {
    this.allowedSoftware.add(name.toLowerCase());
  }

  // Добавление ПО в список заблокированных
  addBlockedSoftware(name) {
    this.blockedSoftware.add(name.toLowerCase());
  }

  // Получение отчета о ПО
  getSoftwareReport() {
    return {
      totalSoftware: this.software.size,
      allowedSoftware: this.allowedSoftware.size,
      blockedSoftware: this.blockedSoftware.size,
      violations: this.checkSoftwareCompliance(
        Array.from(this.software.values())
      ),
      lastScan: new Date(),
    };
  }
}

Control 3: Data Protection

Защита данных

Цель

Разработать процессы и технические меры для идентификации, классификации, обработки и защиты данных.

Ключевые подконтроли

  • 3.1 — Установить процессы и технические меры для идентификации и классификации данных
  • 3.2 — Установить процессы и технические меры для обработки данных
  • 3.3 — Установить процессы и технические меры для защиты данных
  • 3.4 — Установить процессы и технические меры для удаления данных

Примеры реализации

// Система защиты данных для CIS Control 3
class DataProtectionSystem {
  constructor() {
    this.dataClassification = new Map();
    this.encryptionKeys = new Map();
    this.dataRetention = new Map();
  }

  // Классификация данных
  classifyData(data, metadata = {}) {
    const classification = {
      level: "PUBLIC", // PUBLIC, INTERNAL, CONFIDENTIAL, RESTRICTED
      category: "GENERAL",
      sensitivity: "LOW",
      retention: 365, // дни
      encryption: false,
      access: "ALL",
    };

    // Автоматическая классификация на основе содержимого
    if (this.containsPII(data)) {
      classification.level = "RESTRICTED";
      classification.sensitivity = "HIGH";
      classification.encryption = true;
      classification.access = "AUTHORIZED";
      classification.retention = 2555; // 7 лет для PII
    }

    if (this.containsFinancialData(data)) {
      classification.level = "CONFIDENTIAL";
      classification.sensitivity = "HIGH";
      classification.encryption = true;
      classification.access = "FINANCE";
      classification.retention = 2555; // 7 лет для финансовых данных
    }

    if (this.containsHealthData(data)) {
      classification.level = "RESTRICTED";
      classification.sensitivity = "CRITICAL";
      classification.encryption = true;
      classification.access = "HEALTHCARE";
      classification.retention = 2555; // 7 лет для медицинских данных
    }

    // Применение метаданных
    if (metadata.classification) {
      classification.level = metadata.classification;
    }

    if (metadata.retention) {
      classification.retention = metadata.retention;
    }

    return classification;
  }

  // Проверка на PII
  containsPII(data) {
    const piiPatterns = [
      /\b\d{3}-\d{2}-\d{4}\b/, // SSN
      /\b\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b/, // Credit card
      /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/, // Email
      /\b\d{3}-\d{3}-\d{4}\b/, // Phone
      /\b[A-Za-z]+\s[A-Za-z]+\s[A-Za-z]+\b/, // Full name
    ];

    return piiPatterns.some((pattern) => pattern.test(data));
  }

  // Проверка на финансовые данные
  containsFinancialData(data) {
    const financialPatterns = [
      /\$[\d,]+\.?\d*/, // Currency
      /\b\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b/, // Credit card
      /\b\d{3}-\d{2}-\d{4}\b/, // SSN
      /\b(account|balance|transaction|payment|invoice)\b/i,
    ];

    return financialPatterns.some((pattern) => pattern.test(data));
  }

  // Проверка на медицинские данные
  containsHealthData(data) {
    const healthPatterns = [
      /\b(patient|medical|health|diagnosis|treatment|prescription)\b/i,
      /\b\d{3}-\d{2}-\d{4}\b/, // SSN
      /\b[A-Za-z]+\s[A-Za-z]+\s[A-Za-z]+\b/, // Full name
    ];

    return healthPatterns.some((pattern) => pattern.test(data));
  }

  // Шифрование данных
  async encryptData(data, classification) {
    if (!classification.encryption) {
      return data;
    }

    const crypto = require("crypto");
    const algorithm = "aes-256-gcm";
    const key = await this.getEncryptionKey(classification.level);

    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipher(algorithm, key);
    cipher.setAAD(Buffer.from(classification.level));

    let encrypted = cipher.update(data, "utf8", "hex");
    encrypted += cipher.final("hex");

    const authTag = cipher.getAuthTag();

    return {
      encrypted: encrypted,
      iv: iv.toString("hex"),
      authTag: authTag.toString("hex"),
      algorithm: algorithm,
      classification: classification.level,
    };
  }

  // Расшифровка данных
  async decryptData(encryptedData, classification) {
    if (!classification.encryption) {
      return encryptedData;
    }

    const crypto = require("crypto");
    const algorithm = encryptedData.algorithm;
    const key = await this.getEncryptionKey(classification.level);

    const decipher = crypto.createDecipher(algorithm, key);
    decipher.setAAD(Buffer.from(classification.level));
    decipher.setAuthTag(Buffer.from(encryptedData.authTag, "hex"));

    let decrypted = decipher.update(encryptedData.encrypted, "hex", "utf8");
    decrypted += decipher.final("utf8");

    return decrypted;
  }

  // Получение ключа шифрования
  async getEncryptionKey(classificationLevel) {
    if (!this.encryptionKeys.has(classificationLevel)) {
      const crypto = require("crypto");
      const key = crypto.randomBytes(32);
      this.encryptionKeys.set(classificationLevel, key);
    }

    return this.encryptionKeys.get(classificationLevel);
  }

  // Установка политики хранения данных
  setDataRetentionPolicy(classificationLevel, retentionDays) {
    this.dataRetention.set(classificationLevel, retentionDays);
  }

  // Проверка необходимости удаления данных
  shouldDeleteData(data, classification) {
    const retentionDays =
      this.dataRetention.get(classification.level) || classification.retention;
    const dataAge = (Date.now() - data.createdAt) / (1000 * 60 * 60 * 24);

    return dataAge > retentionDays;
  }

  // Безопасное удаление данных
  async secureDeleteData(data) {
    // Перезапись данных случайными байтами
    const crypto = require("crypto");
    const randomData = crypto.randomBytes(data.length);

    // В реальной системе здесь должно быть физическое удаление
    return {
      deleted: true,
      method: "secure_overwrite",
      timestamp: new Date().toISOString(),
    };
  }

  // Аудит доступа к данным
  logDataAccess(data, user, action) {
    const logEntry = {
      timestamp: new Date().toISOString(),
      dataId: data.id,
      classification: data.classification,
      user: user,
      action: action,
      ip: this.getClientIP(),
      userAgent: this.getUserAgent(),
    };

    console.log(JSON.stringify(logEntry));
  }

  // Получение IP клиента
  getClientIP() {
    // В реальной системе получать из заголовков запроса
    return "127.0.0.1";
  }

  // Получение User Agent
  getUserAgent() {
    // В реальной системе получать из заголовков запроса
    return "DataProtectionSystem/1.0";
  }
}

Внедрение CIS Controls

Этап 1: Планирование

  1. Оценка текущего состояния — аудит существующих контролей
  2. Определение приоритетов — выбор контролей для внедрения
  3. Планирование ресурсов — бюджет, персонал, время
  4. Создание команды — назначение ответственных

Этап 2: Внедрение Basic Controls

  1. Control 1 — Инвентаризация активов
  2. Control 2 — Инвентаризация ПО
  3. Control 3 — Защита данных
  4. Control 4 — Управление уязвимостями
  5. Control 5 — Управление привилегированными аккаунтами
  6. Control 6 — Конфигурация безопасности

Этап 3: Внедрение Foundational Controls

  1. Control 7 — Управление электронной почтой и веб-браузерами
  2. Control 8 — Резервное копирование
  3. Control 9 — Управление конфигурацией
  4. Control 10 — Управление данными
  5. Control 11 — Управление доступом
  6. Control 12 — Управление сетевыми инфраструктурами
  7. Control 13 — Мониторинг и анализ
  8. Control 14 — Управление пользователями
  9. Control 15 — Управление привилегированными аккаунтами
  10. Control 16 — Управление активами

Этап 4: Внедрение Organizational Controls

  1. Control 17 — Управление инцидентами
  2. Control 18 — Управление рисками

Мониторинг и измерение

Ключевые метрики

  • Покрытие контролей — процент внедренных контролей
  • Время внедрения — скорость реализации
  • Эффективность — снижение инцидентов
  • Соответствие — соответствие требованиям

Инструменты мониторинга

  • CIS Controls Self-Assessment Tool (CSAT)
  • CIS Controls Implementation Guide
  • CIS Controls Metrics Guide
  • CIS Controls Community Profiles

Заключение

CIS Controls — это практический подход к обеспечению кибербезопасности, основанный на реальном опыте и лучших практиках. Внедрение контролей:

  • Снижает риски киберугроз
  • Улучшает общую безопасность
  • Повышает соответствие требованиям
  • Обеспечивает системный подход

Помните: CIS Controls — это не разовое мероприятие, а постоянный процесс улучшения безопасности. Успех зависит от правильного планирования, поэтапного внедрения и непрерывного мониторинга.


Совет: Начните с Basic Controls (1-6), так как они обеспечивают фундаментальную защиту. Не пытайтесь внедрить все контроли сразу — это может привести к хаосу в организации.