Skip to content

Add real EVTX parser (parse_evtx_real)#6

Merged
bioless merged 1 commit into
mainfrom
real-evtx-parser
Jun 15, 2026
Merged

Add real EVTX parser (parse_evtx_real)#6
bioless merged 1 commit into
mainfrom
real-evtx-parser

Conversation

@bioless

@bioless bioless commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Adds the real parse_evtx_real typed tool wrapping evtx_dump: evidence-ID only, read-only subprocess, structured records (EventID/channel/provider/timestamp/record offset) plus failure artifacts, input schema, manifest registration, deterministic tests. 41 passed, 1 skipped (the live-parse test skips until a sample .evtx is staged). No phase rework; built on main at 2ac2933.

…d-only subprocess), structured records (EventID/channel/provider/timestamp/record offset) + failure artifacts, input schema, manifest registration, deterministic tests
Copilot AI review requested due to automatic review settings June 15, 2026 00:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new typed tool, parse_evtx_real, that wraps evtx_dump to parse registered EVTX evidence into a normalized JSON artifact, including structured failure artifacts and deterministic unit tests. This extends the existing typed-tool infrastructure beyond mocks while keeping tool inputs schema-validated and evidence-ID based.

Changes:

  • Register the new parse_evtx_real tool in the builtin tool registry and example plugin manifest.
  • Implement parse_evtx_real plus helper functions for locating evtx_dump, invoking it, and normalizing XML event records.
  • Add unit tests and input schema for the new tool, plus README documentation and manifest-order test updates.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_typed_tools.py Updates manifest-order expectations to include parse_evtx_real.
tests/test_parse_evtx_real.py Adds deterministic unit tests for binary discovery, schema rejection, failure modes, and basic XML parsing.
src/sift_crs/tools.py Implements parse_evtx_real and supporting helpers (binary lookup, subprocess invocation, XML normalization).
schemas/parse_evtx_real.input.schema.json Defines schema-validated inputs (case_id, evidence_id only).
README.md Documents the new real EVTX parser tool and usage example.
examples/plugin_manifest.example.json Registers parse_evtx_real in the example manifest.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/sift_crs/tools.py
Comment on lines +528 to +529
def is_executable_file(path: Path) -> bool:
return path.is_file() and os.access(path, os.X_OK)
Comment thread src/sift_crs/tools.py
Comment on lines +371 to +375
completed = subprocess.run(
command,
check=False,
capture_output=True,
text=True,

def write_fake_binary(path: Path, body: str) -> Path:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("#!/usr/bin/python3\n" + body, encoding="utf-8")

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 612725ed44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/sift_crs/tools.py
Comment on lines +484 to +485
"evidence_id": evidence.evidence_id,
"source_sha256": evidence.sha256,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify evidence bytes before claiming the ledger hash

When a registered EVTX file is modified or replaced after registration but before this tool runs, the subprocess parses the changed bytes while the artifact still copies the original ledger hash into source_sha256. The deterministic verifier only compares this field with the ledger value, so findings derived from altered evidence can incorrectly pass hash verification. Re-hash the file immediately before/after parsing and fail the run if it no longer matches the registered hash.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/tools.py
Comment on lines +511 to +514
for name in EVTX_DUMP_NAMES:
candidate = Path(directory) / name
if is_executable_file(candidate):
return candidate

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid executing PATH-selected parsers with evidence access

When PATH contains a shadowing or compromised executable named evtx_dump, this lookup selects and executes it with the registered evidence path and unrestricted process permissions. Such an executable can modify evidence or make network calls despite the tool being declared read_only and the manifest declaring network/shell access disabled. Use a trusted/pinned parser and enforce read-only isolation before giving a subprocess access to evidence.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/tools.py
Comment on lines +371 to +375
completed = subprocess.run(
command,
check=False,
capture_output=True,
text=True,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stream EVTX output instead of buffering it

For large forensic event logs, capture_output=True loads the complete XML dump into memory, after which the code also builds a full ElementTree and a second normalized records list. XML output can be substantially larger than the source EVTX, so an ordinary large log can exhaust process memory and terminate without the structured failure artifact promised by this tool. Stream and incrementally parse the subprocess output instead.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/tools.py
Comment on lines +374 to +376
capture_output=True,
text=True,
timeout=60,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the parser timeout suitable for real EVTX files

Any valid EVTX whose evtx_dump conversion takes longer than 60 seconds is unconditionally killed and reported as a failure. This is a common scenario for large Security or ForwardedEvents logs, especially with the intended pure-Python parser, and callers have no input option to request a longer limit. Make the timeout configurable or base it on a policy suitable for forensic-sized evidence.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/tools.py
Comment on lines +614 to +616
"record_offset": coerce_int(
event.attrib.get("offset") or event.attrib.get("record_offset")
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Derive record offsets from actual EVTX metadata

For the documented python-evtx evtx_dump, standard event XML does not add offset or record_offset attributes to the <Event> element, so this field is always null on real parser output. The test only passes because its fake XML injects a nonstandard offset attribute, meaning the advertised source record offset is unavailable during real investigations. Obtain the offset from EVTX record metadata or stop claiming that it is populated.

Useful? React with 👍 / 👎.

@bioless
bioless merged commit 8d43300 into main Jun 15, 2026
1 check passed
@bioless
bioless deleted the real-evtx-parser branch June 15, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants