Skip to main content

IntegrityAnomaly

Enum IntegrityAnomaly 

Source
pub enum IntegrityAnomaly {
Show 20 variants LogCleared { channel: String, timestamp: u64, user_sid: Option<String>, }, RecordIdGap { chunk_offset: u64, expected: u64, found: u64, }, ChecksumMismatch, ChunkChecksumMismatch { chunk_offset: u64, computed: u32, stored: u32, }, RecordChecksumMismatch { chunk_offset: u64, computed: u32, stored: u32, }, NextRecordIdInconsistency { header_next: u64, actual_highest: u64, }, TimestampAnomaly { chunk_offset: u64, record_id: u64, prev_ts: u64, this_ts: u64, }, FileHeaderChecksumMismatch { computed: u32, stored: u32, }, FileNotCleanlyShutdown, FileFull, ChunkCountMismatch { header_count: u16, actual_count: usize, }, ExportTimestampCorruption { record_id: u64, chunk_offset: u64, }, SurgicalRecordDeletion { chunk_offset: u64, absorbing_record_id: u64, stated_size: u32, ghost_offset_in_chunk: u64, }, InvalidChunkDataLength(u32), LogFileGuidMismatch { chunk_index: usize, expected: u128, actual: u128, }, TrailingData { offset: u64, len: usize, }, TruncatedFile { declared_chunks: u16, found_chunks: usize, }, OverlappingChunks { chunk_a_offset: u64, chunk_b_offset: u64, }, EmptyLog, PhantomRecordInjection { gap_start_id: u64, gap_end_id: u64, prev_timestamp_ns: i64, next_timestamp_ns: i64, },
}
Expand description

Structural integrity anomalies detected in an EVTX file.

These variants represent low-level binary format facts only. Intent inference (e.g. anti-forensic classification) belongs in the caller — for example, the RapidTriage correlation engine.

Variants§

§

LogCleared

Fields

§channel: String
§timestamp: u64
§user_sid: Option<String>
§

RecordIdGap

Fields

§chunk_offset: u64
§expected: u64
§found: u64
§

ChecksumMismatch

Generic checksum mismatch (caller should prefer the specific variants below).

§

ChunkChecksumMismatch

Fields

§chunk_offset: u64
§computed: u32
§stored: u32
§

RecordChecksumMismatch

Fields

§chunk_offset: u64
§computed: u32
§stored: u32
§

NextRecordIdInconsistency

Fields

§header_next: u64
§actual_highest: u64
§

TimestampAnomaly

Fields

§chunk_offset: u64
§record_id: u64
§prev_ts: u64
§this_ts: u64
§

FileHeaderChecksumMismatch

Fields

§computed: u32
§stored: u32
§

FileNotCleanlyShutdown

§

FileFull

§

ChunkCountMismatch

Fields

§header_count: u16
§actual_count: usize
§

ExportTimestampCorruption

A record has a zeroed header timestamp consistent with the wevtutil / Event Viewer export bug: when exporting with wevtutil epl or “Save As…”, each record’s header timestamp is replaced with the previous record’s BinXml timestamp; the first record in the export therefore has no predecessor and receives timestamp 0.

Reference: Wassenaar, Fox-IT BV (2019). “Export corrupts Windows Event Log files” https://blog.fox-it.com/2019/06/04/export-corrupts-windows-event-log-files/

Fields

§record_id: u64

Record ID of the affected record (header timestamp is 0).

§chunk_offset: u64

Byte offset of the chunk that contains this record.

§

SurgicalRecordDeletion

A record’s stated size spans the magic bytes of a subsequent record, consistent with surgical deletion by the NSA DanderSpritz eventlogedit tool. The tool absorbs the deleted record into the preceding record’s size field without emitting EID 1102.

Reference: Wassenaar & van Dijk, Fox-IT BV (2017). “Detection and recovery of NSA’s covered up tracks” https://blog.fox-it.com/2017/12/08/detection-and-recovery-of-nsas-covered-up-tracks/

