Force Push
Force Push
Platform: CACTF2026 | Category: Forensics | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-07-27 | Status: Solved Techniques: git_fsck_enumeration, unreachable_object_recovery, git_object_verification
Summary
Task: A leaked Git repository has spotless reachable history after a committed production credential was removed. Solution: Enumerate unreachable objects with git fsck and extract the deleted file directly from its orphaned commit.
Force Push — CACTF2026
Description
We pulled a copy of the
crownspire-deployrepository off a leaked Cinderbound backup. Word is the production warden's key for the reliquary got committed by mistake and then cleaned up before anyone noticed. The current history looks spotless. Recover what they tried to bury.
The ZIP contains a complete crownspire-deploy/ repository, including its .git/ directory and loose Git objects. The goal is to recover the credential removed from visible branch history.
Semantic Clue
The title Force Push points to rewritten Git history. Moving a branch reference does not immediately erase the old commit, tree, and blob objects; until garbage collection removes them, they may remain in the object database as unreachable objects.
Analysis
First, verify the downloaded evidence and inspect every reachable reference:
bash read-only • copy allowedshasum -a 256 challenge_download git -C crownspire-deploy log --all --oneline --decorate
The archive digest is:
text read-only • copy allowed08f819507302c60599bf08be2432c06bcdf98638c4faab67e203b05b5de343e0
The reachable main history ends at 7ae3842, and git log --all contains no secret-bearing commit. This denies the reachable-history hypothesis.
Next, ask Git to validate the complete object database while excluding reflogs from reachability:
bash read-only • copy allowedgit -C crownspire-deploy fsck --full --no-reflogs --unreachable
Relevant output:
text read-only • copy allowedunreachable commit 3c8803d7146cd07c75325d6b555116200f2569ee unreachable tree 1fe5a4a75df03ff80a3743b93b8df188ee48c06c unreachable blob 12b14971d38c09ee73fed80613951dfdd3562291
Inspecting the orphaned commit identifies the mistake without checking it out:
bash read-only • copy allowedgit -C crownspire-deploy show --stat --format=fuller 3c8803d7146cd07c75325d6b555116200f2569ee
Its message is:
text read-only • copy allowedtemp: add reliquary.creds to debug 403 on manifest push (REVERT ME)
The commit creates reliquary.creds. The matching unreachable commit, tree, and blob prove that the force-pushed content survived as loose objects even though no current reference reaches it. Reflog or alternate-reference recovery is therefore unnecessary.
Solution
Read the deleted file directly from the orphaned commit and save it without changing the working tree:
bash read-only • copy allowedgit -C crownspire-deploy show \ 3c8803d7146cd07c75325d6b555116200f2569ee:reliquary.creds \ > recovered-reliquary.creds
The recovered credential file contains an AWS_SECRET_ACCESS_KEY value in the expected flag format.
Verification
Verify both the recovered bytes and their Git object identity:
bash read-only • copy allowedshasum -a 256 recovered-reliquary.creds git -C crownspire-deploy hash-object ../recovered-reliquary.creds
Expected output:
text read-only • copy allowed62b22041f38c920b4c39b8c13bd8d20eaa7b19564629c5a8e917c6415389766e recovered-reliquary.creds 12b14971d38c09ee73fed80613951dfdd3562291
The second value equals the unreachable blob reported by git fsck, confirming byte-for-byte recovery from the repository object database.