Skip to content

Commit

Permalink
fix(__init__.py): fix incorrect path handling #21
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
WangYihang committed Jan 31, 2022
1 parent e22d81f commit f97710c
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions GitHacker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,9 @@ def start(self):
threading.Thread(target=self.worker, daemon=True).start()

if self.directory_listing_enabled():
self.sighted()
return self.sighted()
else:
self.blind()

return True
return self.blind()

def directory_listing_enabled(self):
response = requests.get("{}{}".format(self.url, ".git/"), verify=self.verify)
Expand All @@ -69,7 +67,7 @@ def directory_listing_enabled(self):
def sighted(self):
self.add_folder(self.url, ".git/")
self.q.join()
self.git_clone()
return self.git_clone()

def add_folder(self, base_url, folder):
url = "{}{}".format(base_url, folder)
Expand Down Expand Up @@ -117,7 +115,7 @@ def blind(self):
else:
break

self.git_clone()
return self.git_clone()

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


def add_hashes_parsed(self, content):
Expand Down Expand Up @@ -276,11 +279,14 @@ def check_file_content(self, content):

def wget(self, url, path):
response = requests.get(url, verify=self.verify)
if ".." in path:
logging.error(f"Malicious repo detected: {url}")
sanitized_path = path.replace("..", "")
logging.warning(f"Replacing {path} with {sanitized_path}")
path = sanitized_path
folder = os.path.dirname(path)
try:
os.makedirs(folder)
except:
pass
try: os.makedirs(folder)
except: pass
status_code = response.status_code
content = response.content
result = False
Expand Down

0 comments on commit f97710c

Please sign in to comment.