6.9 KiB
Native EVTX export and recovery evidence
Related to #382. evtx-recovery exports one validated native Security 4688 probe to a new .evtx file, reopens it with the Windows event API and compares its original event fields. Verify can repeat that read under the intended reader's actual Windows session. Sysmon is excluded.
# First collect a real fixed probe using existing, enabled audit prerequisites.
./WELA.ps1 native-validation -ProbeAction Run -ProbeOutputPath C:\Evidence\probe
# On that source host, export exactly the observed record and verify native readback.
./WELA.ps1 evtx-recovery -EvtxAction Export -EvtxProbePath C:\Evidence\probe -EvtxOutputPath C:\Evidence\archive
# Run under the intended reader account with access to the unchanged source bundle and EVTX.
./WELA.ps1 evtx-recovery -EvtxAction Verify -EvtxProbePath C:\Evidence\probe -EvtxArchivePath C:\Evidence\archive\probe.evtx -EvtxOutputPath C:\Evidence\readback
Verify is the default. The command changes no Windows policy, log settings, retention or permissions on existing evidence. New output directories restrict inherited access to the current user, SYSTEM and local Administrators; any transfer/access arrangement for another reader is an operator task. Local fixed-drive paths only; no network/device paths, alternate streams, reparse traversal, overwrites or output inside the input bundle. Relative paths follow PowerShell's current location.
The importer requires the exact five native-probe files, four matching hashes, strict JSON, consistent embedded metadata, all 59 typed audit masks, valid native process/event identities and unchanged source prerequisites. Imported evidence is operator supplied; hashes prove consistency, not authenticity. Export compares the live source host and policy context to the original probe and verifies the actual Security record before copying it. The exported file is reopened even when Windows reports a successful export: an empty EVTX is not success.
The archive stays open without write/delete sharing during hashing and native readback. Exactly one event must match the original System and EventData semantics, and the native query status must identify that exact file with a zero status code. XML namespace/attribute order and optional RenderingInfo are handled without ignoring original fields. Empty, corrupt, denied, duplicate or changed records remain Unverified, as do reader/host/source changes. Each recovered XML record is capped at four MiB; the archive is capped at sixteen MiB. The report records actual archive bytes/hash, reader SID/groups/logon identity, host context, source identity, query, timestamps and recovered raw XML.
Version 2 recovery reports contain ReaderBefore and ReaderAfter primary-token snapshots with the actual user, process, token ID, authentication/logon ID and modification ID. The native helper rejects impersonation and requires its loaded C# source to match the current file. The recorded interval starts after private output/ACL and source-policy preparation, before event access; it ends after archive hashing, native query and input-file verification. Token changes, including privilege adjustments that change the modification ID, invalidate the interval. Final host and source-policy inventory runs outside that interval because those APIs may adjust available privileges. Implementation fingerprints and private evidence hashes are checked before the final manifest. These observations are not signatures or an atomic transaction against another administrator.
Verify reads ordinary host metadata and does not require administrator-only installed-feature inventory. Run it in the intended account's own Windows session with existing read access to the unchanged probe bundle and EVTX plus permission to create its private output. FileReadAccess=Denied records an actual denied file-open attempt; NativeQuery=NotAttempted makes clear that no event query followed. An opened file records FileReadAccess=Allowed, while NativeQuery=ExactEventRecovered requires the actual Windows event API and matching event content. Native query denial is recorded separately. A later token/context/evidence failure keeps the overall report Unverified, even if earlier I/O observations succeeded. The event's original producer is independent of the archive reader: opening a Security EVTX does not establish access to the live Security channel, an Event Log Readers membership requirement, or access by a WEC service token. The product offers no credential, impersonation, group-membership or privilege-granting options and does not grant archive permissions.
NativeEventRecovered proves only that this recorded reader recovered this one event at the observation time. It does not establish completeness, eighteen-month retention, rollover behavior, storage capacity, other-principal access, disaster recovery or Sigma readiness. It does not archive localized message resources or clear the source log. The new archive is a probe artifact, not a full-log backup.
Focused fixtures exercise source/event tampering, empty/duplicate/corrupt/denied readback, native query status, primary-token/logon/modification/host/source drift, paths and CLI guards. Explicitly gated disposable Server 2022/2025 tests under PowerShell 5.1/7 collect a genuine 4688 event, export/reopen it, independently verify it and reject an actual empty EVTX. A separate owned standard account uses two fresh primary-token logons to prove file-read denial and exact native recovery after removing a deny ACE from an owned archive copy. The account is neither an administrator nor an Event Log Readers member. Its credentials pass only through the process API, and its temporary files, outputs and ACL changes stay in the owned fixture. The test restores that file ACL, removes only the owned account, and checks all 59 original audit masks and typed registry values/absence. It requires both -AllowDisposablePolicyWrite and -AllowDisposableAccount on an ephemeral GitHub-hosted runner. Windows 11/DC/ADCS, service/network-reader and long-term recovery exercises remain deployment checks.
Implementation references: Microsoft EventLogSession.ExportLog selects events without message resources; EvtExportLog requires a new target and can create a header-only file for an empty query.
TOKEN_STATISTICS defines token, logon and modification identities; WindowsIdentity.GetCurrent distinguishes a process primary token from thread impersonation; EvtQuery supports local file queries independently of live channel queries.