> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

DVCS-Pillage: The Security Tool That Exposes Your Forgotten .git Directories

[ View on GitHub ]

DVCS-Pillage: The Security Tool That Exposes Your Forgotten .git Directories

Hook

Every year, developers accidentally deploy .git directories to production servers, exposing API keys, database credentials, and proprietary source code to anyone who knows how to ask for it. DVCS-Pillage is the shell script that does exactly that.

Context

In the early 2010s, as Git and distributed version control systems gained widespread adoption, a troubling pattern emerged: developers were routinely deploying their entire version control history to production web servers. Unlike centralized systems where the repository lived on a remote server, DVCS systems like Git, Mercurial, and Bazaar store complete repository data in local directories (.git, .hg, .bzr). When developers used simple deployment methods like FTP uploads or rsync without proper exclusions, these directories came along for the ride.

The security implications were severe. A .git directory doesn't just contain current source code—it holds every commit, every deleted file, every secret that was ever committed and later removed. Even if direct directory listing was disabled, the predictable structure of Git's object database meant that attackers could systematically reconstruct entire repositories using nothing but HTTP requests. DVCS-Pillage, created by security researcher Adam Baldwin (evilpacket), emerged as a proof-of-concept tool that automated this exploitation, forcing the development community to confront an uncomfortable truth: deployment wasn't as simple as copying files anymore.

Technical Insight

DVCS-Pillage works by exploiting the deterministic file structure within Git repositories. When you initialize a Git repository, it creates a .git directory with predictable subdirectories: objects, refs, logs, and configuration files. The brilliance of this tool lies in its methodical approach to reconstructing repositories even when standard cloning is impossible.

The attack begins with reconnaissance. The script first attempts to download known files that exist in every Git repository: .git/HEAD, .git/config, and .git/index. If these succeed, the tool knows it has found an exposed repository. Here's the core logic from the original gitpillage.sh that demonstrates this approach:

#!/bin/bash
BASE_URL=$1
OUTPUT_DIR=$2

# Download known Git files
wget --no-check-certificate $BASE_URL/.git/HEAD -O $OUTPUT_DIR/.git/HEAD
wget --no-check-certificate $BASE_URL/.git/config -O $OUTPUT_DIR/.git/config
wget --no-check-certificate $BASE_URL/.git/index -O $OUTPUT_DIR/.git/index

# Extract object hashes from the index file
git ls-files --stage $OUTPUT_DIR | awk '{print $2}' | while read hash; do
    # Calculate directory and file structure from hash
    dir=${hash:0:2}
    file=${hash:2}
    mkdir -p $OUTPUT_DIR/.git/objects/$dir
    wget --no-check-certificate \
        $BASE_URL/.git/objects/$dir/$file \
        -O $OUTPUT_DIR/.git/objects/$dir/$file
done

The index file is particularly valuable because it contains SHA-1 hashes of every blob in the current working tree. Git stores objects using a two-tier directory structure: the first two characters of the SHA-1 hash become a directory name, and the remaining 38 characters become the filename. For example, an object with hash a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 would be stored at .git/objects/a9/4a8fe5ccb19ba61c4c0873d391e987982fbbd3.

Once the tool has downloaded these initial objects, it enters a recursive discovery phase. Git commits contain pointers to tree objects, which contain pointers to more trees and blobs. By parsing these objects (which are zlib-compressed but otherwise readable), the script can discover and download the entire object graph:

# Extract commit hashes from refs
for ref in $(find $OUTPUT_DIR/.git/refs -type f); do
    commit=$(cat $ref)
    dir=${commit:0:2}
    file=${commit:2}
    wget --no-check-certificate \
        $BASE_URL/.git/objects/$dir/$file \
        -O $OUTPUT_DIR/.git/objects/$dir/$file
    
    # Parse commit object to find tree and parent commits
    git cat-file -p $commit | grep '^tree\|^parent' | \
        awk '{print $2}' | while read obj; do
        # Recursively download referenced objects
        download_object $obj
    done
done

The tool also attempts to download pack files, which are compressed collections of objects that Git creates for efficiency. These are gold mines for attackers because they contain multiple objects in a single download, significantly speeding up the extraction process.

What makes this approach particularly devastating is that it works even with aggressive caching, CDNs, and reverse proxies. As long as the web server serves static files from the .git directory—and many do by default—the attack succeeds. The tool requires no authentication, no special permissions, and no exploitation of software vulnerabilities. It simply leverages the documented, intentional structure of Git repositories against developers who didn't realize they were publishing them.

The shell-based implementation is both a strength and a limitation. Using only bash, wget, and standard Git commands makes the tool incredibly portable—it runs on any Unix-like system without additional dependencies. This was crucial for penetration testing scenarios where you couldn't install Python libraries or Ruby gems. However, the reliance on shell scripting also means the tool lacks sophisticated error handling and retry logic that modern Python-based alternatives provide.

Gotcha

DVCS-Pillage hasn't been updated since 2011, and Git has evolved significantly since then. Modern Git repositories may use features like protocol v2, sparse checkouts, or alternative hash functions (SHA-256) that the tool doesn't understand. More critically, the tool's wget-based approach struggles with rate limiting, connection timeouts, and modern web application firewalls. If a server implements even basic anti-scraping measures or requires authentication tokens in headers, DVCS-Pillage will fail silently or only partially extract the repository.

The tool also operates under the assumption that the web server allows access to all files within .git, but modern frameworks and web servers have gotten smarter. Nginx, Apache, and application frameworks like Next.js, Django, and Rails now commonly include default configurations that explicitly deny access to dotfiles and dot-directories. Cloud platforms like Vercel, Netlify, and AWS Amplify automatically exclude version control directories from deployments. This means that while the vulnerability DVCS-Pillage exploits is still very real—HackerOne reports dozens of exposed .git directories annually—the attack surface has shrunk considerably compared to 2011. You're more likely to find this vulnerability on legacy systems, custom-built deployments, or projects maintained by teams without strong DevOps practices.

Verdict

Use if: You're conducting authorized penetration tests or security audits and need a lightweight, dependency-free tool that demonstrates the risks of exposed version control directories. It's particularly valuable in restricted environments where you can't install modern Python tools, or when you want to understand the fundamental mechanics of Git object exploitation without abstractions. DVCS-Pillage also serves as an excellent educational tool for teaching developers why proper .gitignore configuration and deployment practices matter—seeing how easily their repository can be reconstructed drives the point home viscerally. Skip if: You need a tool for active security research against modern web applications, as the dated implementation will miss edge cases and fail against contemporary defenses. Instead, use dvcs-ripper or git-dumper, which handle modern Git features, implement better retry logic, and are actively maintained. Also skip this if you're looking for legitimate repository management utilities—despite the name, this is strictly a security tool. Finally, skip this entirely if you don't have explicit written authorization to test the target system; unauthorized use is illegal and unethical, regardless of how simple the tool makes the exploitation.