# Hash-chained audit log में पहली टूटन की जाँच कैसे करें

Hash-chained audit log के विफल होने पर एक स्पष्ट सीमा मिलती है: शुरुआत का वह हिस्सा जिसे आप verify कर सकते हैं और उसके बाद की वह सामग्री जिसे chain के जरिए authenticate नहीं किया जा सकता। यह सीमा तभी उपयोगी है जब आप इसे सटीक रूप से report करें। «Audit log corrupt है» कहने से investigators, incident responders और legal counsel के लिए सबसे जरूरी जानकारी छूट जाती है।

आपकी report में **last valid record**, **first mismatch**, acquired file में exact byte offset और उस सीमा को पार करने वाले या उसके बाद आने वाले sessions की पहचान होनी चाहिए। यह भी अलग-अलग बताना चाहिए कि chain क्या साबित करती है और किन बातों की अभी जाँच बाकी है। Failed link inconsistency का evidence है, intent पर फैसला नहीं।

## Failed link proof का अंत बताता है, blame की शुरुआत नहीं

Chained record में आम तौर पर अपना content और पिछले record के hash का reference होता है। Verification record bytes से expected value फिर से निकालती है और उसे उस value से मिलाती है जिसे record पिछले record के रूप में follow करने का दावा करता है। तुलना विफल होने पर failure से पहले का पूरी तरह verified prefix भरोसेमंद रहता है। लेकिन mismatch के आगे उस भरोसे को बढ़ाया नहीं जा सकता।

यह बात तब तक स्पष्ट लगती है जब तक incident report में यह न लिखा हो, «Record 842 बदला गया था।» Record 842 वह पहला record हो सकता है जहाँ समस्या दिखाई दी, लेकिन संभव है कि record 841 बदला गया हो। दोनों के बीच कोई record गायब हो सकता है। Storage error ने किसी एक record में एक byte खराब किया हो सकता है। Log अधूरा copy हुआ हो सकता है और उसका tail damaged हो सकता है। Chain केवल इतना बताती है कि relationship verify नहीं की जा सकती। वह mechanism की पहचान नहीं करती।

इन terms को अलग रखें:

- **Last valid record**: trusted prefix के विरुद्ध content, stored hash और predecessor relationship verify होने वाला सबसे नया complete record।
- **First mismatch**: पहला complete record जिसका claimed predecessor या calculated hash verify नहीं होता।
- **Break boundary**: इन दोनों records के बीच की सीमा, जिसे record identifiers और byte offsets के रूप में लिखा जाता है।
- **Unverified suffix**: broken sequence पर निर्भर हर बाद का record, जब तक कोई दूसरा independent checkpoint उसे authenticate न करे।

यह केवल paperwork नहीं है। इससे access scope तय होता है। Verified prefix के आधार पर आप कह सकते हैं, «Break से पहले इस agent session ने यह approved API call की थी।» Suffix से आपको यह lead मिल सकती है, «इस session identifier ने SSH action करने की कोशिश की प्रतीत होती है,» लेकिन इसे damaged chain द्वारा cryptographically authenticated तथ्य की तरह प्रस्तुत नहीं करना चाहिए।

Signed syslog messages के लिए IETF specification RFC 5848 अलग design में यही practical point रखता है। वह message sequencing और missing-message detection को verification properties मानता है और चेतावनी देता है कि alteration या truncation validation को अमान्य कर सकती है। उपयोगी सीख यह है कि audit log को syslog format में ढालना नहीं, बल्कि integrity verification को exact serialized data की property मानना है। यह केवल इतना भरोसा नहीं कि log «बदला हुआ नहीं लगता»।

## Parser से समझाने को कहने से पहले bytes सुरक्षित करें

Acquisition से शुरुआत करें। Perfect verifier भी उस investigation को नहीं बचा सकता जो overwritten source file, text editor rewrite या ऐसे compressed export से शुरू हुई हो जिसने चुपचाप line endings बदल दिए हों।

