Alias: Remote-Code-Execution-as-a-Service / RCEaaS
CTF-Challenge for ENOWARS 3 based on Python, Flask and Gunicorn.
The service allows to create "recipes" of en-/decoding steps to manipulate multiple inputs in the same way. The idea is inspired by CyberChef.
-
Operations are taken from string parameters and are blindly executed: The line
recipe.ingredients.append(getattr(globals()[ingredient], method))
(seeservice/cyber-alchemist/app.py
:164) searches foringredient
inglobals()
, gets the attributemethod
from it and appends the reference to the function to ingredients. This way, not only the intended ingredients can be executed, but all functions from all objects available in the scope of the app. -
Recipes can be imported as pickle files. Pickle has known security issues with unserializing untrusted input.
All exploits are also implemented in checker/checker.py
.
Predict the output of the pseudorandom number generator:
- Call
/recipe/<recipe_name>/random/getstate
to get the random state of the pseudorandom number generator in the potion field. - In the python exploit, create an own
r = random.Random()
object and setr.setstate(<random_state>)
to the state you obtained from the recipe's potion field. - Execute
recipe_name = ''.join(r.choice(ascii_letters) for i in range(r.randint(20,40)))
(as often as you want) to predict future recipe names the server will generate.
Include arbitrary functions in ingredients (even from packages which are not imported in app.py
):
- Craft malicious recipes by copying the app's recipe class and include arbitrary functions in ingredients, e.g.
subprocess.check_output
. - Import the recipe
- Show the recipe and see the result in the potion field
- Craft malicious pickle file (google "pickle RCE")
- Import file
- You get banned, so you have to pipe the results of your code execution to a file which is publicly available, e.g. in
static
.
The service directory contains all source files needed to run CyberAlchemist.
http://localhost:8787 / http://[::1]:8787
cd service
docker-compose up -d
cd service/cyber-alchemist
FLASK_APP=app.py FLASK_DEBUG=1 python3 -m flask run
The checker puts flags in all the team's vulnboxes, tests if they can be retrieved afterwards, and checks all other important functionality of the service. Additionally, it contains an exploit function to test, whether the intended exploits are possible (only during testing, not during the actual ctf).
Run with -h
to get the output.
Checkout the branch local
docker-compose up
Access http://[::1]:7878/
python3 checker.py listen 666
http://localhost:666/
{
"method":"putflag",
"address": "localhost"
}
{
"method":"getflag",
"address": "localhost"
}
We want to test the "live" configuration therefore we want to access the service container from "outside" through the exposed port 8787
. Checker and service are running on the docker host and are accessible through the host gateway. Use docker inspect *service_container_id*
to get the IP of the gateway. Use the IP as address (instead of "gunicorn") in the checker web interface.
{
"method": "putflag",
"address": "gunicorn"
}
docker network create checkernet --ipv6 --subnet fd00:1337:0:cecc::/64 --gateway fd00:1337:0:cecc::ffff
docker-compose up -d