Читать 6 мин

Как определить первый разрыв в журнале аудита с хеш-цепочкой

Узнайте, как определить первый разрыв в журнале аудита с хеш-цепочкой, сохранить доказательства, указать смещение в байтах и определить затронутые сессии.

Как определить первый разрыв в журнале аудита с хеш-цепочкой

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

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

Разорванная связь отмечает конец доказательства, а не начало обвинений

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

Это кажется очевидным, пока в отчете об инциденте не появляется фраза: «запись 842 была изменена». Возможно, именно запись 842 впервые показала проблему, но изменить могли запись 841. Между ними могла исчезнуть запись. Ошибка хранения могла повредить один байт в любой из записей. Копирование журнала могло оборваться, оставив поврежденный хвост. Цепочка говорит только о том, что связь нельзя проверить. Она не определяет механизм.

Разделяйте следующие понятия:

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

Это не формальность. От этого зависит область проверки доступа. Проверенный префикс позволяет сказать: «Эта сессия агента выполнила одобренный вызов API до разрыва». Суффикс может дать зацепку: «Похоже, этот идентификатор сессии пытался выполнить действие SSH», но не следует выдавать ее за криптографически подтвержденный факт, если цепочка повреждена.

RFC 5848, спецификация IETF для подписанных сообщений syslog, показывает ту же практическую идею в другой конструкции. Она рассматривает последовательность сообщений и обнаружение пропущенных сообщений как свойства проверки и предупреждает, что изменение или усечение могут сделать проверку недействительной. Важно не превращать журнал аудита в формат syslog, а понимать целостность как свойство точно сериализованных данных, а не как расплывчатую уверенность, что журнал «выглядит неизмененным».

Сначала сохраните байты, а потом просите парсер объяснить их

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

В macOS создайте рабочую копию контролируемым способом и зафиксируйте ее размер и хеш до запуска любого инструмента анализа, который может изменить метаданные или содержимое. Используйте команды, соответствующие вашим процедурам работы с доказательствами. Минимальная запись ниже дает специалисту конкретную последовательность для воспроизведения:

mkdir -p case-2026-07-22
cp -p /path/to/audit-log.bin case-2026-07-22/audit-log.bin
stat -f '%z bytes  %N' case-2026-07-22/audit-log.bin
shasum -a 256 case-2026-07-22/audit-log.bin

Последняя команда выведет результат примерно такого вида:

9d5e...c41a  case-2026-07-22/audit-log.bin

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

Не открывайте оригинал в редакторе. Не запускайте форматирование. Не преобразуйте бинарный экспорт в JSON «для удобства». Не помещайте единственную копию во вложение к заявке, которое может изменить файл. Для каждого эксперимента создавайте производную копию, а полученный оригинал храните без изменений.

Здесь команды часто допускают тихую, но серьезную ошибку: называют сбой парсера «повреждением журнала», хотя парсер уже нормализовал доказательства. Он может декодировать экранированные символы, менять порядок полей, удалять неизвестные поля, заменять некорректный Unicode или считать отсутствие перевода строки несущественным. Для отображения это может быть разумно. Для цепочки, охватывающей точные байты, такие действия разрушительны.

Для Sallyport начните с sp audit verify, запустив проверку сохраненной копии audit-log или поддерживаемого источника аудита продукта. Цепочку аудита можно проверять офлайн поверх шифротекста, поэтому результат не требует доступа к хранилищу. Сохраните в материалах дела точную команду, код завершения и полный вывод. Не составляйте «аккуратное» резюме по частичному снимку терминала.

Смещение в байтах должно указывать на полученный файл

Смещение в файле, это число байтов от начала полученного файла доказательств до определенного места. Это стабильная координата для другого специалиста. Номер записи такой координатой часто не является.

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

По возможности указывайте два смещения:

  1. Смещение начала последней корректной записи.
  2. Смещение начала первой записи с несовпадением.

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

В построчном экспорте grep -b может найти известный идентификатор по позиции в байтах, но используйте это лишь как вспомогательный прием и только после проверки, что идентификатор записан буквально и встречается однозначно. Для бинарных или зашифрованных записей используйте hex-просмотрщик, который не изменяет файл. Простая команда просмотра позволяет зафиксировать байты вокруг известной позиции:

xxd -g 1 -s 104832 -l 256 case-2026-07-22/audit-log.bin

Число после -s, это смещение в байтах. Вывод начинается с шестнадцатеричных смещений, затем идут значения байтов и, когда возможно, их ASCII-представление. Сохраните этот фрагмент как артефакт анализа, но не подменяйте им полный файл.

Ясно укажите, что означает смещение. Фраза «смещение 104832» недостаточна. Напишите: «Первая запись с несовпадением начинается со смещения 104832 в байтах в файле с SHA-256 9d5e...c41a, отсчет ведется от нулевого байта полученного файла». Если в журнале есть заголовок контейнера, скажите, включен ли он в смещение. Он должен быть включен, поскольку другой специалист будет открывать полученный файл, а не внутренний поток записей вашего парсера.

Частая ошибка в отчетах, указать смещение после распаковки. Оно может помочь разработчику воспроизвести проблему парсера, но не указывает место в файле доказательств. Указывайте оба значения только с ясными пометками: одно относится к необработанным доказательствам, второе, к производной копии для анализа.

Проверяйте записи по порядку и прекращайте доверие на границе разрыва

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

Не просматривайте файл до конца в поисках более позднего несовпадения, которое выглядит серьезнее. Объем доказанного определяется самой ранней ошибкой. Более поздние ошибки могут быть ее следствием, независимыми дефектами или результатом того, что парсер потерял синхронизацию.

Полезный формат вывода выглядит так, даже если ваш проверяющий использует другие имена полей:

verification_status: failed
last_valid_record: 841
last_valid_offset: 104576
first_mismatch_record: 842
first_mismatch_offset: 104832
failure_kind: predecessor_hash_mismatch
expected_predecessor: 6f4a...
observed_predecessor: c928...
affected_session_ids: sess-17, sess-21, sess-24

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

Точно классифицируйте ошибку. Эти случаи имеют разные последствия:

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

Не сводите все пять случаев к слову «изменение». Несовпадение ссылки в полной записи отличается от потери питания во время добавления. Поврежденная запись может появиться из-за повреждения при передаче. Данные о пропущенной последовательности могут доказать отсутствие записей, даже если все оставшиеся записи правильно хешируются.

NIST Special Publication 800-92 рассматривает управление журналами не только как хранение: организациям нужно настраивать источники, анализировать журналы, реагировать на события, хранить данные и проверять сам процесс управления журналами. Это правильная операционная рамка для сбоя цепочки. Проверяющий показывает, где заканчивается подлинность. Чтобы понять причину, нужно изучить сбор данных, хранение, конечные точки и записи о реагировании.

Сессия может пересекать границу, даже если в ней не появляется запись на самой границе

Отследите сессии по обе стороны границы
Sallyport строит журналы Sessions и Activity из одного зашифрованного журнала с хеш-цепочкой.

Затронутые сессии, это не только идентификаторы, напечатанные в первой плохой записи. Сессия может начаться в проверенном префиксе, выполнить действия после разрыва и больше не повторить свой идентификатор в поврежденной части. Другая сессия может впервые появиться в неподтвержденном суффиксе, но иметь связанный процесс, одобрение или использование учетных данных, видимые до границы.

Формируйте область сессий по записям по обе стороны разрыва. Для каждой сессии укажите ее связь с границей:

Класс сессииКартина доказательствКак отражать в отчете
Полностью подтвержденаНачало, действия и завершение находятся до разрываИстория, подтвержденная цепочкой, остается целостной
Пересекает границуДанные о сессии есть до и после разрываРанние действия подтверждены, поздние не подтверждены
Впервые видна на границеПервое появление приходится на запись с несовпадениемВся наблюдаемая история сессии считается неподтвержденной
Только в суффиксеВсе наблюдаемые записи находятся после разрываЭто зацепка для расследования, а не подтвержденная история
Возможно пропущенаВнешние данные ссылаются на сессию, отсутствующую в цепочкеИсследуйте это как пробел, а не как обычную сессию суффикса

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