macOS पर controlled path से working copy बनाएँ और किसी भी analysis tool का उपयोग करने से पहले उसका size और digest दर्ज करें, खासकर ऐसा tool जो metadata या content को rewrite कर सकता हो। अपने evidence procedures के अनुसार commands चुनें। नीचे का छोटा record reviewer को कुछ ठोस देता है जिसे दोहराया जा सकता है:

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

अंतिम command इस तरह का output देगी:

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

पूरा digest दर्ज करें, abbreviated display नहीं। Source path, timezone के साथ acquisition time, evidence process के अनुसार hostname या device identity, operator और यह भी दर्ज करें कि file उस समय ली गई थी या नहीं जब application अभी लिख रही थी। अगर log live था, तो बाद में दूसरी copy लें। अलग offsets पर विफल होने वाली दो copies incomplete write के संकेत दे सकती हैं, स्थायी historical break के नहीं।

Original को editor में न खोलें। Formatter न चलाएँ। इसे «सुविधा के लिए» binary export से JSON में convert न करें। केवल copy को ऐसे ticket attachment में न डालें जो उसे transform कर सकता हो। हर experiment के लिए derivatives बनाएँ और acquisition copy को unchanged रखें।

यहीं teams अक्सर एक गंभीर, पर शांत गलती करती हैं: parser ने evidence normalize करने के बाद parser failure को «log corruption» कह देती हैं। Parser escapes decode कर सकता है, fields का order बदल सकता है, unknown fields हटा सकता है, invalid Unicode replace कर सकता है या missing newline को harmless मान सकता है। Display के लिए ये choices ठीक हो सकती हैं। Exact bytes को cover करने वाली chain के लिए ये destructive हैं।

Sallyport में preserved audit-log copy या product के supported audit source पर `sp audit verify` से शुरुआत करें। Audit chain को ciphertext पर offline verify किया जा सकता है, इसलिए verification result के लिए vault access जरूरी नहीं। Command को ठीक उसी रूप में capture करें जैसे वह चली, उसका exit status और पूरा output case record में रखें। अधूरे terminal screenshot से साफ-सुथरा summary न गढ़ें।

## Byte offset acquired file की ओर संकेत करना चाहिए

File offset acquired evidence file की शुरुआत से किसी defined location तक bytes की संख्या है। इससे दूसरे investigator को एक stable coordinate मिलता है। Record number अक्सर यह सुविधा नहीं देता।

जब parser blank entries skip करता है, collector files combine करता है या export malformed line छोड़ देता है, तो record numbers बदल सकते हैं। Timestamps एक जैसे हो सकते हैं, गलत order में आ सकते हैं या मौजूद ही न हों। Byte offset reviewer को अलग implementation से exact आसपास के bytes देखने देता है।

जहाँ संभव हो, दो offsets दें:

1. Last valid record शुरू होने का offset।
2. First mismatching record शुरू होने का offset।

अगर mismatch इसलिए है कि record गलत predecessor value की ओर point करता है, तो first mismatching record का start offset report करें। अगर record खुद incomplete है, तो incomplete record की शुरुआत और end-of-file offset report करें। ये अलग स्थितियाँ हैं।

Line-oriented export में known identifier को byte position से खोजने के लिए `grep -b` उपयोगी हो सकता है, लेकिन इसे केवल सुविधा मानें और तभी उपयोग करें जब आपको पता हो कि identifier literally और uniquely encoded है। Binary या encrypted records के लिए ऐसा hex viewer इस्तेमाल करें जो file को न बदले। Known position के आसपास bytes देखने के लिए यह सरल command उपयोगी है:

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

`-s` के बाद की संख्या bytes में offset है। Output में पहले hexadecimal offsets, फिर byte values और जहाँ संभव हो वहाँ ASCII rendering दिखाई देती है। इस excerpt को analysis artifact के रूप में सुरक्षित रखें, लेकिन इसे पूरी file का विकल्प न बनाएँ।

Offset का अर्थ स्पष्ट लिखें। «Offset 104832» अधूरा है। लिखें: «SHA-256 digest 9d5e...c41a वाली acquired file में first mismatching record byte offset 104832 से शुरू होता है, जिसकी गणना byte zero से की गई है।» अगर log में container header है, तो बताएँ कि offset में वह शामिल है या नहीं। शामिल होना चाहिए, क्योंकि दूसरा reviewer आपके acquired file को खोलेगा, parser की internal record stream को नहीं।

एक आम reporting error decompression के बाद का offset देना है। इससे developer को parser issue दोहराने में मदद मिल सकती है, लेकिन evidence file में location नहीं मिलती। दोनों offsets तभी दें जब साफ-साफ label करें: एक raw evidence offset है और दूसरा derivative-analysis offset।

## Records को क्रम से verify करें और break पर trust बढ़ाना बंद करें

Verifier को records को stored order में process करना चाहिए, exact authenticated representation से हर record की expected chain value निकालनी चाहिए और उसे stored chain reference से मिलाना चाहिए। First failure वह पहला point है जहाँ verifier verified prefix से claimed relationship derive नहीं कर सकता।

आगे scan करके किसी बाद के mismatch को केवल इसलिए न चुनें कि वह अधिक गंभीर दिखता है। Proof का scope earliest failure से तय होता है। बाद की failures first failure के downstream consequences, अलग defects या ऐसे parser के artifacts हो सकती हैं जो अब synchronized नहीं है।

Useful output कुछ ऐसा दिख सकता है, भले आपके verifier में field names अलग हों:

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

ये values report structure का उदाहरण हैं, किसी tool से गढ़ा जाने वाला output नहीं। आपकी actual report में record का stable identifier, यदि उपलब्ध हो, file में ordinal position और byte offset होना चाहिए। अगर identifiers encrypted हैं या offline tool को उपलब्ध नहीं हैं, तो पहले ordinal और offset दर्ज करें, फिर authorized analysis path से boundary को sessions से map करें।

Failure को सही तरह classify करें। इन स्थितियों के अलग implications हैं:

- **Predecessor mismatch**: record का previous hash reference verified predecessor से मेल नहीं खाता।
- **Record hash mismatch**: record का stored digest authenticated bytes से निकाले गए digest से मेल नहीं खाता।
- **Missing sequence**: explicit sequence values या checkpoints बताते हैं कि एक या अधिक records गायब हैं।
- **Malformed record**: verifier chain value निकालने लायक complete record parse नहीं कर सकता।
- **Truncated tail**: final record complete होने से पहले file समाप्त हो जाती है।

इन पाँचों को «tampering» कहकर एक न कर दें। Complete record में predecessor mismatch, append के दौरान power loss से अलग है। Malformed record transport damage का परिणाम हो सकता है। Missing sequence evidence यह साबित कर सकता है कि records गायब हैं, भले बाकी हर record का hash सही हो।

NIST Special Publication 800-92 log management को केवल storage से अधिक मानता है: organizations को sources configure करने, logs analyze करने, events पर response देने, data retain करने और log-management operation का audit करने की जरूरत होती है। Chain failure के लिए यही सही operational frame है। Verifier बताता है कि authenticity कहाँ रुकती है। Why जानने के लिए collection, retention, endpoints और response records की भी जाँच करनी होगी।

## कोई session boundary पर दिखाई दिए बिना भी उसे पार कर सकता है

Affected sessions केवल उन session IDs की सूची नहीं हैं जो पहले bad record पर छपे हैं। कोई session verified prefix में शुरू होकर break के बाद actions कर सकता है और damaged portion में अपना identifier दोबारा कभी न दिखाए। दूसरा session पहली बार unverified suffix में दिखाई दे सकता है, लेकिन उससे जुड़ा process, approval या credential use boundary से पहले दिखाई दे सकता है।

Break के दोनों ओर के records से session scope बनाएँ। हर session को boundary से उसके संबंध के आधार पर classify करें:

