MAATRIX / Блог / Данные подменяли месяц: как найти последнюю чистую копию

Данные подменяли месяц: как найти последнюю чистую копию

MAATRIX

Шифровальщик — это заметно: файлы переименованы, на рабочем столе записка с требованием выкупа, сервис лёг. С тихой подменой данных всё наоборот — атакующий месяцами правит записи в базе, подкидывает изменённые файлы, чуть смещает суммы или статусы, и ничего не падает. Обнаруживаете вы это случайно, спустя недели, а к тому моменту ваши ежедневные и еженедельные бэкапы уже переписали друг друга — искажённые данные есть везде, включая архивы. Разберём, как в такой ситуации искать последнюю действительно чистую точку и что должно быть настроено заранее, чтобы это вообще было возможно.

Почему это опаснее шифровальщика

Ransomware решает за вас: он делает повреждение мгновенным и очевидным. Вы точно знаете момент компрометации — это момент, когда файлы стали нечитаемыми, — и восстанавливаетесь на бэкап, который был снят до него. Разбор похожего явного сценария есть в статье про шифровальщика, который зашёл по RDP с коротким паролем: там вся сложность в скорости реакции, а не в поиске момента.

Тихая подмена данных устроена ровно наоборот. Атакующий, получив доступ — через украденные учётные данные, уязвимость в приложении или скомпрометированную интеграцию, — не шифрует и не удаляет, а точечно правит: меняет реквизиты получателя в платёжных записях, подкручивает остатки на складе, вставляет бэкдор в конфиг, который выглядит как обычная строка. Каждое отдельное изменение выглядит как легитимная операция пользователя или синхронизация — потому что технически ей и является, просто выполненной не тем, кем должна была.

Обнаружение здесь почти всегда отложенное: расхождение находит бухгалтер при сверке, клиент жалуется на данные, которых не вводил, или мониторинг целостности (если он вообще настроен) выдаёт алерт спустя недели после первой подмены. К моменту обнаружения ваш RPO (recovery point objective) — то, насколько старую копию нужно поднять, чтобы она была чистой, — может исчисляться неделями или месяцами, а не часами, как при ransomware. И если retention бэкапов у вас 7 или 14 дней — чистой копии в архиве может просто не быть физически.

Первый шаг: очертить период компрометации

Прежде чем откатывать что-либо, нужна рабочая гипотеза — когда всё началось. Без этого вы либо откатитесь недостаточно далеко (и восстановите уже подменённые данные), либо слишком далеко (и потеряете недели легитимных изменений без необходимости).

Источники для реконструкции таймлайна:

  • Логи аутентификации и доступа/var/log/auth.log (Debian/Ubuntu) или journalctl -u sshd, логи VPN, логи панели управления CMS/CRM. Ищите нетипичное: вход в нерабочее время, новый IP для существующей учётной записи, успешный вход после серии неудачных попыток.
  • Логи приложения и веб-сервера — запросы к административным эндпоинтам, необычные User-Agent, паттерны запросов, не похожие на действия обычного пользователя (например, одинаковый интервал между запросами — признак скрипта).
  • История изменений на уровне СУБД, если включён аудит: PostgreSQL с расширением pgaudit, MySQL с General Query Log или Audit Log Plugin, MongoDB с auditLog. Если аудит не был включён заранее — эта дверь для вас закрыта, и это стоит записать как урок на будущее.
  • Изменения в системе контроля версий, если конфиги и код лежат в git — git log --all --since="2026-07-01" -- path/to/config покажет, кто и когда трогал критичные файлы, даже если коммит был замаскирован под рутинное обновление.

Практический пример: если аномалию заметили в конце августа 2026 года, а последний доверенный аудит целостности проходил в начале месяца, разумная стартовая гипотеза — компрометация где-то между этими датами, и именно этот промежуток проверяется в первую очередь, а не весь год бэкапов подряд. Умение восстанавливать хронологию по разрозненным логам пригодится и при разборе самого факта взлома — принцип тот же, только фокус смещается с данных на точку входа.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Сверка контрольных сумм с эталонами

Для файлов (не строк в базе, а именно файлов — конфигов, статических ассетов, бинарников, дистрибутивов) контрольные суммы — самый быстрый способ найти момент изменения, если у вас есть с чем сравнивать.

Если для критичных файлов заранее считался хеш и хранился отдельно (не на том же сервере — иначе атакующий мог подменить и эталон тоже):

sha256sum /etc/nginx/nginx.conf /etc/app/config.yaml > /tmp/current.sha256
diff /tmp/current.sha256 /secure/storage/baseline.sha256

