top of page
BlueDolphin

DownUnderCTF - Web - Python Prototype Pollution

Updated: Aug 14

I did not solve this challenge during the CTF, so I put some content together to understand how it was solved.


YouTube Writeup

Visual workflow
Summary

This challenge demonstrates a classic prototype pollution vulnerability. By understanding how the merge function works we can exploit it to inject malicious properties into the global scope. The key take away is the emphasis on securely handling user input and being cautious about functions that dynamically merge or copy attributes as they can be vectors of attack.


Technical Workflow Summary
  1. Website Enumeration

  2. Feedback Form Request Inspection and JSON Data

  3. Source Code Analysis, utils.py and routes.py

  4. Identify Prototype Pollution Vulnerability Via Merging Process

  5. Craft Payload with class, init, global and flag.

  6. Exploit and receive flag

References

Challenge Description

Website Enumeration

Initially viewing the website reveals very little. With the ability to interact with the register and login functions, we are forced to register an account as our attack surface is lacking otherwise.


We can see that some new menu options appear, dashboard and feedback. The dashboard area just shows existing blog posts. The feedback form however can be interacted with and thus represents our attack surface.


Taking a look at the feedback form doesn't tell us much beyond the fact that our submissions are stored forever which is suggestive to me that we don't have to worry about a race or timing condition.


Bupring the request we see that our feedback is sent as JSON data to the save_feedback endoint.

Source Code Analysis

routes.py helps us understand the flag is stored as an environment variable and can be retrieved via route with /get_flag if the users flag environment variable is set to true. The feedback form is actually storing the user data.


utils.py reveals that the merge function is responsible for copying attributes from the src to destination opbject. The merge function recursively merges dictionaries, updating the destination object with values from the source.


routes.py - 1/3: Reveals the flag is stored as an environment variable.


routes.py - 2/3: Reveals the flag can be access from the /get_flag endpoint, however the flag variable has to return true. The get_flag function relies on the flag global variable.








routes.py - 3/3: reveals that we want to grab user input via the feedback form and save it as an attribute, and suggesting language that attributes can be created on the fly through the merge function which is responsible for the saving and creation of the new attributes.


utils.py 1/1: reveals that the merge function is responsible for copying attributes from the src to destination object. The merge function recursively merges dictionaries, updating the destination object with values from the source.


Vulnerability Identification

The vulnerability here is prototype pollution. This occurs when an attacker manipulates the structure of an object by injecting properties that affect the entire prototype chain which effects the behavior of a program.


The prototype chain is a workflow that lets objects inherit properties from other objects. Every object can have only one prototype object from which it may inherit properties from. Each object prototype can have its own prototype, creating a chain of inheritance.


Prototype Analogy: The Hotel Registry

Imagine a hotel with a digital registry system where guests can enter their details when they check in. The hostel has a default template for each guests details, etc name, room number, special requests. The system automatically merges these details into the guests profile.


The merging process.


  1. The hostel has a default template for guests.

    1. Name: Guests

    2. room: Not assigned

    3. Special requests: unknown

  2. When a guest checks in, they provide their details

    1. Name: Bob

    2. room: 5

    3. Special requests: unknown

      1. extra_towels: true

  3. The system merges the default template with the guests input creating a profile for bob. This results due to lack of user input sanitization.

  4. Malicious input can be padded that affects the hotels entire system.

    1. Name: Bob

    2. room: 5

    3. Special requests: unknown

      1. extra_towels: true __System_{ fire_alarm: false }

  5. Merging the malicious input:

    1. The system now merges the input like it does for all the guests, however system is called and an environment variable for fire_alarm is now false either for the backend user calling the process, or possible the entire hotel.

Building the Payload


  1. Identifying the get_flag function:

    1. There is a get_flag function we have observed above, that checks if the value of flag which is defined as an environment variable is set to "true", and returns the flag if so. The value of the flag is not directly controllable, but is controlled through a class pollution vulnerability.

  2. Crafting a payload

    1. Below is our default json data that is rendered from the feedback form, this is where we will build our payload. { "title":"aaa", "content":"aaaa", "rating":"5", "referred":"dsag" }

    2. __class_

      1. Purpose: Access the class of object "feedback_obj"

      2. Use Case: Can be used to manipulate the class "Feedback"

    3. __init_

      1. Purpose: The initializer method for a class.

      2. Use Case: Use to modify application behaviour during object creation.

    4. __globals_

      1. Purpose: Access global variable flag within the context.

      2. Use Case: This lets us manipulate the global flag variable to true

    5. The payload is constructed as follows:



Exploitation Phase

Here we burp the request and enter our payload, and we see the response from the server shows as true.



We then attempt a request to the /get_flag endpoint where we discover our flagf.


END



39 views0 comments

Recent Posts

See All

Comments


bottom of page