| Session class | Evidence pattern | Reporting treatment |
| --- | --- | --- |
| Fully verified | Start, actions और end break से पहले हैं | Chain-backed history intact रहती है |
| Crossing | Session का evidence break से पहले और बाद में मिलता है | शुरुआती activity verified, बाद की activity unverified |
| First seen at boundary | पहली occurrence mismatching record है | पूरी observed session history को unverified मानें |
| Suffix-only | सभी observed records break के बाद हैं | Authenticated history नहीं, investigative lead की तरह उपयोग करें |
| Possibly omitted | External evidence ऐसे session का reference देती है जो chain में नहीं है | इसे gap मानकर जाँच करें, normal suffix session नहीं |

Session के boundary पार करने का निर्णय केवल timestamps से न लें। Clocks drift कर सकती हैं, records buffer हो सकते हैं और log writer batches में flush कर सकता है। Session IDs, उपलब्ध होने पर process identifiers, agent-run identifiers, action correlation IDs और explicit start या end records का उपयोग करें। System ये सभी fields न देता हो तो limitation लिखें, यह न दिखाएँ कि time window से समस्या हल हो जाती है।

एक practical worksheet reasoning को reviewable बनाए रखती है:

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

Worksheet में हर conclusion के evidence source का नाम होना चाहिए। «Supporting evidence» session journal, endpoint process record, application event, remote API receipt या SSH server log हो सकता है। केवल यह लिखना पर्याप्त नहीं कि session «probably active» था। Investigators को जानना चाहिए कि conclusion chain, किसी अन्य log या operator statement से आया है।

Sallyport agent runs को Sessions journal में और individual calls को Activity journal में रखता है। दोनों एक ही encrypted hash-chained audit log से project होते हैं। इसलिए chain boundary दोनों views के लिए relevant है, लेकिन इससे friendly journal display को verifier की finding का विकल्प नहीं बनाया जा सकता। Sessions और calls पहचानने के लिए journals का उपयोग करें, फिर हर claim का chain status label करें।

## Last complete record के बारे में अलग निर्णय चाहिए

अचानक समाप्त होने वाली file, predecessor check में fail होने वाले record से अलग सवाल उठाती है। आपको तय करना होगा कि अंतिम bytes में कोई complete लेकिन inconsistent record है या incomplete write है जिसने कभी record का रूप ही नहीं लिया।

File के अंत से शुरुआत करें और उस format के record framing rules तय करें। Line-delimited format में newline जरूरी हो सकता है, लेकिन newline का न होना अपने आप record को incomplete नहीं बनाता। Length-prefixed binary format में declared length की तुलना बाकी bytes से की जा सकती है। Encrypted container में authenticated framing tag invalid complete record और unfinished append के बीच अंतर बता सकता है।

इनमें से कोई एक finding report करें, अस्पष्ट hybrid नहीं:

- «अंतिम complete record verify होता है; file 73 ऐसे bytes पर समाप्त होती है जो complete record नहीं बनाते।»
- «अंतिम complete record offset 104832 से शुरू होता है और predecessor verification में विफल होता है।»
- «Final record 512 bytes घोषित करता है, लेकिन केवल 301 bytes बाकी हैं; content hash निकालना संभव नहीं था।»

यह wording महत्वपूर्ण है क्योंकि operational response अलग होगा। Crash के दौरान truncated tail के लिए दूसरी copy recover करना, storage diagnostics और collector से comparison जरूरी हो सकता है। Complete mismatching record के लिए भी यही comparison चाहिए, लेकिन साथ में endpoint state और access records को तुरंत सुरक्षित करना होगा क्योंकि content मौजूद और inconsistent था।

Truncated record को memory, किसी अन्य export या similar entry से पूरा न करें। Troubleshooting के लिए reconstructed derivative बनाया जा सकता है, लेकिन reconstructed file acquired evidence नहीं है। Reconstruction का नाम, method और source bytes case notes में रखें।