Если отдельного эталона не вели, но система была развёрнута из пакетов дистрибутива — можно свериться с контрольными суммами, которые предоставляет сам пакетный менеджер:

# Debian/Ubuntu — проверка изменённых файлов пакета
dpkg -V nginx
debsums -c

Для непрерывного контроля на будущее стоит развернуть систему мониторинга целостности файлов (FIM) — например, AIDE:

apt install aide
aideinit
# после инициализации базы — периодическая проверка
aide --check

AIDE хранит хеши файловой системы на момент инициализации и на каждой проверке показывает, что изменилось, добавилось или удалилось. Ключевой нюанс: база AIDE и её конфиг должны храниться вне проверяемого сервера (на отдельном read-only носителе или в другой системе), иначе атакующий с root-доступом просто пересчитает эталон под свежее, уже искажённое состояние — и проверка ничего не покажет.

Для данных внутри базы контрольные суммы файлов не помогут — нужны либо построчные хеши на уровне приложения (если они закладывались архитектурно), либо сверка с внешним источником истины: выгрузкой у контрагента, копией у клиента, распечаткой отчёта за нужный период, если она сохранилась вне вашей инфраструктуры.

История изменений: версионирование и аудит-логи

Если в системе есть версионирование или журналирование изменений — это самый надёжный путь найти точный момент подмены, потому что он показывает не просто «что сейчас не так», а «кто, когда и как именно изменил запись».

Для PostgreSQL — WAL-архивирование с возможностью point-in-time recovery позволяет поднять базу на состояние на любую секунду в прошлом, если WAL-файлы архивировались непрерывно и достаточно долго:

# restore_command в postgresql.conf на восстанавливаемом инстансе
restore_command = 'cp /archive/wal/%f %p'
recovery_target_time = '2026-08-14 09:00:00'

Это работает только если архивирование WAL было настроено заранее и архив не пересекается по сроку хранения с моментом компрометации — задним числом WAL не восстановить.

Для MySQL/MariaDB — аналогично работает бинарный лог (binlog) при включённом log_bin, через mysqlbinlog можно вычленить и просмотреть конкретные транзакции за период, не поднимая всю базу целиком.

На уровне приложения — если в схеме БД предусмотрены поля вроде updated_at, updated_by, или отдельная таблица аудита (audit trail), это часто самый быстрый способ: SELECT * FROM orders WHERE updated_at BETWEEN '2026-08-01' AND '2026-08-25' AND updated_by NOT IN (<список ожидаемых сервисных аккаунтов>) — такой запрос за минуты покажет подозрительные правки, если аудит вёлся честно (то есть в отдельной append-only таблице, куда у обычных ролей приложения нет прав на UPDATE/DELETE).

Если аудит-лога не было и версионирования тоже нет — единственный оставшийся путь это ручная бинарная сверка между поколениями бэкапов, которая описана в следующем разделе. Она медленнее и грубее, но работает даже без предварительной подготовки.

Постепенный откат к более старым бэкапам

Когда точной даты нет, работает стратегия бинарного поиска по цепочке бэкапов: не восстанавливать сразу самый старый архив (это может откатить на месяцы легитимных данных), а сужать диапазон шагами.

Общий алгоритм:

  1. Разверните подозреваемую копию в изолированной песочнице, не в проде — отдельный сервер или контейнер без доступа к боевой сети, чтобы случайно не перезаписать текущие данные и не дать атакующему (если у него ещё есть доступ) увидеть вашу деятельность.
  2. Прогоните на этой копии проверку целостности — тот же скрипт сверки контрольных сумм, ту же выборку по аудит-полям, тот же ручной просмотр критичных записей (балансы, реквизиты, список пользователей с правами администратора).
  3. Если копия чистая — двигайтесь к более свежей точке (например, следующему поколению бэкапа между текущей чистой и первой заведомо испорченной). Если грязная — откатывайтесь дальше в прошлое.
  4. Повторяйте, пока не найдёте границу: последний чистый снапшот и первый испорченный, между ними — окно компрометации.

Если бэкапы снимаются инструментом с поддержкой множества точек восстановления, это удобно делать без полного разворачивания каждой копии. Например, BorgBackup хранит дедуплицированные снапшоты и позволяет монтировать конкретный архив как файловую систему для быстрой сверки:

borg list /path/to/repo
borg mount /path/to/repo::2026-08-10 /mnt/check
diff -r /mnt/check/etc /etc
borg umount /mnt/check

