# Git Repository Exploitation

> Exploit exposed .git directories to reconstruct source code, extract credentials, and uncover sensitive application logic from misconfigured web servers.

- **URL:** https://hackindex.io/services/web/exploitation/git-repository-exploitation
- **Path:** HTTP/HTTPS > Exploitation
- **Up:** [Exploitation](https://hackindex.io/services/web/exploitation.md)
- **Published:** 2026-03-28
- **Updated:** 2026-05-15

An exposed .git directory confirmed in [vulnerability discovery](https://hackindex.io/services/web/vulnerability-discovery/check-exposed-git-directory) allows reconstructing the full repository from the web server. This recovers complete application source code, all historical commits including deleted files, hardcoded credentials, and API keys that may no longer appear in the current codebase. The most valuable finds are often not in the current checkout. Developers rotate credentials after a breach but rarely rewrite git history. Old commits frequently contain database passwords, cloud provider keys, and internal service tokens that still work. Config management transitions leave traces. An application that moved from hardcoded values to environment variables will have a commit marking the change. The old values sit in the diff directly above it.

After dumping a git repository, focus on these high-value targets:

- `.env` files with database passwords, API keys, and app secrets
- Configuration files (`config.php`, `settings.py`, YAML configs) with hardcoded credentials
- Deleted commits containing rotated secrets that may still be valid
- SSH private keys and cloud provider tokens in the commit history
- Remote URLs in `.git/config` pointing to other private repositories

Once you have the source code, apply [source code review methodology](https://hackindex.io/services/web/exploitation/source-code-review-methodology) to find vulnerabilities through sink-to-source tracing.

## Dump the Repository with git-dumper

git-dumper reconstructs the full git repository from an exposed .git directory. It handles missing directory listings by inferring object hashes from the git pack index. The tool works even when web server directory listing is disabled. A successful dump ends with `git checkout .` restoring the working tree from the object store. If the dump fails partway through, re-run the same command. git-dumper resumes from what it already fetched. If object requests return 403 after the initial HEAD check passes, a WAF is blocking selective path requests. Lower concurrency with `--threads 1` to reduce the request rate:

```bash
pipx install git-dumper
```

```bash
git-dumper http://$TARGET_IP:$PORT/.git /tmp/git_dump
# [+] Testing http://10.10.10.50/.git/HEAD [200]
# [+] Fetching .git/
# [+] Running git checkout .
```

```bash
ls -la /tmp/git_dump/
# total 28
# drwxr-xr-x  3 www-data www-data 4096 Mar 15 14:22 .
# drwxr-xr-x 12 user     user     4096 Mar 15 14:22 ..
# drwxr-xr-x  8 www-data www-data 4096 Mar 15 14:22 .git
# -rw-r--r--  1 www-data www-data  342 Mar 15 14:22 .env
# -rw-r--r--  1 www-data www-data 2847 Mar 15 14:22 config.php
# -rw-r--r--  1 www-data www-data 1204 Mar 15 14:22 index.php
```

## Extract Credentials from Source

Search the dumped source for credentials, API keys, and connection strings. The `.env` file is the highest-priority target. Laravel, Django, Rails, and most modern frameworks store all sensitive configuration there. `config.php`, `settings.py`, and YAML configuration files are common secondary locations. When you find a database password, test it against any exposed database port on the target. When you find an API key, identify the service from context and test access. Cloud provider keys often carry broad permissions because developers give themselves admin access during development and rarely rotate before shipping. Check `package.json` or `requirements.txt` to identify what third-party services the app integrates with. That tells you which keys matter most to pursue.

```bash
grep -rn --include='*.php' --include='*.env' --include='*.py' --include='*.js' --include='*.yml' -iE 'password|passwd|secret|api_key|apikey|token|db_pass|database_password' /tmp/git_dump/
# /tmp/git_dump/.env:DB_PASSWORD=SuperSecret123!
# /tmp/git_dump/config.php:$db_pass = 'admin123';
```

```bash
cat /tmp/git_dump/.env
```

## Mine Commit History for Deleted Secrets

Credentials removed from the current codebase often remain in commit history. Search all commits for sensitive patterns. Commit messages are a useful signal before diving into diffs. A message like "Fix security issue - removed hardcoded credentials" points at the exact commit you want. Check the commit immediately before it. The removed credential appears as an added line in that earlier commit. `git show` on the target commit reveals the full file at that point in time. Pay attention to branch names from `git log --all`. Development and staging branches often diverge from main with less scrutiny. A `dev` or `feature/` branch may contain credentials that were never merged to main.

```bash
cd /tmp/git_dump && git log --all --oneline
# a1b2c3d Fix security issue - removed hardcoded credentials
# b4c5d6e Initial commit with working config
```

```bash
cd /tmp/git_dump && git show b4c5d6e:config.php | grep -iE 'password|secret|key'
# $db_password = 'OldPassword!2023';
```

```bash
cd /tmp/git_dump && git log -p --all | grep -iE '\+.*password|\+.*secret|\+.*api_key' | head -30
```

## trufflehog for Automated Secret Mining

trufflehog scans all commits for high-entropy strings and known secret patterns automatically. It uses regex detectors for over 700 secret types including AWS keys, GitHub tokens, and Stripe keys. High-entropy detection catches generic secrets that do not match a known pattern. Use filesystem mode on the dumped repo to scan both the working tree and full git history. trufflehog validates many secret types against their respective APIs to confirm active credentials. An unverified result still warrants investigation. Parse the JSON output and look for `SourceMetadata` to find the exact file and commit where each secret appeared. If output volume is high, filter for `"Verified": true` first to prioritize confirmed active credentials before reviewing unverified hits.

```bash
trufflehog filesystem /tmp/git_dump/ --json 2>/dev/null | python3 -m json.tool | grep -A5 'reason\|stringsFound'
```

Take found credentials to the relevant service page for the next step. A database password goes to MySQL, PostgreSQL, or MSSQL exploitation depending on what `.env` reveals. Cloud keys go directly to the provider CLI. SSH private keys found in the repository allow direct access to any host they were provisioned for. Check `.git/config` for the remote URL. GitHub, GitLab, or Bitbucket tokens may grant access to other private repositories in the same organization. If credentials from history no longer work, try them on other services on the target. Password reuse between database credentials and system user accounts is common.

## References

- [git-dumper](https://github.com/arthaud/git-dumper) - Repository reconstruction from exposed .git directories
- [trufflehog](https://github.com/trufflesecurity/trufflehog) - Secret scanning across git history and filesystem