Практический лист помогает сделать рассуждение проверяемым:

Boundary: valid record 841 at offset 104576
          mismatch record 842 at offset 104832

Session sess-17
  first observed: record 809, verified
  last verified action: record 838
  later references: records 842-850, unverified
  classification: crossing

Session sess-21
  first observed: record 842, unverified
  supporting evidence: endpoint process journal reference
  classification: first seen at boundary

В листе нужно указывать источник доказательств для каждого вывода. Подтверждением может быть журнал сессии, запись процесса на конечной точке, событие приложения, квитанция удаленного API или журнал SSH-сервера. Недостаточно написать, что сессия «вероятно была активна». Следователю нужно понимать, основан ли вывод на цепочке, другом журнале или заявлении оператора.

Sallyport хранит запуски агентов в журнале Sessions, а отдельные вызовы, в журнале Activity. Оба представления строятся из одного зашифрованного журнала аудита с хеш-цепочкой. Поэтому граница цепочки важна для обоих представлений, но удобное отображение журнала не заменяет результат проверки. Используйте журналы, чтобы найти сессии и вызовы для изучения, а затем указывайте статус цепочки для каждого утверждения.

Для последней полной записи нужно принять отдельное решение

Проверьте первый разрыв цепочки
Запустите sp audit verify офлайн поверх шифротекста, не открывая хранилище.

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

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

Сообщите один из следующих результатов, а не расплывчатую комбинацию:

  • «Последняя полная запись проходит проверку; файл заканчивается 73 байтами, которые не образуют полную запись».
  • «Последняя полная запись начинается со смещения 104832 и не проходит проверку ссылки на предыдущую запись».
  • «Последняя запись объявляет 512 байт, но остается только 301 байт; вычислить хеш содержимого невозможно».

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

Не восстанавливайте усеченную запись по памяти, другой выгрузке или похожей записи. Для устранения неполадок можно создать реконструированную производную копию, но она не является полученными доказательствами. В материалах дела укажите имя реконструкции, способ ее создания и исходные байты.

Корректная последняя запись тоже не доказывает полноту файла. Цепочка может идеально проверяться после удаления целого конечного сегмента, если конструкция не предусматривает внешнюю контрольную точку, подписанный корень, ожидаемое число записей или доверенную запись о хранении. Хеш-цепочка обнаруживает изменения внутри проверяемой последовательности. Для полноты нужен внешний якорь.

Сравните независимые копии, прежде чем называть это изменением

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

Полезно сравнить локальное хранилище приложения, архив экспорта, резервный снимок, копию сборщика, снимки файловой системы и записи систем, получивших действие из журнала. Для каждой копии отдельно зафиксируйте хеш и сведения о получении. Никогда не перезаписывайте одну копию другой только потому, что они «должны совпадать».

Используйте такую схему решений:

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

Популярная, но неправильная рекомендация, «просто восстановить журнал из резервной копии и повторить проверку». Восстановленная копия может показать, что содержалось в другом сохраненном экземпляре. Она не исправит исходные доказательства и не объяснит, изменился ли активный файл, исчез ли он или был неправильно получен. Сохраните обе копии. Разница между ними часто и есть инцидент.

Внешние журналы действий помогают сузить область. Если агент вызвал HTTP API, идентификаторы запросов, записи аудита на стороне поставщика и изменения ресурсов могут показать, произошло ли действие. При использовании SSH могут помочь записи аутентификации и команд на удаленном сервере. Эти данные не возвращают криптографическое доверие поврежденному суффиксу, но могут независимо подтвердить факты и показать сессии, требующие блокировки.

Напишите отчет так, чтобы другой специалист мог воспроизвести проверку

Определите затронутые запуски агентов
Используйте журнал Sessions, чтобы найти запуски агентов, затронутые границей аудита.

Хороший отчет содержит узкое утверждение и достаточно деталей для его проверки. Он не прячет неопределенность за широкими формулировками вроде «целостность аудита нарушена».

Используйте следующий каркас:

Artifact
  Evidence file: audit-log.bin
  SHA-256: <full digest>
  Size: <bytes>
  Source and acquisition reference: <case record>

