• 学习笔记-SSTI


    SSTI


    免责声明

    本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.


    什么是模板

    模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这大大提升了开发效率,良好的设计也使得代码重用变得更加容易。

    模板引擎也扩展了黑客的攻击面。除了常规的 XSS 外,注入到模板中的代码还有可能引发 RCE(远程代码执行)。通常来说,这类问题会在博客,CMS,wiki 中产生。虽然模板引擎会提供沙箱机制,攻击者依然有许多手段绕过它。

    什么是 SSTI

    1. 如果攻击者能够控制要呈现的模板,服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,就可能导致上下文数据的暴露,甚至在服务器上运行任意命令的表达式。
    2. 服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行等问题。其影响范围主要取决于模版引擎的复杂性,所以说 用户的输入永远都是不可信的,凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言.

    相关文章

    相关案例

    相关工具

    靶场


    SSTI 怎么产生的

    以 PHP Twig 为例

    • 正确写法 ✔

      1. require_once dirname(__FILE__).‘/../lib/Twig/Autoloader.php‘;
      2. Twig_Autoloader::register(true);
      3. $twig = new Twig_Environment(new Twig_Loader_String());
      4. $output = $twig->render("Hello {{name}}", array("name" => $_GET["name"])); // 将用户输入作为模版变量的值
      5. echo $output;

      这段代码没有什么问题,用户的输入到时候渲染的时候就是 name 的值,由于 name 外面已经有 {{}} 了,也就是说,到时候显示的只是 name 变量的值,就算你输入了 {{xxx}} 输出也只是 {{xxx}} 而不会将 xxx 作为模板变量解析

    • 错误写法 ❌

      1. require_once dirname(__FILE__).‘/../lib/Twig/Autoloader.php‘;
      2. Twig_Autoloader::register(true);
      3. $twig = new Twig_Environment(new Twig_Loader_String());
      4. $output = $twig->render("Hello {$_GET[‘name‘]}"); // 将用户输入作为模版内容的一部分
      5. echo $output;

      现在开发者将用户的输入直接放在要渲染的字符串中了

      注意:不要把这里的 {} 当成是模板变量外面的括号,这里的括号实际上只是为了区分变量和字符串常量而已**,于是我们输入 {{xxx}} 就非常的符合模板的规则,模板引擎解析了

    以 python 的 jinja2 为例

    • 错误写法1 ❌

      1. @app.errorhandler(404)
      2. def page_not_found(e):
      3. template = '''{%% extends "layout.html" %%}
      4. {%% block body %%}
      5. Oops! That page doesn't exist.

      6. %s

  • {%% endblock %%}
  • ''' % (request.url)
  • return render_template_string(template), 404
  • 这里使用了一个字符串的格式化来传递一个 url ,但是还是用模板的方式去渲染的啊,也就是说还是支持模板引擎支持的语法,那我们为什么不能输入模板引擎的语法呢?于是在 URL 后面跟上 {{7+7}} 自然而然就能计算出 49 了

  • 错误写法2 ❌

    1. # coding: utf-8
    2. import sys
    3. from jinja2 importTemplate
    4. template = Template("Your input: {}".format(sys.argv[1] if len(sys.argv) > 1 else ''))
    5. print template.render()

点击关注,共同学习!安全狗的自我修养

github haidragon

https://github.com/haidragon

  • 相关阅读:
    (a == 1 && a == 2 && a == 3)不可以为true?
    opencv入门笔记(二)
    链表的奇偶重排
    MySQL数据库的数据类型和基于MySQL数据类型的综合实例项目
    【学习笔记】CF559E Gerald and Path
    SSM+家装管理系统 毕业设计-附源码191452
    【服务器数据恢复】RAID故障导致数据库所在分区无法识别的数据恢复
    Mybaits延迟加载实现原理
    【无标题】
    SpringMVC使用(注解、获取各种参数的方式、视图模板、文件上传下载、国际化、RestFul)
  • 原文地址:https://blog.csdn.net/sinat_35360663/article/details/127639549