欢迎来到云服务器

网络技术

Django任意代码执行裂痕阐明

1 从Django的SECTET_KEY到代码执行

Django是一个可以用于快速搭建高机能,优雅的网站的平台,由Python写成。回收了MVC的软件设计模式,即模子M,视图V和节制器C。它 最初是被开拓来用于打点劳伦斯出书团体旗下的一些以新闻内容为主的网站的,等于CMS(内容打点系统)软件。并于2005年7月在BSD许可证下宣布。

最 近在举办网站代码审查的进程中,发明某些产物由于session利用不妥,导致大概被进攻者操作,执行任意代码。这些产物在登录的JS代码中,泄露了 SECRET_KEY,将该值作为暗码加密的盐,这样就袒露了加密salt不太好吧,更重要的是对django的安详造成了极大的威胁。

2 SECRET_KEY浸染

SECTET_KEY在djanog中利用很是遍及,根基上涉及到安详,加密等的处所都用到了,下面罗列一些常见情景: 1,json object的签名 2,加密函数,如暗码重置,表单,评论,,csrf的key,session数据

这内里就要重点讲到session的问题,在这里利用不妥就会导致代码执行

3 代码执行 3.1 settings的session配置

django默认存储session到数据库中,可是大概会较量慢,就会利用到缓存,文件,尚有cookie等方法,假如回收了cookie机制则有大概代码执行,settings设置如下:


SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'


3.2 django 1.6以下

在django1.6以下,session默认是回收pickle执行序列号操纵,在1.6及以上版本默认回收json序列化。代码执行只存在于利用pickle序列话的操纵中。

3.3 session处理惩罚流程

可以简朴的分为两部门,process_request和process_response,前者认真选择session引擎,初始化cookie数据。见代码


class SessionMiddleware(object):
    def process_request(self, request):
        engine = import_module(settings.SESSION_ENGINE)
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)

class SessionMiddleware(object):

    def process_request(self, request):

        engine = import_module(settings.SESSION_ENGINE)

        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)

process_response则是处理惩罚返回给用户的cookie信息,好比修改逾期时间等。在将session存入缓存后,大概在某个操纵中会用到session信息,这个时候就会通过反序列化操纵从缓存中取,假如反序列话引擎是回收pickle机制的话就存在代码执行。反序列化的代码位于django.core.signing.py中,这个模块主要是一些签名,加解密操纵,同时也包括序列化和反序列化,默认回收JSON引擎,下面是反序列话loads的代码:


loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, max_age=None):
    """
    Reverse of dumps(), raises BadSignature if signature fails
    """
    base64d = smart_str(
        TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
    decompress = False
    if base64d[0] == '.':
        # It's compressed; uncompress it first
        base64d = base64d[1:]
        decompress = True
    data = b64_decode(base64d)
    if decompress:
        data = zlib.decompress(data)
    return serializer().loads(data)

loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, max_age=None):

    """

    Reverse of dumps(), raises BadSignature if signature fails

    """

    base64d = smart_str(

        TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))

    decompress = False

    if base64d[0] == '.':

        # It's compressed; uncompress it first

        base64d = base64d[1:]

        decompress = True

    data = b64_decode(base64d)

    if decompress:

        data = zlib.decompress(data)

    return serializer().loads(data)

3.4 结构POC
腾讯云代理

Copyright © 2003-2021 MFISP.COM. 国外vps服务器租用 梦飞云服务器租用 版权所有 粤ICP备11019662号