{"id":51595179,"url":"https://github.com/securityronin/vsc-forensic","last_synced_at":"2026-07-11T18:01:39.994Z","repository":{"id":368076988,"uuid":"1270382366","full_name":"SecurityRonin/vsc-forensic","owner":"SecurityRonin","description":"Volume Shadow Copy forensic library — planned reader/analyzer for Windows VSS store/catalog: enumerate shadow copies, diff filesystem state. Early-stage scaffold.","archived":false,"fork":false,"pushed_at":"2026-06-28T23:29:02.000Z","size":35,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-29T01:14:36.514Z","etag":null,"topics":["dfir","digital-forensics","forensics","incident-response","rust","volume-shadow-copy","vss","windows"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SecurityRonin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-15T16:54:38.000Z","updated_at":"2026-06-28T23:29:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SecurityRonin/vsc-forensic","commit_stats":null,"previous_names":["securityronin/vsc-forensic"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/SecurityRonin/vsc-forensic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fvsc-forensic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fvsc-forensic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fvsc-forensic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fvsc-forensic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SecurityRonin","download_url":"https://codeload.github.com/SecurityRonin/vsc-forensic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fvsc-forensic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35370428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dfir","digital-forensics","forensics","incident-response","rust","volume-shadow-copy","vss","windows"],"created_at":"2026-07-11T18:01:39.173Z","updated_at":"2026-07-11T18:01:39.974Z","avatar_url":"https://github.com/SecurityRonin.png","language":"Rust","funding_links":["https://github.com/sponsors/h4x0r"],"categories":[],"sub_categories":[],"readme":"# vsc-forensic\n\n[![Crates.io vsc-core](https://img.shields.io/crates/v/vsc-core.svg?label=vsc-core)](https://crates.io/crates/vsc-core)\n[![Crates.io vsc-forensic](https://img.shields.io/crates/v/vsc-forensic.svg?label=vsc-forensic)](https://crates.io/crates/vsc-forensic)\n[![Docs.rs](https://img.shields.io/docsrs/vsc-core?label=docs.rs)](https://docs.rs/vsc-core)\n[![Rust 1.81+](https://img.shields.io/badge/rust-1.81%2B-orange.svg)](https://www.rust-lang.org)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)\n[![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/h4x0r)\n\n[![CI](https://github.com/SecurityRonin/vsc-forensic/actions/workflows/ci.yml/badge.svg)](https://github.com/SecurityRonin/vsc-forensic/actions/workflows/ci.yml)\n[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)\n\n**Windows Volume Shadow Copy (VSS) forensics for Rust — a panic-free reader for the shadow-copy store/catalog structures, and a graded anomaly analyzer that turns each NTFS snapshot into evidence you can diff across time.**\n\nVSS is how Windows keeps point-in-time snapshots of an NTFS volume under `System Volume Information`: each shadow copy preserves the blocks that were about to change, so the live volume plus the VSS stores together encode the temporal cohort of the filesystem's past states. `vsc-forensic` is the `[P^H]` disk-history member of the forensic fleet — it navigates that VSS region by snapshot, enumerates the catalog of stores and their metadata, and surfaces shadow-copy timeline and integrity anomalies as fleet findings.\n\n## Quick start\n\nPoint the reader at a raw NTFS volume (offset 0 = the NTFS boot sector) and enumerate its shadow copies:\n\n```rust\nuse std::fs::File;\nuse vsc::VssVolume;\n\nlet mut vol = VssVolume::open(File::open(\"ntfs_volume.raw\")?)?;\nprintln!(\"shadow copies: {}\", vol.store_count());\n\nfor store in vol.stores() {\n    println!(\n        \"{}  size {}  created FILETIME {}\",\n        store.store_id_string(), store.volume_size, store.creation_time,\n    );\n}\n\n// Read a store's per-snapshot metadata (shadow-copy IDs, attribute flags, machine).\nif vol.store_count() \u003e 0 {\n    let info = vol.store_info(0)?;\n    println!(\"shadow copy {}\", info.shadow_copy_id_string());\n\n    // Reconstruct the volume as it was at the snapshot — copy-on-write blocks\n    // overlaid on the live volume — and read any 16 KiB block back.\n    let mut snap = vol.snapshot(0)?;\n    let block = snap.read_block(0)?; // the NTFS boot sector as it was at snapshot time\n    println!(\"snapshot boot sector: {:02x?}\", \u0026block[3..11]); // b\"NTFS    \"\n}\n# Ok::\u003c(), vsc::error::VssError\u003e(())\n```\n\nThen run the analyzer to get graded findings — no shadow copies where you expected some (consistent with MITRE T1490 deletion), a sequence gap, a non-persistent store:\n\n```rust\nuse vsc_forensic::audit;\n\nfor anomaly in audit(\u0026mut vol) {\n    println!(\"[{:?}] {} — {}\", anomaly.severity, anomaly.code, anomaly.note);\n    // e.g. [Info] VSC-STORE-PRESENT — shadow copy 1afc8871-… created 2023-01-04T21:38:00Z\n}\n```\n\n## The two-crate split\n\nFollowing the fleet reader/analyzer standard, the workspace ships two crates:\n\n| Crate | Role | Depends on | Emits |\n|---|---|---|---|\n| [`vsc-core`](https://crates.io/crates/vsc-core) | reader / decoder | `uuid`, `thiserror` | typed VSS catalog / store records |\n| [`vsc-forensic`](https://crates.io/crates/vsc-forensic) | anomaly analyzer | `vsc-core`, `forensicnomicon` | graded [`forensicnomicon::report::Finding`](https://crates.io/crates/forensicnomicon)s |\n\nThe reader stays pure — it decodes bytes and makes no judgments. All *forensic meaning* lives in the analyzer, a side-effect-free function of already-decoded records. That separation is why `vsc-core` is useful on its own and why `vsc-forensic` drops straight into a fleet `Report` next to every other analyzer.\n\n## Findings\n\n| Code | Meaning |\n|---|---|\n| `VSC-NO-SHADOW-COPIES` | a VSS volume header is present but the catalog holds zero stores — consistent with MITRE T1490 shadow-copy deletion *or* a volume that never had snapshots |\n| `VSC-STORE-PRESENT` | one finding per enumerated shadow copy, carrying its GUID and creation time |\n| `VSC-SEQUENCE-GAP` | non-contiguous catalog sequence numbers — consistent with a deleted intermediate store |\n| `VSC-STORE-NON-PERSISTENT` | a store whose attribute flags mark it non-persistent |\n\nFindings are observations, not verdicts — the \"consistent with\" framing is deliberate; the analyst or tribunal draws the conclusion.\n\n## Capabilities\n\n| Capability | Status |\n|---|---|\n| VSS volume header + catalog enumeration (store GUID, size, sequence, creation time) | ✅ |\n| Store metadata decode (shadow-copy IDs, attribute flags, originating machine) | ✅ |\n| `vsc-forensic` anomaly auditor (`VSC-*` findings → `forensicnomicon::report`) | ✅ |\n| Fuzzed (`fuzz_catalog` / `fuzz_store` / `fuzz_reconstruct`) + Tier-1 validated against `libvshadow` | ✅ |\n| COW block-list reconstruction — materialize a snapshot's view of the volume, read any block back | ✅ |\n\n## Trust but verify\n\nBoth crates enforce the fleet hardening contract: `#![forbid(unsafe_code)]`, the Paranoid-Gatekeeper clippy set (`unwrap_used`/`expect_used` denied), bounds-checked readers that never panic on malformed input, `cargo-deny` supply-chain gating, and a 100%-line-coverage CI gate. Every parsed structure has a `cargo-fuzz` target whose invariant is \"must not panic\".\n\nCorrectness is proven against an **independent third-party oracle** — [`libvshadow`](https://github.com/libyal/libvshadow) (via `pyvshadow`) — run on a real public CTF disk image: `vsc-core`'s catalog and store-metadata output matches the oracle field-for-field (store count, GUID, volume size, creation FILETIME, shadow-copy IDs), and its **reconstruction** reproduces the snapshot's bytes block-for-block across every path — passthrough, bitmap zero-fill, plain copy-on-write, and 512-byte overlay merge (validated over 1,415 blocks; the algorithm is documented in [docs/RECONSTRUCTION.md](docs/RECONSTRUCTION.md)). See [`tests/data/README.md`](tests/data/README.md) and the env-gated `oracle_pcmus001` / `reconstruct_pcmus001` integration tests.\n\n## Documentation\n\nThe curated docs site is built with MkDocs and served from GitHub Pages. See [docs/RESEARCH.md](docs/RESEARCH.md) for the VSS on-disk format research behind the design.\n\n[Privacy Policy](https://securityronin.github.io/vsc-forensic/privacy/) · [Terms of Service](https://securityronin.github.io/vsc-forensic/terms/) · © 2026 Security Ronin Ltd\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Fvsc-forensic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecurityronin%2Fvsc-forensic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Fvsc-forensic/lists"}