# Como diagnosticar a primeira quebra em um log de auditoria encadeado por hashes

Um log de auditoria encadeado por hashes oferece um limite claro quando falha: há um prefixo que pode ser verificado, seguido por material que não pode ser autenticado por meio dessa cadeia. Esse limite só é útil se for relatado com precisão. Dizer que «o log de auditoria está corrompido» elimina justamente a parte mais importante para investigadores, equipes de resposta a incidentes e assessores jurídicos.

Seu relatório deve identificar o **último registro válido**, a **primeira divergência**, o deslocamento exato em bytes no arquivo adquirido e as sessões que atravessam ou seguem esse limite. Também deve separar o que a cadeia prova do que ainda precisa ser investigado. Uma ligação que falhou é evidência de inconsistência. Não é um veredito sobre a intenção.

## Uma ligação que falhou marca o fim da prova, não o início da culpa

Um registro encadeado normalmente inclui seu próprio conteúdo e uma referência ao hash do registro anterior. A verificação recalcula o valor esperado a partir dos bytes do registro e o compara com o valor que o registro declara seguir. Quando essa comparação falha, o verificador ainda pode confiar no prefixo totalmente verificado antes da falha. Ele não pode estender essa confiança através da divergência.

Isso parece óbvio até que um relatório de incidente diga: «o registro 842 foi alterado». O registro 842 pode ser o primeiro a revelar o problema, mas o registro 841 pode ter sido modificado. Um registro entre os dois pode estar ausente. Um erro de armazenamento pode ter danificado um byte em qualquer um deles. O log pode ter sido copiado de forma incompleta, deixando uma cauda danificada. A cadeia informa que não é possível verificar a relação. Ela não identifica o mecanismo.

Mantenha estes termos separados:

- **Último registro válido**: o registro completo mais recente cujo conteúdo, hash armazenado e relação com o predecessor verificam contra o prefixo confiável.
- **Primeira divergência**: o primeiro registro completo cuja referência ao predecessor ou hash calculado não verifica.
- **Limite da quebra**: o ponto entre esses dois registros, expresso por identificadores de registros e deslocamentos em bytes.
- **Sufixo não verificado**: todos os registros posteriores que dependem da sequência quebrada, a menos que outro ponto de verificação independente os autentique.

Essa distinção não é mera burocracia. Ela determina como delimitar o acesso. O prefixo verificado pode sustentar uma afirmação como: «Esta sessão de agente fez esta chamada de API aprovada antes da quebra». O sufixo pode fornecer uma pista como: «Este identificador de sessão parece ter tentado uma ação SSH», mas não deve ser apresentado como autenticado criptograficamente pela cadeia danificada.

A RFC 5848, especificação do IETF para mensagens syslog assinadas, apresenta o mesmo ponto prático em um projeto diferente. Ela trata o sequenciamento de mensagens e a detecção de mensagens ausentes como propriedades de verificação e alerta que alterações ou truncamentos podem invalidar a validação. A lição útil não é transformar um log de auditoria em formato syslog. É tratar a verificação de integridade como uma propriedade dos dados serializados exatos, e não como uma garantia vaga de que um log «parece inalterado».

## Preserve os bytes antes de pedir a um analisador que os explique

Comece pela aquisição. Um verificador perfeito não consegue salvar uma investigação que começa com um arquivo de origem sobrescrito, uma regravação feita por um editor de texto ou uma exportação compactada que alterou silenciosamente as quebras de linha.

No macOS, crie uma cópia de trabalho por um caminho controlado e registre seu tamanho e hash antes de usar qualquer ferramenta de análise que possa reescrever metadados ou conteúdo. Use comandos adequados aos seus procedimentos de evidência, mas o registro mínimo a seguir oferece ao revisor algo concreto para reproduzir:

```sh
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
```

O comando final produz uma saída neste formato:

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

Registre o hash completo, não uma versão abreviada. Registre também o caminho de origem, o horário da aquisição com fuso horário, o nome do host ou a identidade do dispositivo conforme seu processo de evidência, o operador e se o arquivo foi obtido enquanto a aplicação ainda estava gravando. Se o log estava ativo, adquira uma segunda cópia mais tarde. Duas cópias que falham em deslocamentos diferentes podem revelar uma gravação incompleta, e não uma quebra histórica estável.

Não abra o original em um editor. Não execute um formatador. Não o converta de uma exportação binária para JSON «por conveniência». Não mova a única cópia para um anexo de chamado que possa transformá-la. Crie derivados para cada experimento e preserve a cópia de aquisição sem alterações.

