3

在 python SimpleXMLRPC Server的 python 文档中,提到了:

警告 启用 allow_dotted_names 选项允许入侵者访问您模块的全局变量,并可能允许入侵者在您的机器上执行任意代码。仅在安全、封闭的网络上使用此选项。

现在我有一个服务器,代码如下:

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler


server = SimpleXMLRPCServer(("localhost", 8000),
                            requestHandler=RequestHandler)
server.register_introspection_functions()

server.register_function(pow)

def adder_function(x,y):
    return x + y
server.register_function(adder_function, 'add')

class MyFuncs:
    def mul(self, x, y):
        return x * y

server.register_instance(MyFuncs(), allow_dotted_names=True)

server.serve_forever()

请解释如何利用该漏洞将任意代码注入服务器?如果我上面的代码不是易受攻击的,那么举一个可以被利用的例子和客户端代码这样做。

4

1 回答 1

0

MyFuncs().mul不仅仅是一个可调用函数,它(像所有 Python 函数一样)是一个具有自己属性的一流对象。

除了一大堆__xxx__魔法方法(因为 SimpleXMLRPCServer 阻止访问以 开头的任何东西,您无法访问_)之外,还有内部方法成员im_class(指向类对象)、im_self(指向MyFuncs()实例)和im_func(指向函数定义为mul)。该函数对象本身具有许多可访问的属性 - 最值得注意的是包括func_globals哪些属性可以访问包含文件的变量范围字典。

因此,通过调用mul.im_func.func_globals.get攻击者将能够读取您在脚本中设置的任意全局变量,或者使用update()字典来更改它们。在上面的示例中,这是不可利用的,因为您在全局变量中没有任何敏感内容。但这可能不是您希望始终保持真实的东西。

完整的“执行任意代码”不太可能,但您可能会想象一个可写的全局codeToExecute变量,eval例如稍后会被编辑,或者有人使用 注册整个模块register_instance,从而允许访问它导入的所有模块(典型示例:osos.system)。

在 Python 3 中,这种特殊的攻击不再可访问,因为函数/方法的内部属性被重命名为双下划线版本,在那里它们被阻止了。但总的来说,“默认打开”并允许外部访问仅基于名称的实例上的任何属性似乎是一个坏主意 - 不能保证将来不会存在其他非下划线名称,或者属性不会被添加到可以以某种方式利用的那些属性的可访问内置类型(元组、字典)中。

如果您确实需要嵌套属性访问,那么提供一个 SimpleXMLRPCServer 版本似乎更安全,该版本需要类似@rpc_accessible装饰的东西来定义应该可见的内容。

于 2013-03-17T16:19:37.030 回答