Clean final record यह भी साबित नहीं करता कि file complete है। External checkpoint, signed root, expected sequence count या trusted retention record न होने पर किसी पूरे terminal segment को delete करने के बाद भी chain पूरी तरह verify हो सकती है। Hash chaining inspected sequence के भीतर edits का पता लगाती है। Completeness के लिए उस sequence के बाहर का anchor चाहिए।

## Tampering कहने से पहले independent copies की तुलना करें

Chain break को बढ़ा-चढ़ाकर बताने का सबसे तेज तरीका है एक copy देखना और मान लेना कि वही canonical log है। Actor पर आरोप लगाने से पहले, जहाँ authority और incident process अनुमति दें, independent copies लें।

Useful comparisons में local application store, exported archive, backup snapshot, collector copy, filesystem snapshots और audited action पाने वाले systems के records शामिल हैं। हर copy का अपना digest और acquisition details रखें। «Match करना चाहिए» सोचकर एक copy को दूसरी से overwrite न करें।

यह decision pattern अपनाएँ:

1. अगर independently acquired दो copies में identical preceding bytes के साथ उसी record और byte offset पर failure है, तो समस्या acquisition से पहले मौजूद रही होगी। फिर भी इससे intent साबित नहीं होता।
2. अगर एक copy दूसरी से आगे तक verify होती है, तो first divergence के आसपास files की byte-for-byte तुलना करें। छोटी या damaged copy incomplete हो सकती है।
3. अगर दोनों copies internally verify होती हैं, लेकिन पूरी files के रूप में अलग हैं, तो जाँचें कि वे अलग legitimate segments हैं, अलग scope वाले exports हैं या replacement का evidence।
4. अगर supposedly identical acquisition की digest reads के बीच बदलती है, तो chain analysis रोकें और source medium, live writer, permissions और collection process की जाँच करें।

लोकप्रिय लेकिन गलत सलाह है, «बस log को backup से restore करें और verification फिर चलाएँ।» Restored copy यह दिखाने में मदद कर सकती है कि दूसरी retained copy में क्या था। वह original evidence को repair नहीं कर सकती और न यह समझा सकती है कि live file बदली, गायब हुई या खराब तरीके से collect हुई। दोनों copies रखें। अक्सर incident इन्हीं के अंतर में छिपा होता है।

External action logs scope सीमित करने में मदद कर सकते हैं। अगर agent ने HTTP API invoke की, तो request identifiers, provider-side audit entries और resource changes action के होने या न होने का संकेत दे सकते हैं। अगर उसने SSH का उपयोग किया, तो remote server authentication और command records मददगार हो सकते हैं। ये records broken suffix में cryptographic trust वापस नहीं लाते, लेकिन independently facts स्थापित कर सकते हैं और containment की जरूरत वाले sessions पहचान सकते हैं।

## Incident report ऐसे लिखें कि दूसरा investigator इसे दोहरा सके

अच्छी report पर्याप्त detail के साथ narrow claim करती है ताकि उसकी जाँच हो सके। वह «audit integrity compromised» जैसे broad phrases के पीछे uncertainty नहीं छिपाती।

यह report skeleton उपयोग करें:

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

Last valid record को «last safe action» कहकर report न करें। इसका केवल अर्थ है कि chain उस point तक record sequence को authenticate कर सकती है। Action खुद harmful हो सकता है, अलग approval process के तहत unauthorized हो सकता है या बाद में reverse किया गया हो सकता है। इसी तरह unverified suffix को fake न कहें। वह पूरी तरह accurate हो सकता है। बस उस chain से अब सिद्ध नहीं होता।

Stable failure के बाद पहला action wording पर बहस नहीं, बल्कि affected sessions और credentials के अनुपात में containment होना चाहिए। Evidence सुरक्षित करें, risk होने पर boundary पार करने वाले live sessions revoke करें, incident procedure के अनुसार exposed credentials rotate करें और independent records की तुलना करें। फिर boundary को इतनी precision से लिखें कि अगला investigator आपकी memory पर भरोसा किए बिना काम verify कर सके।
