Skip to main content
🧠Educationalintermediate13 min read
β€’

OverTheWire Bandit Level 31: Finding Secrets in Git Refs and Packed-Refs

OverTheWire Bandit Level 31 walkthrough. Learn about Git refs, packed-refs files, and how Git stores references to commits that might contain secrets not visible in normal git log output.

OverTheWireBanditLinuxGitgit refspacked-refsgit showintermediateCTF

πŸ”— 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 .git directory
  • Reading packed-refs files
  • Using git show with 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 .git directory structure
  • Reading packed-refs files
  • 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 references
  • packed-refs β€” Packed references (optimized storage)
  • objects/ β€” Git objects (commits, trees, blobs)
  • config β€” Repository configuration
  • HEAD β€” 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 refs
  • refs/tags/tag-name β€” Tag refs
  • refs/remotes/origin/branch-name β€” Remote refs
  • refs/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 .git directory
  • Check packed-refs file
  • 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:

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:

  1. Explore .git directory:

    ls -la .git
    ls -la .git/refs
    
  2. Check packed-refs:

    cat .git/packed-refs
    
  3. View refs:

    git for-each-ref
    git show-ref
    
  4. 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-refs for hidden refs
  • Use .gitignore for 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 .git directory
  • βœ… Can read packed-refs files
  • βœ… Can use git show with refs
  • βœ… Know why Git internals matter for security

πŸ“š Key Takeaways

After completing Level 31, you should understand:

  1. Git refs β€” Pointers to commits stored in .git directory
  2. packed-refs β€” Optimized file containing multiple refs
  3. Git internals β€” How Git stores references internally
  4. Exploring .git β€” Why exploring Git internals matters
  5. Security implications β€” Why refs can contain secrets

🎯 Quick Reference

ConceptExplanationExample
Git refsPointers to commitsrefs/heads/master
packed-refsOptimized ref storage.git/packed-refs
git showShow ref/commit contentsgit show refs/secret/secret-ref
.git directoryGit internals.git/refs/, .git/packed-refs
Custom refsUser-defined refsrefs/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 .git directory structure
  • Check packed-refs for hidden refs
  • Look for custom refs
  • Search for keywords in refs
  • Use git show on 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:


M Square LLC
Cybersecurity | Penetration Testing | No-Nonsense Advice

Found this helpful? Share it:

Need Help With This?

Have questions about implementing these security practices? Let's discuss your specific needs.

Get in Touch

More in Educational

Explore more articles in this category.

Browse 🧠 Educational

Related Articles