É aqui que as equipes costumam cometer um erro silencioso, mas grave: chamam uma falha do analisador de «corrupção do log» depois que o analisador já normalizou a evidência. Um analisador pode decodificar escapes, reordenar campos, descartar campos desconhecidos, substituir Unicode inválido ou tratar uma quebra de linha ausente como algo sem importância. Essas escolhas podem ser adequadas para exibição. Elas são destrutivas para uma cadeia que cobre bytes exatos.

Para o Sallyport, comece com `sp audit verify` sobre a cópia preservada do audit-log ou sobre a fonte de auditoria compatível do produto. A cadeia de auditoria pode ser verificada offline sobre o texto cifrado, portanto o resultado da verificação não exige acesso ao cofre. Registre no caso o comando exatamente como foi executado, seu status de saída e toda a saída. Não invente um resumo mais limpo a partir de uma captura de tela parcial do terminal.

## O deslocamento em bytes deve apontar para o arquivo adquirido

Um deslocamento no arquivo é o número de bytes desde o início do arquivo de evidência adquirido até um local definido. Ele fornece a outro investigador uma coordenada estável. Um número de registro, muitas vezes, não fornece.

Os números de registro podem mudar quando um analisador ignora entradas vazias, um coletor combina arquivos ou uma exportação descarta uma linha malformada. Os horários podem coincidir, chegar fora de ordem ou estar ausentes. Um deslocamento em bytes permite que um revisor examine os bytes exatos ao redor usando outra implementação.

Use dois deslocamentos quando possível:

1. O deslocamento onde começa o último registro válido.
2. O deslocamento onde começa o primeiro registro com divergência.

Se a divergência surgir porque um registro aponta para o valor errado do predecessor, informe o deslocamento inicial do primeiro registro divergente. Se o próprio registro estiver incompleto, informe o início do registro incompleto e o deslocamento do fim do arquivo. São casos diferentes.

Em uma exportação orientada por linhas, `grep -b` pode localizar um identificador conhecido pela posição em bytes, mas trate isso apenas como conveniência depois de confirmar que o identificador está codificado de forma literal e é único. Para registros binários ou cifrados, use um visualizador hexadecimal que não altere o arquivo. Um comando simples de inspeção pode estabelecer os bytes ao redor de uma posição conhecida:

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

O número depois de `-s` é o deslocamento em bytes. A saída começa com deslocamentos em hexadecimal, seguida pelos valores dos bytes e, quando possível, por uma representação ASCII. Preserve esse trecho como artefato de análise, mas não o use como substituto do arquivo completo.

Seja explícito sobre o significado do deslocamento. «Deslocamento 104832» é incompleto. Escreva: «O primeiro registro divergente começa no deslocamento 104832 em bytes, no arquivo com hash SHA-256 9d5e...c41a, medido a partir do byte zero do arquivo adquirido». Se o log tiver um cabeçalho de contêiner, diga se o deslocamento o inclui. Deve incluí-lo, porque outro revisor abrirá o arquivo que você adquiriu, e não o fluxo interno de registros do seu analisador.

Um erro comum no relatório é fornecer um deslocamento depois da descompactação. Isso pode ajudar um desenvolvedor a reproduzir um problema do analisador, mas não identifica uma posição no arquivo de evidência. Informe ambos somente se os rotular claramente: um é o deslocamento na evidência bruta, o outro é o deslocamento da análise derivada.

## Verifique os registros em ordem e pare de estender a confiança na quebra

Um verificador deve processar os registros na ordem em que estão armazenados, calcular o valor esperado da cadeia a partir da representação autenticada exata e compará-lo com a referência armazenada. A primeira falha é o primeiro ponto em que o verificador não consegue derivar a relação declarada a partir do prefixo verificado.

Não examine adiante para escolher uma divergência posterior porque ela parece mais dramática. A primeira falha determina o alcance da prova. Falhas posteriores podem ser consequências da primeira, defeitos independentes ou efeitos de um analisador que perdeu a sincronização.

A estrutura de saída útil é esta, mesmo que seu verificador use nomes de campos diferentes:

```text
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
```

Esses valores são um exemplo de estrutura de relatório, não uma saída que você deve inventar a partir de uma ferramenta. Seu relatório real precisa do identificador estável do registro, se houver, da posição ordinal no arquivo e do deslocamento em bytes. Se os identificadores estiverem cifrados ou indisponíveis para uma ferramenta offline, registre primeiro a posição ordinal e o deslocamento; depois use um caminho de análise autorizado para relacionar o limite às sessões.

Classifique a falha com precisão. Estes casos têm implicações diferentes:

- **Divergência do predecessor**: a referência do registro ao hash anterior não corresponde ao predecessor verificado.
- **Divergência do hash do registro**: o resumo armazenado do próprio registro não corresponde ao resumo calculado a partir dos bytes autenticados.
- **Sequência ausente**: valores explícitos de sequência ou pontos de verificação mostram que um ou mais registros estão ausentes.
- **Registro malformado**: o verificador não consegue analisar um registro completo o suficiente para calcular o valor da cadeia.
- **Cauda truncada**: o arquivo termina antes que um registro final esteja completo.

Não reduza os cinco casos a «adulteração». Uma divergência do predecessor em um registro completo é diferente de uma perda de energia durante uma gravação. Um registro malformado pode resultar de danos no transporte. Evidências de sequência ausente podem provar que há registros faltando mesmo quando todos os registros restantes têm hashes corretos.

A Publicação Especial 800-92 do NIST trata o gerenciamento de logs como algo que vai além do armazenamento: as organizações precisam configurar fontes, analisar logs, responder a eventos, reter dados e auditar a própria operação de gerenciamento de logs. Esse é o enquadramento operacional correto para uma falha de cadeia. O verificador informa onde a autenticidade termina. Ainda é preciso examinar a coleta, a retenção, os endpoints e os registros de resposta para descobrir o motivo.

## Uma sessão pode atravessar a fronteira sem aparecer nela

As sessões afetadas não são simplesmente os IDs de sessão impressos no primeiro registro ruim. Uma sessão pode começar no prefixo verificado, executar ações depois da quebra e nunca repetir seu identificador na parte danificada. Outra pode aparecer pela primeira vez no sufixo não verificado, mas ter um processo relacionado, uma aprovação ou um uso de credencial visível antes da fronteira.

Construa o escopo das sessões a partir dos registros dos dois lados da quebra. Para cada sessão, classifique sua relação com a fronteira:

| Classe da sessão | Padrão de evidência | Tratamento no relatório |
| --- | --- | --- |
| Totalmente verificada | Início, ações e fim estão antes da quebra | O histórico sustentado pela cadeia permanece íntegro |
| Que atravessa a fronteira | Há evidências da sessão antes e depois da quebra | Atividade inicial verificada, atividade posterior não verificada |
| Vista pela primeira vez na fronteira | A primeira ocorrência é o registro divergente | Trate todo o histórico observado da sessão como não verificado |
| Somente no sufixo | Todos os registros observados ocorrem depois da quebra | Use como pista de investigação, não como histórico autenticado |
| Possivelmente omitida | Evidências externas fazem referência a uma sessão ausente da cadeia | Investigue como lacuna, não como sessão normal do sufixo |

Não dependa apenas dos horários para decidir se uma sessão atravessou a fronteira. Os relógios podem divergir, os registros podem ser armazenados em buffer e o gravador do log pode descarregar dados em lotes. Use IDs de sessão, identificadores de processo quando disponíveis, identificadores de execução do agente, IDs de correlação de ações e registros explícitos de início ou fim. Se o sistema não expuser todos esses campos, declare a limitação em vez de fingir que uma janela de tempo resolve o problema.

Uma planilha prática mantém o raciocínio revisável:

```text
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
```

A planilha deve indicar a fonte de evidência para cada conclusão. «Evidência de apoio» pode ser um diário de sessão, um registro de processo do endpoint, um evento da aplicação, um recibo de API remota ou um log de servidor SSH. Não basta escrever que uma sessão «provavelmente estava ativa». Os investigadores precisam saber se a conclusão vem da cadeia, de outro log ou da declaração de um operador.

O Sallyport mantém as execuções dos agentes em um diário Sessions e as chamadas individuais em um diário Activity, ambos projetados a partir do mesmo log de auditoria cifrado e encadeado por hashes. Isso torna o limite da cadeia relevante para as duas visões, mas não permite tratar uma exibição amigável do diário como substituta da conclusão do verificador. Use os diários para identificar as sessões e chamadas que precisam de revisão e, depois, rotule o status da cadeia de cada afirmação.

## O último registro completo precisa de uma decisão própria

Um arquivo que termina abruptamente apresenta uma questão diferente de um registro que falha na verificação do predecessor. É preciso decidir se os bytes finais contêm um registro completo e inconsistente ou uma gravação incompleta que nunca formou um registro.

Comece pelo fim do arquivo e determine as regras de enquadramento dos registros para aquele formato. Um formato delimitado por linhas pode exigir uma quebra de linha, mas a ausência dela não significa automaticamente que o registro esteja incompleto. Em um formato binário prefixado por tamanho, compare o tamanho declarado com os bytes restantes. Um contêiner cifrado pode ter uma tag de enquadramento autenticada capaz de distinguir um registro completo inválido de uma gravação interrompida.

Relate uma destas conclusões, e não uma combinação vaga:

