BuckeyeCTF2024 web/homecooked
My solution for BuckeyeCTF2024 web/homecooked challenge
Challenge overview
The Homecooked challenge is a web application which uses a unique templating engine named Meal. The target endpoint is /chef, where users can interact with the Chef Creator, an online IDE that facilitates writing Meal templates. These templates are rendered on the server side using the Meal templating engine, and the application fails to properly sanitize the input, leading to security vulnerabilities.
Application structure
- Meal is a templating language used within the framework that relies on emojis for control structures, making it similar to Jinja2 in concept but visually distinct.
- The Chef module is implemented as a sub-router, responsible for handling file uploads, processing Meal templates, and rendering them back to users.
Analysis
Upon examining the Chef functionality, a few critical features stand out:
Meal template processing: When a user uploads a Meal template through the
/upload
endpoint, it is saved to a temporary directory. The/download/{filename}
endpoint retrieves this file and renders it usingTemplateResponse.from_string()
, which means the Meal engine processes the content directly.Meal templating engine: This custom engine interprets Meal templates, which are similar to other templating languages but replace common operators and syntax with emojis (e.g., π΄, π₯’).
The Meal interpreter lacks sufficient sandboxing, allowing templates to access Python internals. By abusing certain special attributes, an attacker can access built-in classes and execute arbitrary commands.
Identifying the vulnerabilities
Improper restriction on built-ins The Meal templating engine allows templates to access
class
andsubclasses()
attributes. These attributes are extremely powerful, as they can be used to list all subclasses of an object, including sensitive system-related classes.Use of
from_string()
in template rendering The rendering function,TemplateResponse.from_string()
, does not provide sufficient input validation or context isolation, leading to a scenario where user-supplied content can execute arbitrary Python code.
Crafting the exploit
Accessing subclasses
To exploit the vulnerability, the first step was to list all subclasses of Pythonβs base object, using the following payload:
1
2
3
π΄π idx π rangeπ¦lenπ¦''π₯__class__π₯__base__π₯__subclasses__π¦π¦π¦π¦ π₯
π₯’ idx π₯’ : π₯’ ''π₯__class__π₯__base__π₯__subclasses__π¦π¦πidxππ₯__name__ π₯’<br>
π₯π΄
This payload iterates over all subclasses and outputs their names, helping identify classes that could be leveraged for arbitrary code execution.
Reading sensitive files
The exploit proceeds to identify the MealManager class (at index 555), which exposes access to globals
Using this, the attacker can access Python built-ins and open files:
1
π₯’ ''π₯__class__π₯__base__π₯__subclasses__π¦π¦π555ππ₯__init__π₯__globals__π'__builtins__'ππ'open'ππ¦'/flag.txt'π¦π₯readπ¦π¦ π₯’
This payload successfully reads the content of /flag.txt
, demonstrating an arbitrary file read vulnerability.
Flag:bctf{m4yb3_i_5h0uld_t3st_n3w_f34tur35}
Conclusion
The challenge exploits weaknesses in the custom Meal templating engine. The lack of proper sandboxing in the templating engine allows malicious users to access dangerous Python attributes and execute arbitrary code, ultimately leading to the exposure of sensitive files.
Key takeaways
- Sandboxing matters: When building a custom template engine, it is crucial to restrict access to Pythonβs internal methods and attributes. Proper sandboxing can prevent attackers from escalating privileges or gaining access to sensitive objects.
- Input validation and restriction: Avoid exposing dangerous functionality, such as the ability to directly access special attributes or the global namespace, when processing user inputs.
- Template rendering caution: Be careful when using
from_string()
or similar methods that execute code based on user input. Always sanitize inputs to ensure they cannot execute unintended commands.