Verification
  Tool and version: <verifier>
  Command: <exact command>
  Result: failed
  Last valid record: <stable ID and ordinal>
  Last valid record offset: <raw byte offset>
  First mismatch record: <stable ID and ordinal>
  First mismatch offset: <raw byte offset>
  Failure classification: <specific classification>

Scope
  Verified sessions: <identifiers>
  Crossing sessions: <identifiers>
  First seen at boundary: <identifiers>
  Suffix-only sessions: <identifiers>
  Related external evidence: <sources and references>

Limits
  The hash chain verifies the prefix through <record>.
  The chain does not establish the cause of the mismatch.
  Records after <offset> require independent corroboration.

Actions taken
  Evidence preserved: <references>
  Access or session revocations: <references>
  Copies compared: <references>
  Follow-up owner and deadline: <names or case roles>

Не называйте последнюю корректную запись «последним безопасным действием». Это означает лишь, что цепочка может подтвердить последовательность записей до этой точки. Само действие все еще могло быть вредным, несанкционированным по отдельной процедуре одобрения или позднее отмененным. Так же не называйте неподтвержденный суффикс фиктивным. Он может быть полностью точным. Просто эта цепочка больше не доказывает его подлинность.

Первое действие после устойчивого сбоя, это соразмерная затронутым сессиям и учетным данным блокировка, а не спор о формулировках. Сохраните доказательства, при необходимости отзовите активные сессии, пересекающие границу, смените раскрытые учетные данные по процедуре реагирования и сравните независимые записи. Затем опишите границу с такой точностью, чтобы следующий специалист мог проверить вашу работу, не полагаясь на память.

Вопросы и ответы

Показывает ли первое несовпадение хешей, какую запись изменил злоумышленник?

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

Чем отличаются последняя корректная запись и первое несовпадение?

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

Зачем включать смещение в файле в отчет об инциденте с журналом аудита?

Используйте смещение в байтах в неизменяемой копии доказательств, отсчитывая его от нулевого байта. Если журнал состоит из строк, укажите также номер строки, но не заменяйте им смещение. Смещение позволяет другому специалисту изучить те же байты, даже если парсеры работают по-разному.

Может ли хеш-цепочка доказать, что кто-то изменил журнал?

Нет. Хеш-цепочка обнаруживает несоответствие проверяемой последовательности ожидаемой, но не показывает, кто внес изменение и было ли оно злонамеренным. Сравните другую копию, данные файловой системы, журналы приложения и активность конечной точки, прежде чем делать такой вывод.

Непригодны ли записи после разрыва хеш-цепочки?

Считайте каждую запись после первой неудачной связи неподтвержденной, если только независимая контрольная точка или отдельно аутентифицированный сегмент не доказывает обратное. Такие записи могут быть полезными зацепками, но не имеют той же доказательной силы, что проверенный префикс.

Что делать с файлом журнала, который заканчивается посреди записи?

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

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

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

Как определить, какие сессии агентов затронуты поврежденным журналом?

Определяйте затронутые сессии по записям, а не только по временным меткам. Учитывайте сессии, которые начались до разрыва и продолжились в неподтвержденной области, сессии, впервые появившиеся в месте несовпадения, и сессии, чье последнее действие пришлось на период после разрыва. Сессия может пересекать границу, даже если ее идентификатор встречается лишь один раз в начале.

Доказывает ли успешная проверка аудита полноту журнала?

Чистый результат означает, что проверяющий не нашел несоответствий в переданных ему байтах согласно своим правилам проверки. Это не доказывает полноту файла, отсутствие замены более раннего сегмента целиком или получение копии с ожидаемой машины. Сопоставляйте результат с данными о происхождении и хранении доказательств.

Что записать, если проверяющий аудита сообщает об ошибке?

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

Sallyport

Sallyport выполняет API-вызовы и SSH-команды за вашего ИИ-агента. Ключи остаются в локальном хранилище на вашем Mac; вы подтверждаете каждый запуск, и каждое действие попадает в запечатанный журнал.

© 2026 Sallyport · Открытый код по лицензии Apache-2.0 · Oleg Sotnikov