Field Guide

Chain of custody for a physical penetration test

How to prove your evidence was not altered · 2026

On a physical penetration test, the evidence you collect is small, copyable, and produced off the network on handheld hardware. That is exactly what makes it easy to challenge. This guide sets out what an unbroken chain of custody requires for physical findings, and how a SHA-256 hash taken at the point of capture turns a contestable file into tamper-evident evidence.

Why physical findings get challenged

When a red team clones an access badge, captures a fob, or reads a card at a turnstile, the proof of that work is a tiny capture file. A Flipper Zero .nfc dump can be a few hundred bytes. A Proxmark3 log is plain text. Either one opens in any editor. Change a UID, a sector, or a key, and the file still looks valid. Nothing inside the file says when it was read, which device read it, or whether a single byte changed afterwards.

That is the opening a client uses to push back. When a physical finding lands in front of the building's facilities manager, the client's security team, or an external auditor, the first question is rarely "how bad is this". It is "how do we know this is real, and that nobody edited it after the visit". A narrative that says the team cloned a badge and walked in carries no weight on its own. The capture file behind it has to be anchored to the moment it was collected.

Three properties make physical evidence unusually contestable:

Any one of those is enough for a motivated client to argue the evidence cannot be trusted.

What an unbroken chain of custody actually requires

Chain of custody is a forensic idea, not a marketing one. For a physical pentest finding to hold up, the chain has to answer four questions without a gap:

The integrity question is the hard one, because it is the one a file cannot answer about itself. The standard answer in digital forensics is a cryptographic hash. A SHA-256 digest is a 64-character fingerprint of the exact bytes of a file. Change a single byte and the digest changes completely. Record the digest at collection time, and anyone can recompute it later and compare. If the two match, the bytes are identical. If they differ, the file changed. There is no middle ground and no practical way to forge a match.

The catch is timing. A hash only proves integrity from the moment it was taken. Hash a capture a week later on the analyst's laptop, and all you have proven is that nobody changed it in the last few seconds. The value of the hash is a function of how early in the chain it was created.

Where the chain breaks on a physical engagement

On most engagements the hash, if it exists at all, is created far too late. The capture happens on a handheld at the site. The file then travels: copied off an SD card, dropped onto a laptop, sent over a chat tool, pulled into a reporting template, and finally hashed (if anyone remembers) at write-up time, days later. Every hop before that first hash is unprotected. If the question is "could this have been altered between the site and the report", the honest answer for most teams is "yes, and we cannot prove otherwise".

That is the gap. Not dishonesty, just a missing anchor at the start of the chain.

Hashing at the point of capture

The fix is to move the hash to the earliest possible moment: the device, at the instant of capture. Vaultprobe does this for NFC captures. A capture companion running on the handheld computes a SHA-256 of the native file the moment it is written, and stores that digest in a small sidecar record alongside the capture. The chain of custody therefore begins on the device, before the file ever reaches a laptop, rather than after.

When that capture is later ingested, Vaultprobe independently recomputes the SHA-256 over the file's raw bytes and compares it to the on-device digest. The raw-byte detail matters: the hash is taken over the exact bytes on disk, so it matches a plain sha256sum of the file and stays byte-accurate for binary captures, not a lossy text projection of them. The result is one of a few clear states, and every one of them is shown rather than hidden:

The sidecar also carries the engagement identifier, the operator, the capture sequence, and the capture time recorded by the device, so the integrity proof travels together with the context that makes it reproducible.

Re-verifying the evidence later

A custody chain is only useful if a third party can check it without trusting you. Vaultprobe records the SHA-256 of every ingested capture in the report as a custody record with its own evidence identifier. Anyone holding the original file can re-verify it on demand:

$ vaultprobe verify VP-2026-0042 --file badge.nfc Stored SHA-256 : 498ee8be2b43984788c3445dcda87ba9... Current SHA-256: 498ee8be2b43984788c3445dcda87ba9... VERIFIED. File integrity confirmed.

The command re-hashes the file's raw bytes and compares. It exits zero when the hashes match and a non-zero code when they do not, so the check can run unattended in a pipeline as well as by hand. A client's own auditor can run sha256sum badge.nfc on their own machine and compare the result to the digest printed in the report, with no Vaultprobe install required at all. The whole evidence set also gets a single master identifier derived from every file hash, so a change to any one capture is detectable at the level of the engagement, not just the individual file.

Integrity that only your own tool can confirm is not integrity. Because each custody record is a standard SHA-256 over the original file, the verification path is one anybody can walk, including the client's auditor, on their own machine, with tools they already trust.

From custody to a defensible report

An unbroken chain of custody is the foundation, not the finished product. The hash proves the bytes did not change. The report still has to put those bytes in front of an auditor in a form they can trace, map to a control, and reproduce. That is where capture integrity and framework mapping turn an intact capture into a finding a client cannot wave away.

See it on your own captures

Vaultprobe runs as a single self-hosted Docker container, with no cloud upload and no client data leaving your network. The 30-day pilot lets you put your own engagement files through it and read the chain-of-custody output in a real report.