Restic работает похожим образом через restic snapshots и restic mount.

Для баз данных «примонтировать» снапшот напрямую обычно нельзя — приходится поднимать временный инстанс СУБД из дампа или физической копии и гонять по нему проверочные запросы. Это дороже по времени, поэтому на практике комбинируют: сначала грубо сужают диапазон по датам файловых бэкапов и логам, а точную границу внутри базы находят уже прицельно, на одном-двух кандидатах, а не на всей цепочке.

Важный нюанс: если у бэкапа нет проверки целостности при создании (не только при восстановлении), сама резервная копия может быть повреждена независимо от атаки — стоит не путать битый архив со «свежей подменой». Про то, почему бэкап на том же сервере или без независимой проверки — плохая опора в кризис, есть отдельный разбор: антипаттерн — бэкап на том же сервере.

Почему длинный retention и версионирование решают всё

Всё описанное выше работает только при одном условии: чистая копия физически существует в каком-то бэкапе. Если retention — 7 или 14 дней, а компрометация длилась месяц, вы технически не сможете найти чистую точку, потому что её больше нет, даже теоретически, — она удалена по расписанию ротации.

Отсюда практический вывод для конфигурации бэкапов, актуальный именно для сценария тихой подмены, а не для быстрого сбоя диска:

Что важноЗачем именно против тихой подмены
Retention от 60-90 дней хотя бы для части копийДаёт запас на «долгое» обнаружение — большинство скрытых компрометаций находят не в первую неделю
Grandfather-Father-Son (GFS) схема ротацииХранит не только последние N дней, но и разреженные точки за месяцы — недельные и месячные архивы живут дольше ежедневных
Неизменяемость (immutable/WORM) хранилища бэкаповДаже с правами root на проде нельзя переписать или удалить уже созданную копию — это же защищает и от шифровальщика
Отдельные учётные данные для бэкап-хранилищаКомпрометация прод-сервера не даёт автоматически доступ к архиву бэкапов на удаление
Проверка целостности бэкапа сразу при созданииОтличает «бэкап битый сам по себе» от «бэкап содержит подмену»

Базовое правило распределения копий по типам и местам хранения разобрано в статье про правило 3-2-1 для бэкапов недорого — оно решает задачу физической сохранности копии. Retention и неизменяемость — следующий шаг: копия должна не просто существовать где-то ещё, а существовать достаточно долго и быть защищена от переписывания даже тем, кто уже внутри инфраструктуры.

Практически это означает: ежедневные копии можно хранить неделю-две, но хотя бы недельные снапшоты имеет смысл держать 3-6 месяцев, а месячные — год. Дисковое пространство для этого стоит недорого по сравнению с ценой отсутствия чистой точки восстановления: на VPS с NVMe-хранилищем разница между 14 и 90 днями retention для типичной базы небольшого проекта — это обычно десятки гигабайт, а не порядки величины больше.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Как понять, что это именно тихая подмена, а не баг или кривое обновление?

Первый признак — данные меняются точечно и правдоподобно (не массово и не хаотично), а изменения коррелируют с активностью конкретной учётной записи или IP, не характерной для обычного рабочего процесса. Если сомневаетесь, разбор смежного вопроса — взлом или глюк: как отличить компрометацию от кривого обновления — поможет не потратить время на то, что окажется обычной программной ошибкой.

Что делать, если чистой копии нет вообще ни в одном бэкапе?

Тогда восстановление придётся делать вручную — сверяя записи с внешними источниками (выгрузками у контрагентов, копиями у клиентов, бумажными или почтовыми подтверждениями) и восстанавливая только то, что удаётся подтвердить. Это медленно и не покрывает всё, поэтому вывод один: длинный retention нужно настроить заранее, а не после инцидента.

Нужно ли менять пароли и ключи после того, как нашли чистую точку?

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

Можно ли автоматизировать сверку контрольных сумм на будущее?

Да — FIM-системы вроде AIDE или Tripwire, запущенные по расписанию с уведомлением в отдельный канал (не на тот же сервер), ловят изменения файлов практически сразу. Для баз данных ближайший аналог — триггеры аудита или CDC (change data capture) в отдельное append-only хранилище.

Сколько по времени занимает такой разбор на практике?

Сильно зависит от объёма данных и качества логов — от нескольких часов, если аудит-лог есть и точен, до нескольких дней при ручной бинарной сверке по цепочке бэкапов без вспомогательных инструментов. Точных цифр без знания вашей инфраструктуры никто честно не назовёт — ориентируйтесь на порядок, а не на конкретное число.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →