Hack. Eat. Sleep. Repeat!!!
The web app is vulnerable to path traversal which involves using the dot-dot slash characters to read a file.The route download
contains
the sink code.
@app.route('/download/<path:file_id>')
def download(file_id):
file_id = filter_file_id(file_id)
if file_id is None:
return {'status': 'error', 'message': 'Invalid file id'}, 400
if not os.path.exists('uploads/' + file_id):
return {'status': 'error', 'message': 'File not found'}, 404
if not os.path.isfile('uploads/' + file_id):
return {'status': 'error', 'message': 'Invalid file id'}, 400
return send_file('uploads/' + file_id, download_name=f"{file_id}.{file_exts.get(file_id, 'UNK')}")
The send_file()
function is vulnerable to path traversal if the file value can be controlled by an attacker.The download
route in this case
passes the file_id
path variable into send file.We can control the path to read the flag file.
return send_file('uploads/' + file_id, download_name=f"{file_id}.{file_exts.get(file_id, 'UNK')}")
../
in a request without interpreting it with the --path-as-is
option and read the file /etc/passwd
.bctf{4lw4y5_35c4p3_ur_p4th5}