π OverTheWire Bandit Level 31: Finding Secrets in Git Refs and Packed-Refs
Level 31 builds on Git concepts from previous levels, introducing Git refs and packed-refsβinternal Git files that store references to commits. This level teaches you how to explore the .git directory, understand refs, and find secrets stored in Git references that aren't visible through normal git log commands.
Level 31 teaches you:
- Understanding Git refs
- Exploring the
.gitdirectory - Reading
packed-refsfiles - Using
git showwith commit hashes - Finding secrets in Git references
If you've made it this far, you understand Git commits, history, and branches. Now you're learning about Git's internal structureβanother place where secrets can hide in real-world security assessments.
π― The Objective
After logging into bandit30, your goal is to find the password for Level 31. There's a Git repository at ssh://bandit30-git@localhost/home/bandit30-git/repo. The password for the user bandit30-git is the same as for the user bandit30.
What Level 31 teaches:
- Understanding Git refs
- Exploring
.gitdirectory structure - Reading
packed-refsfiles - Finding secrets in refs
- Why Git internals matter for security
The challenge: The commit history and branches don't show the password. You need to explore the .git directory and check packed-refs to find a reference with "secret" in its name, which contains the password.
π Understanding the Problem
Let's start by connecting to Level 30:
sshpass -p `cat bandit30` ssh bandit30@bandit.labs.overthewire.org -p 2220
Once connected, let's clone the repository:
mkdir -p /tmp/m1k3
cd /tmp/m1k3
git clone ssh://bandit30-git@localhost/home/bandit30-git/repo
cd repo
The problem: When you check commit history and branches, there's no password visible. But Git stores references in the .git directory, and packed-refs might contain additional commits not shown in normal git log output.
π§ Understanding Git Refs and Packed-Refs
Here's what's happening: Git stores references to commits in the .git directory. packed-refs contains additional refs that might not be visible through normal Git commands.
How Git Refs Work
Git refs are pointers to commits:
- Stored in
.git/refs/directory - Can point to branches, tags, or specific commits
- Used by Git to track commits
- Can contain references not visible in
git log
Why this matters:
- Refs might point to hidden commits
- Packed-refs contains additional references
- Secrets might be in refs not shown in branches
- Git internals can reveal hidden information
Understanding the .git Directory
The .git directory contains:
refs/β Branch and tag referencespacked-refsβ Packed references (optimized storage)objects/β Git objects (commits, trees, blobs)configβ Repository configurationHEADβ Current branch pointer
In Level 31: The packed-refs file contains a reference with "secret" in its name that points to a commit with the password.
Understanding packed-refs
packed-refs is an optimization file:
- Contains multiple refs in one file
- Used to reduce filesystem overhead
- Stores refs that aren't in individual files
- Can contain refs not visible in
git branch -a
Format:
# pack-refs with: peeled fully-peeled sorted
<commit-hash> refs/heads/branch-name
<commit-hash> refs/tags/tag-name
<commit-hash> refs/remotes/origin/branch-name
<commit-hash> refs/secret/secret-ref-name
The key: Look for refs with "secret" in the nameβthey might contain the password.
Understanding git show
git show <ref> shows a ref's commit:
- Shows commit details
- Shows file contents
- Works with commit hashes
- Works with ref names
Example:
git show refs/secret/secret-ref
Or with a commit hash:
git show abc123def456...
In Level 31: Use git show on the ref with "secret" in its name to see the commit containing the password.
π Step-by-Step Walkthrough
Step 1: Connect to Level 30
sshpass -p `cat bandit30` ssh bandit30@bandit.labs.overthewire.org -p 2220
Step 2: Get the Password Ready
You'll need the bandit30 password for the Git clone:
cat /etc/bandit_pass/bandit30
Copy this password.
Step 3: Create Temporary Directory and Clone
mkdir -p /tmp/m1k3
cd /tmp/m1k3
git clone ssh://bandit30-git@localhost/home/bandit30-git/repo
cd repo
When prompted, paste the bandit30 password.
Step 4: Check Commit History
Let's check the commit history:
git log
What you'll see: Only a few commits, nothing useful. The password isn't in the visible commits.
Step 5: Check Branches
Let's check what branches are available:
git branch -a
What you'll see: Only 2 branches (likely master and maybe dev).
Step 6: Check Out Branches
Let's check out each branch and see their commits:
git checkout master
git log
git checkout dev # or whatever the other branch is
git log
What you'll see: Still no password in the commits. We need to look deeper.
Step 7: Explore the .git Directory
Let's look at the .git directory structure:
ls -la .git
What you'll see: Various Git internal files and directories.
Step 8: Check packed-refs
The key file for this level is packed-refs:
cat .git/packed-refs
What you'll see:
# pack-refs with: peeled fully-peeled sorted
abc123def456... refs/heads/master
xyz789uvw012... refs/heads/dev
secret123hash... refs/secret/secret-ref-name
The key: There's a ref with "secret" in its name! That's likely where the password is.
Step 9: Show the Secret Ref
Let's use git show on the ref with "secret" in its name:
git show refs/secret/secret-ref-name
Or use the commit hash directly:
git show secret123hash...
What you'll see: The commit details, and the password should be visible in the commit content!
Step 10: Alternative: Search for "secret" in packed-refs
You can also search for "secret" in the packed-refs file:
cat .git/packed-refs | grep secret
This shows the line with the secret ref, then use git show on that ref.
Step 11: Extract the Password
From the git show output, find the password. It might be:
- In the commit message
- In a file shown in the commit
- As the commit hash itself (if it's the password)
The password: Should be visible in the commit shown by git show.
Step 12: Save the Password
Copy the password and save it:
On Linux/macOS:
echo "PASSWORD_HERE" > bandit31
On Windows (PowerShell):
"PASSWORD_HERE" | Out-File -FilePath bandit31 -NoNewline
Step 13: Connect to Level 31
sshpass -p `cat bandit31` ssh bandit31@bandit.labs.overthewire.org -p 2220
π‘ Understanding Git Refs in Depth
Let's dive deeper into Git refs concepts:
Git Ref Structure
Refs are stored in:
.git/refs/heads/β Branch refs.git/refs/tags/β Tag refs.git/refs/remotes/β Remote refs.git/packed-refsβ Packed refs (optimized)
Why packed-refs exists:
- Reduces filesystem overhead
- Faster ref lookups
- Stores refs efficiently
- Can contain refs not in individual files
Understanding Ref Names
Ref names follow patterns:
refs/heads/branch-nameβ Branch refsrefs/tags/tag-nameβ Tag refsrefs/remotes/origin/branch-nameβ Remote refsrefs/secret/secret-nameβ Custom refs (like in Level 31)
In Level 31: The ref with "secret" in its name is a custom ref that points to a commit with the password.
Why Secrets Are in Refs
Common scenarios:
- Secrets stored in custom refs
- Hidden commits referenced by refs
- Refs pointing to old commits with secrets
- Packed-refs containing forgotten refs
Why it's dangerous:
- Refs might not be visible in normal Git commands
- Packed-refs can contain hidden refs
- Custom refs might be forgotten
- Refs can point to commits with secrets
π Real-World Context
Why does this matter in penetration testing?
Git refs and packed-refs are another source of exposed secrets:
1. Finding Secrets in Refs
In real assessments, you might:
- Clone repositories
- Explore
.gitdirectory - Check
packed-refsfile - Look for custom refs
- Extract secrets from refs
The technique: Same as Level 31βexplore .git directory, check packed-refs, look for interesting ref names.
2. Common Ref Security Issues
Secrets in refs:
- Passwords in custom refs
- API keys in tag refs
- Credentials in old branch refs
- Secrets in packed-refs
Why it's dangerous:
- Refs might not be visible in
git log - Packed-refs can contain hidden refs
- Custom refs might be forgotten
- Ref access might be less restricted
3. Real-World Examples
Common scenarios:
- Developer creates custom ref with secret
- Secret stored in tag ref
- Old refs in packed-refs still accessible
- Secrets in refs not shown in branches
The skill you're learning: How to explore Git internals and find secrets in refs. This is essential for:
- Finding exposed credentials
- Understanding repository structure
- Discovering hidden information
- Security auditing
π οΈ Alternative Methods
Here are different ways to approach Level 31:
Method 1: cat packed-refs + git show (Recommended)
cat .git/packed-refs
git show refs/secret/secret-ref-name
Pros: Direct and straightforward Cons: Need to identify the secret ref
Method 2: grep for "secret" in packed-refs
cat .git/packed-refs | grep secret
git show <commit-hash-from-grep>
Pros: Finds secret refs automatically Cons: Might miss if named differently
Method 3: Explore all refs
find .git/refs -type f
cat .git/packed-refs
# Check each ref
Pros: Comprehensive exploration Cons: More time-consuming
Method 4: Use git for-each-ref
git for-each-ref
Pros: Shows all refs in a structured way Cons: Might not show all packed-refs
Method 5: Check .git/refs directory
ls -la .git/refs/
find .git/refs -type f -exec cat {} \;
Pros: Shows individual ref files Cons: Won't show packed-refs
For Level 31, use Method 1 or 2 β they're the most straightforward.
π¨ Common Mistakes
Mistake 1: Only Checking git log
Wrong: Running git log, seeing nothing useful, giving up.
Right: Explore the .git directoryβsecrets might be in refs not shown in git log.
Why: Git refs can point to commits not visible in normal git log output.
Mistake 2: Not Understanding packed-refs
Wrong: Not knowing what packed-refs is or ignoring it.
Right: Understand that packed-refs contains additional refs that might not be visible elsewhere.
Why: Packed-refs is an optimization file that can contain refs not shown in git branch -a.
Mistake 3: Not Looking for "secret" in Ref Names
Wrong: Reading packed-refs but not noticing refs with "secret" in the name.
Right: Look for refs with interesting names like "secret"βthey're often hints in CTF levels.
Why: CTF levels often use descriptive names. "Secret" in a ref name is a clear hint.
Mistake 4: Not Using git show on Refs
Wrong: Finding a ref but not knowing how to view its contents.
Right: Use git show <ref> or git show <commit-hash> to view the commit.
Why: Refs point to commits. You need git show to see what's in those commits.
Mistake 5: Not Exploring .git Directory
Wrong: Only using high-level Git commands, never exploring .git directory.
Right: Understand that .git contains all Git internals, including refs that might contain secrets.
Why: Git internals can reveal information not visible through normal commands. Security assessments require exploring internals.
π» Practice Exercise
Try these to reinforce what you learned:
-
Explore .git directory:
ls -la .git ls -la .git/refs -
Check packed-refs:
cat .git/packed-refs -
View refs:
git for-each-ref git show-ref -
Show specific refs:
git show refs/heads/master git show <commit-hash>
π Understanding Git Internals Security
This level introduces Git internals security concepts:
Why Git Internals Matter
Security implications:
- Secrets might be in refs not visible in
git log - Packed-refs can contain hidden refs
- Custom refs might be forgotten
- Git internals can reveal hidden information
Best Practices
To avoid exposing secrets:
- Never store secrets in any Git refs
- Review all refs, not just branches
- Check
packed-refsfor hidden refs - Use
.gitignorefor sensitive files
If secrets are in refs:
- Rotate all exposed credentials immediately
- Consider all refs as potentially compromised
- May need to remove or update refs
- Review repository access controls
The skill you're learning: How to explore Git internals and find secrets in refs. This is essential for:
- Security auditing
- Penetration testing
- Understanding version control security
- Finding exposed credentials
π What's Next?
Level 32 will likely introduce new concepts or build on Git further. The pattern suggests we'll continue learning about Git or move to new topics.
Before moving on, make sure you:
- β Understand Git refs
- β
Can explore
.gitdirectory - β
Can read
packed-refsfiles - β
Can use
git showwith refs - β Know why Git internals matter for security
π Key Takeaways
After completing Level 31, you should understand:
- Git refs β Pointers to commits stored in
.gitdirectory - packed-refs β Optimized file containing multiple refs
- Git internals β How Git stores references internally
- Exploring .git β Why exploring Git internals matters
- Security implications β Why refs can contain secrets
π― Quick Reference
| Concept | Explanation | Example |
|---|---|---|
| Git refs | Pointers to commits | refs/heads/master |
| packed-refs | Optimized ref storage | .git/packed-refs |
| git show | Show ref/commit contents | git show refs/secret/secret-ref |
| .git directory | Git internals | .git/refs/, .git/packed-refs |
| Custom refs | User-defined refs | refs/secret/secret-name |
π Advanced: Understanding Git Internals
If you want to go deeper, here's Git internals:
Git Object Model
Git stores:
- Commits β Snapshots with metadata
- Trees β Directory structures
- Blobs β File contents
- Refs β Pointers to commits
Why it matters:
- Understanding internals helps find secrets
- Objects are stored in
.git/objects/ - Refs point to commits
- Everything is accessible if you know where to look
Finding Secrets in Git Internals
Techniques:
- Explore
.gitdirectory structure - Check
packed-refsfor hidden refs - Look for custom refs
- Search for keywords in refs
- Use
git showon interesting refs
In Level 31: The password was in a ref with "secret" in its name. Checking packed-refs revealed the ref, and git show revealed the commit with the password.
Questions about Level 31, Git refs, or Git internals security? Reach out directly:
- Email: m1k3@msquarellc.net
- Phone: (559) 670-3159
- Schedule: Book a free consultation
M Square LLC
Cybersecurity | Penetration Testing | No-Nonsense Advice