Triage a reproducible benign artifact
Produce a structured observation record without extracting or executing the contents.
Audience: beginning malware-analysis and DFIR learners. Prerequisites: a terminal, JSON familiarity, and Python 3.9 or later; no third-party packages. Planning time: 15–20 minutes. Executed with Python 3.13.12 on Linux; fixture and validator version 1.0, reviewed 2026-09-09.
The artifact is an authored ZIP containing one plain-text note. The source fixes the entry name, timestamp, permissions, storage mode, and bytes so it can be regenerated. A URL and the word powershell are text observations; their presence does not demonstrate a network connection or interpreter execution.
Inputs and provenance
Download triage.py, the benign fixture.zip, and expected.json. No live sample or external upload is part of this exercise. The distributed ZIP is 245 bytes; its SHA-256 is:
77c380a3c4ab35efe50964b9c97db8bbbe27c49f96a65ee92b63c7c24f676cbb
A matching digest checks byte identity against this published fixture. It does not prove that an arbitrary file is safe or that a publisher is trustworthy.
Workflow and corroboration
- Inspect the script. It accepts only the expected stored entry, bounds file and entry sizes, and reads into memory. It never extracts entries or evaluates their text.
- Run the inspection and controls below.
- Regenerate into a new filename. Generation refuses to overwrite an existing file. Compare both observation records and hashes.
- On Linux, independently run
sha256sum fixture.zipandunzip -l fixture.zip; the archive listing should show onenotes.txtentry, 129 bytes, dated 2026-01-01. These commands inspect this supplied benign fixture.
python3 triage.py fixture.zip
python3 triage.py --self-test
python3 triage.py --generate regenerated.zip
python3 triage.py regenerated.zip
Expected structured observation
{"bytes": 245, "entries": ["notes.txt"], "execution_observed": false, "format": "ZIP (stored)", "sha256": "77c380a3c4ab35efe50964b9c97db8bbbe27c49f96a65ee92b63c7c24f676cbb", "strings": ["example.invalid", "powershell"], "text_bytes": 129}
The format, length, archive entry, and exact content are checked. execution_observed: false describes this static workflow's visibility, not proof of the absence of behavior in another environment.
Failure and negative cases
{"negative_controls_rejected": 3, "positive_fixture_passed": true}
The self-test rejects a traversal entry name, changed content with an invalid CRC, and non-ZIP bytes. It creates those controls in memory and extracts none. Unexpected compression, oversized entries, wrong content, missing files, and malformed archives stop validation with an error; an error is not a malware verdict. An identical hash with a different observation record indicates a tool or environment discrepancy that requires investigation.
Limitations and next step
This deliberately narrow validator recognizes one known fixture. It is not a general archive scanner, sandbox, malware classifier, or a safe parser for arbitrary hostile samples. Static strings suggest questions; they do not demonstrate execution, persistence, or attribution. Keep this provenance and observation record with a separate hypothesis and a safe corroboration step.
Continue the malware-triage path and the analysis guide. Adapt the observation schema to another approved benign artifact before considering any separately authorized dynamic analysis.