Show that a snapshot is not a backup
Task
Demonstrate the difference between a snapshot, a replica and a backup by applying the same destructive event to all three and seeing which survives. This is the distinction ransomware exploits, and one exercise settles it permanently.
Steps
- Create a dataset directory and three protections: a filesystem-level snapshot on the same storage, readable at
/tmp/snap(a btrfs snapshot there, or an LVM snapshot mounted there); a replica synchronised to/tmp/replica(rsync -a --delete <dataset>/ /tmp/replica/); and a backup archive of the dataset's contents (tar cf <backup> -C <dataset> .) written to separate storage and then made unwritable by the account that will run the destructive script -- owned by root, no write permission, and the script run as your ordinary user. Each copy must hold the dataset's files at its top level, so all three can be compared with the original. - Verify all three currently contain the data.
- Write the destructive event yourself: a short script that walks the dataset directory and rewrites each file with its own encrypted contents, using a key it then discards. Nothing outside that directory is touched.
- Run it against the dataset. Then check each protection in turn: does the snapshot still hold the original, does the replica, does the backup?
- Extend the event the way real ransomware does: have your script also look for and overwrite anything it can reach that resembles a protection copy. Re-run from a clean state and check the three again.
- Write
/tmp/protections.mdrecording which survived each round, and why the one that survived did.
Files the Verify reads
The Verify block reads these by name, so save them exactly here:
-
/tmp/backup-extract-- the directory you restore the backup copy into after the second round, e.g.tar xf <backup> -C /tmp/backup-extract. -
/tmp/original.sha-- one hash of the whole dataset taken BEFORE the destructive event, made with exactly the command the Verify uses on each copy, from inside the dataset directory:(cd <dataset> && find . -type f -exec sha256sum {} + | LC_ALL=C sort | sha256sum | cut -d' ' -f1) > /tmp/original.sha. It covers every file's content and relative path, so a copy matches only if it holds the same files with the same contents.
Verify
tree_hash() { (cd "$1" 2>/dev/null && find . -type f -exec sha256sum {} + | LC_ALL=C sort | sha256sum | cut -d' ' -f1) || echo MISSING; }
orig=$(cat /tmp/original.sha); kept=0; backup=LOST
for p in snapshot:/tmp/snap replica:/tmp/replica backup:/tmp/backup-extract; do
n=${p%%:*}; if [ "$(tree_hash "${p#*:}")" = "$orig" ]; then s=intact; kept=$((kept+1)); else s=LOST; fi
echo "$n $s"; [ "$n" = backup ] && backup=$s
done
[ "$backup" = intact ] && echo "the read-only backup survived" || echo "FAIL: the backup did not survive - was it unwritable by the script's account before round 2?"
[ "$kept" -lt 3 ] && echo "round 2 reached a protection copy" || echo "FAIL: all three survived - round 2 never reached the protection copies"
grep -ciE "read.only|immutable|offline|same storage" /tmp/protections.md
Neither FAIL line may print. The offline read-only copy must survive, and at least one of the other two must not — if all three survive, the second round never reached them and the lab has demonstrated nothing. The write-up must name why: the snapshot shared the storage, the replica faithfully replicated the damage, and only the copy the running system could not write to was out of reach.
Notes
This is why the lesson adds 'one immutable or offline' to the 3-2-1 rule. A backup the production credentials can delete is a backup the attacker can delete, and modern ransomware looks for exactly that before it starts encrypting anything.
This is an independent study companion for CompTIA Security+ SY0-801 and is not produced by or endorsed by CompTIA.