Skip to content

Commit f97710c

Browse files
committed
fix(__init__.py): fix incorrect path handling #21
When GitHacker meets Apache/Nginx with folder Indexes enabled, it will recursively download `.git` folder. GitHacker incorrectly trust the hyperlink from the Apache/Nginx, that allows to write arbitrary content into arbitrary file on the GitHacker users machine. This issue is reported by Justin Steven <https://twitter.com/justinsteven>. Thanks a lot for his excellent work and his responsible disclosure.
1 parent e22d81f commit f97710c

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

GitHacker/__init__.py

+17-11
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,9 @@ def start(self):
4646
threading.Thread(target=self.worker, daemon=True).start()
4747

4848
if self.directory_listing_enabled():
49-
self.sighted()
49+
return self.sighted()
5050
else:
51-
self.blind()
52-
53-
return True
51+
return self.blind()
5452

5553
def directory_listing_enabled(self):
5654
response = requests.get("{}{}".format(self.url, ".git/"), verify=self.verify)
@@ -69,7 +67,7 @@ def directory_listing_enabled(self):
6967
def sighted(self):
7068
self.add_folder(self.url, ".git/")
7169
self.q.join()
72-
self.git_clone()
70+
return self.git_clone()
7371

7472
def add_folder(self, base_url, folder):
7573
url = "{}{}".format(base_url, folder)
@@ -117,7 +115,7 @@ def blind(self):
117115
else:
118116
break
119117

120-
self.git_clone()
118+
return self.git_clone()
121119

122120
def git_clone(self):
123121
logging.info("Cloning downloaded repo from {} to {}".format(self.dst, self.real_dst))
@@ -126,13 +124,18 @@ def git_clone(self):
126124
stdout=subprocess.PIPE,
127125
stderr=subprocess.PIPE,
128126
)
127+
if result.stdout != b'': logging.info(result.stdout.decode("utf-8").strip())
128+
if result.stderr != b'': logging.error(result.stderr.decode("utf-8").strip())
129129
if b"invalid path" in result.stderr:
130130
logging.info("Remote repo is downloaded into {}".format(self.real_dst))
131131
logging.error("Be careful to checkout the source code, cause the target repo may be a honey pot.")
132132
logging.error("FYI: https://drivertom.blogspot.com/2021/08/git.html")
133-
else:
133+
if result.returncode == 0:
134+
# return True only when `git clone` successfully executed
134135
logging.info("Check it out: {}".format(self.real_dst))
135136
shutil.rmtree(self.dst)
137+
return True
138+
return False
136139

137140

138141
def add_hashes_parsed(self, content):
@@ -276,11 +279,14 @@ def check_file_content(self, content):
276279

277280
def wget(self, url, path):
278281
response = requests.get(url, verify=self.verify)
282+
if ".." in path:
283+
logging.error(f"Malicious repo detected: {url}")
284+
sanitized_path = path.replace("..", "")
285+
logging.warning(f"Replacing {path} with {sanitized_path}")
286+
path = sanitized_path
279287
folder = os.path.dirname(path)
280-
try:
281-
os.makedirs(folder)
282-
except:
283-
pass
288+
try: os.makedirs(folder)
289+
except: pass
284290
status_code = response.status_code
285291
content = response.content
286292
result = False

0 commit comments

Comments
 (0)