Featured image of post Security Panel - DOJO n°32

Security Panel - DOJO n°32

📜 Description

During a security test, you discovered an unusual administration panel that appears to allow modification of the server’s security settings. Could it also provide a way to obtain a flag?

~ The flag can be found in the file: /tmp/flag.txt.

This Python program takes a JSON input and adds this input to the config.json file or replaces a value if it already exists in the config.json file.

Case 1: If the attribute already exists in config.json, its value will be updated. Payload : {"encryption_level":"owned"}

Case 2: If the attribute does not exist, it will be added to the end of config.json. Payload : {"owne":"owned"}

This is achieved through the merge_config() function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#merge two configuration files
def merge_config(src, dst):
    for key, value in src.items():
        if hasattr(dst, '__getitem__'):
            if dst.get(key) and isinstance(value, dict):
                merge_config(value, dst.get(key))
            else:
                dst[key] = value
        elif hasattr(dst, key) and isinstance(value, dict):
            merge_config(value, getattr(dst, key))
        else:
            setattr(dst, key, value)

🕵️ Proof of Concept

After some research, it was found that the setattr() function is vulnerable to class pollution (similar to prototype pollution in JavaScript). This class pollution would allow us to redefine global variables. https://book.hacktricks.xyz/generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution

In Python, we can access global variables of a program from a string using "".__class__.__init__.__globals__.<global-variable>.

We can see that the program executes os.popen(COMMAND).read(), with COMMAND being a global variable. If we can redefine COMMAND, then we could execute any command.

"".__class__.__init__.__globals__.COMMAND can redefine COMMAND.

If we send : {"__class__":{"__init__":{"__globals__":{"COMMAND":"cat /tmp/flag.txt"}}}}

The server will then execute os.popen('cat flag.txt').read()

Thanks nishacid for this challenge !

🚧 Impacts

A remote code execution could allow an attacker to :

Execute OS commands. Read/Edit/Delete files. Steal secrets. Server takeover. Perform malicious tasks from the victim server. Perform scan on the internal network. …

🔐 Mitigations

Input validation is a frequently-used technique for checking potentially dangerous inputs in order to ensure that the inputs are safe for processing within the code, or when communicating with other components. When software does not validate input properly, an attacker is able to craft the input in a form that is not expected by the rest of the application. This will lead to parts of the system receiving unintended input, which may result in altered control flow, arbitrary control of a resource, or arbitrary code execution.

📚 References

Arbitrary code execution CWE-20: Improper Input Validation CWE-94: Improper Control of Generation of Code (‘Code Injection’)