- «O último registro completo verifica corretamente; o arquivo termina com 73 bytes que não formam um registro completo.»
- «O último registro completo começa no deslocamento 104832 e falha na verificação do predecessor.»
- «O registro final declara 512 bytes, mas restam apenas 301; não foi possível calcular o hash do conteúdo.»

Essa formulação importa porque a resposta operacional é diferente. Uma cauda truncada durante uma falha pode exigir a recuperação de outra cópia, diagnósticos de armazenamento e comparação com um coletor. Um registro completo divergente exige as mesmas comparações, mas também demanda a preservação imediata do estado do endpoint e dos registros de acesso, pois o conteúdo estava presente e era inconsistente.

Não preencha um registro truncado com base na memória, em outra exportação ou em uma entrada semelhante. Você pode criar um derivado reconstruído para solucionar problemas, mas o arquivo reconstruído não é a evidência adquirida. Registre nas notas do caso o nome da reconstrução, o método e os bytes de origem.

Um registro final limpo também não prova que o arquivo está completo. Uma cadeia pode verificar perfeitamente depois da exclusão de um segmento terminal inteiro se o projeto não tiver um ponto de verificação externo, uma raiz assinada, uma contagem de sequência esperada ou um registro de retenção confiável. O encadeamento por hashes detecta alterações dentro da sequência examinada. A completude precisa de uma âncora fora dessa sequência.

## Compare cópias independentes antes de chamar isso de adulteração

A maneira mais rápida de exagerar uma quebra de cadeia é examinar uma cópia e presumir que ela seja o log canônico. Antes de acusar alguém, obtenha cópias independentes quando sua autoridade e seu processo de incidentes permitirem. 

Comparações úteis incluem um armazenamento local da aplicação, um arquivo exportado, um snapshot de backup, uma cópia do coletor, snapshots do sistema de arquivos e registros de sistemas que receberam a ação auditada. Dê a cada cópia seu próprio hash e seus próprios detalhes de aquisição. Nunca sobrescreva uma com outra porque elas «deveriam corresponder».

Use o seguinte padrão de decisão:

1. Se duas cópias adquiridas de forma independente falharem no mesmo registro e deslocamento em bytes, com bytes anteriores idênticos, o problema provavelmente já existia antes da aquisição. Isso ainda não estabelece intenção.
2. Se uma cópia verificar mais longe que outra, compare os arquivos byte a byte ao redor da primeira divergência. A cópia mais curta ou danificada pode estar incompleta.
3. Se ambas as cópias verificarem internamente, mas diferirem como arquivos completos, investigue se são segmentos legítimos separados, exportações com escopos diferentes ou evidência de substituição.
4. Se uma aquisição supostamente idêntica mudar de hash entre leituras, interrompa a análise da cadeia e investigue o meio de origem, o gravador ativo, as permissões e o processo de coleta.

A recomendação popular, mas errada, é «simplesmente restaurar o log do backup e executar a verificação novamente». Uma cópia restaurada pode ajudar a estabelecer o conteúdo de outra cópia retida. Ela não repara a evidência original nem explica se o arquivo ativo mudou, desapareceu ou foi coletado de forma inadequada. Preserve ambos. A diferença costuma ser o próprio incidente.

Logs externos de ações podem delimitar o escopo. Se um agente invocou uma API HTTP, identificadores de solicitação, entradas de auditoria do provedor e alterações nos recursos podem mostrar se a ação ocorreu. Se usou SSH, registros de autenticação e de comandos do servidor remoto podem ajudar. Esses registros não restauram a confiança criptográfica no sufixo quebrado, mas podem estabelecer fatos de forma independente e identificar sessões que exigem contenção.

## Escreva o relatório do incidente para que outro investigador possa reproduzi-lo

Um bom relatório faz uma afirmação restrita, com detalhes suficientes para testá-la. Ele não esconde a incerteza em frases amplas como «a integridade da auditoria foi comprometida».

Use este modelo de relatório:

```text
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>
```

Evite relatar o último registro válido como a «última ação segura». Isso significa apenas que a cadeia pode autenticar a sequência de registros até aquele ponto. A ação ainda pode ter sido prejudicial, não autorizada segundo um processo de aprovação separado ou posteriormente revertida. Da mesma forma, evite descrever o sufixo não verificado como falso. Ele pode estar completamente correto. Simplesmente já não é comprovado por aquela cadeia.

A primeira ação depois de uma falha estável deve ser uma contenção proporcional às sessões e credenciais afetadas, e não um debate sobre a redação. Preserve as evidências, revogue as sessões ativas que atravessam a fronteira quando o risco justificar, altere as credenciais expostas conforme seu procedimento de incidentes e compare registros independentes. Depois, escreva o limite com a precisão necessária para que o próximo investigador verifique seu trabalho sem depender da sua memória.