Reference implementation (Python): Wassenaar, Fox-IT BV — fox-it/danderspritz-evtx https://github.com/fox-it/danderspritz-evtx (MIT License; algorithm independently re-implemented in Rust)

Fields

§chunk_offset: u64

Byte offset of the chunk containing the anomaly.

§absorbing_record_id: u64

Record ID of the absorbing record (its size was inflated).

§stated_size: u32

The inflated size value read from the absorbing record.

§ghost_offset_in_chunk: u64

Byte offset within the chunk where the ghost record’s magic bytes (0x2A 0x2A 0x00 0x00) were found inside the absorbing record’s body.

§

InvalidChunkDataLength(u32)

Chunk data length field falls outside the valid EVTX range [512, 65536].

§

LogFileGuidMismatch

The log_file_guid field in a chunk header differs from the first chunk’s GUID, indicating the chunk was transplanted from a different log file.

Fields

§chunk_index: usize
§expected: u128
§actual: u128
§

TrailingData

Unexpected bytes follow the last valid chunk in the file.

Fields

§offset: u64

Byte offset where unexpected data begins after the last valid chunk.

§len: usize

Number of unexpected bytes.

§

TruncatedFile

The file ends before all chunks declared in the file header are present.

Fields

§declared_chunks: u16

Chunk count declared in the file header.

§found_chunks: usize

Chunks actually found in the file.

§

OverlappingChunks

Two chunk byte-ranges overlap, indicating structural corruption.

Fields

§chunk_a_offset: u64

Byte offset of the first (earlier) chunk.

§chunk_b_offset: u64

Byte offset of the second (later) chunk whose range overlaps chunk_a.

§

EmptyLog

The file header reports zero chunks. The log was cleared and the file was recreated but never written to, or the header is corrupt.

§

PhantomRecordInjection

A record-ID gap whose timestamp delta is too small to account for the missing records, suggesting phantom records were injected without advancing the clock — a deliberate anti-forensic technique.

Fields

§gap_start_id: u64

First record ID in the gap (inclusive).

§gap_end_id: u64

Last record ID in the gap (inclusive).

§prev_timestamp_ns: i64

Timestamp (nanoseconds) of the record immediately before the gap.

§next_timestamp_ns: i64

Timestamp (nanoseconds) of the record immediately after the gap.

Implementations§

Source§

impl IntegrityAnomaly

Source

pub fn severity(&self) -> Severity

Returns the Severity of this anomaly.

Source§

impl IntegrityAnomaly

Source

pub fn code(&self) -> &'static str

Stable, scheme-prefixed machine code for this anomaly.

Trait Implementations§

Source§

impl Clone for IntegrityAnomaly

Source§

fn clone(&self) -> IntegrityAnomaly

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for IntegrityAnomaly

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Observation for IntegrityAnomaly

Source§

fn severity(&self) -> Option<Severity>

Severity, or None if the analyzer deliberately does not grade this kind.
Source§

fn code(&self) -> &'static str

Stable, scheme-prefixed machine code.
Source§

fn note(&self) -> String

Human-readable, consistent-with note.
Source§

fn category(&self) -> Category

Analytical lens; defaults to Category::from_code of Observation::code. Override when a code’s keyword classification is wrong.
Source§

fn subjects(&self) -> Vec<SubjectRef>

Non-disk subjects this kind is about (default: none).
Source§

fn evidence(&self) -> Vec<Evidence>

Backing evidence rows (default: none).
Source§

fn mitre(&self) -> &'static [&'static str]

MITRE ATT&CK technique ids this kind is consistent with (default: none).
Source§

fn confidence(&self) -> Option<Confidence>

Heuristic confidence, if inferential (default: none).
Source§

fn to_finding(&self, source: Source) -> Finding

Assemble the canonical Finding from this kind and its producing source.
Source§

impl Serialize for IntegrityAnomaly

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.