分享好友 最新动态首页 最新动态分类 切换频道
2. SSTI(模板注入)漏洞(cms实例篇)
2024-12-26 21:27

上篇《SSTI(模板注入)漏洞(入门篇)》主要介绍了PHP/Python/Java常见的几种模板注入,本篇主要通过cms实例来更好的理解并且挖掘SSTI。

以下cms的源码地址:https://github.com/bmjoker/Code-audit/

先给出漏洞payload:

通过搜索代码执行常用的字段(eval,assert...),定位到此处

查看 maccms_php_v8.xinccommon emplate.php 文件,判断变量是否可控:

可以看到如果想构造代码执行,需要控制变量 $strif ,通读上下文发现一条数据链:

最原本的传进来的数据是 $this->H ,经过 preg_match_all() 函数进行正则匹配,把匹配到的结果赋值给 $iar 这个二维数组,进入for循环遍历数组,将 $iar[2][$m] 所指的元素传入 asp2phpif() 方法进行安全过滤,最后的返回值就是 $strif 。 

这里看到 asp2phpif() 方法仅是对一些字符的替换。

先来追踪一下 ifex() 函数在哪里被调用:

最后定位到了 maccms_php_v8.xindex.php 文件,发现了调用的地方 $tpl->ifex(),那么 $this->H 参数从哪里传进来呢?

最上面看到了这样一段代码:$m = be('get','m'),跟进 be() 这个方法:

再结合网站的请求:

大概了解了网站接收参数的方法。 $m = be('get','m'):就是通过get请求获取m的参数。然后获取到的参数被 explode() 方法以 - 分割成数组传递给 $par,取数组的第一个元素赋值给$ac,判断 $ac 所指的元素是否在 $acs 的数组中,如果存在的话就使用 include 包含 /inc/module/ 目录下以 $ac 所指元素命名的php文件。

根据payload,进入vod.php文件,这里给出关键代码:

当我们调用 search 方法时,就会进入此分支,通过 be("all","wd") 获取用户传进来的wd的参数,传入 chkSql 方法,然后赋值给 $tpl->P["wd"]

仅是使用 htmlEncode() 方法对一些字符判空,转义。

$tpl->H 就是传入ifex() 方法中的 $this->H 参数,因为 $tpl = new AppTpl()。上图代码中 $tpl->H 加载文件 vod_search.html 然后展示给前端。

$colarr$valarr两个参数数组,经过 str_replace() 方法,将 vod_seach.html 中的类似 {page:des} 的字段替换成 $tpl 所指向的字段,漏洞导致的关键是这个 $tpl->P["wd"] 是我们前端可控的参数。

执行完上面的赋值,回到index.php中下一步就调用 ifex() 方法

$tpl->H 就是替换过后的 vod_search.html 文件

这样的话再倒过来看最初的 template.php 文件,是不是就清楚多了

通过for循环一次一次的匹配到类似  {if-A:"{page:typepid}"="0"}  的字段,赋值给变量 $strif,传入eval方法导致代码执行漏洞 

下面就是如何构造合适的payload绕过正则表达式:{if-([sS]*?):([sS]+?)}([sS]*?){endif-1}

 类似这样即可:

真正代码调试过的人,可能有的人会有疑问,因为使用上面payload的话  if (strpos(",".$strThen,$labelRule2)>0),if (strpos(",".$strThen,$labelRule3)>0) 两个循环都无法进入,所以真正的漏洞出发点在 else:

漏洞演示效果:

静态插桩打印 $iar 的值:

打印 $strif 的值:

参照上面打印 $iar 的值,第三个 phpinfo() 进入else分支的eval函数中,导致代码执行。

ofcms是由JFinal开发的内容管理系统。

从pom.xml可以看到引入freemarker-2.3.21依赖

JFinal允许多模板共存,如果想要使用freemarker模板,需要在configConstant配置

然后再使用 JFinal.me() 调用模板,使用 put 用来替换原来输出response html代码输出到浏览器

到这里我们是不是可以理解为网站的html文件由FreeMarker模板进行渲染。

ofcms后台模板文件

任意选择一个html文件,再文件中插入我们的payload:

保存,在前台访问404.html界面

FreeMarker解析了404.html文件中我们插入的payload,导致命令执行

由于74CMS是基于Thinkphp3的语法魔改而成。建议先去大概看一下Thinkphp3的开发手册:http://document.thinkphp.cn/manual_3_2.html#

先来看一下漏洞代码:ThinkPHPLibraryThinkView.class.php

在第122行,include $templateFile 典型的文件包含,如果 $templateFile 可控就可以getshell。

通读 fetch() 函数代码,发现如果想要文件包含,传进来的参数 $content 必须为空,才能进入if循环与下面的三元表达式。把前端获取的 $templateFile 传进 parseTemplate() 方法:

啊...这?传进来的参数 $template 经过 is_file() 仅仅是做了文件是否存在以及是否为正常的文件,就直接把 $template return ...

当使用PHP原生模板时会进入下面的if循环,紧接着就 include $templateFile 。

什么是PHP原生模板?

由开发者手册可知,如果要使用PHP代码时尽量采用php标签,也就是 <php>...</php> 这种形式

大概知道这些,我们就可以通过上传内容为PHP原生模板的文件,再使用 include 包含。

继续回溯代码,寻找哪里调用 fetch() 这个函数,包括参数从哪里传过来

同文件下的 display() 方法里调用了fetch() 方法,看过模板手册的都知道,渲染模板输出最常用的是使用display方法,继续查找 display() 在哪里被调用

可以看到在 Controller.class.php 中有调用

直接在 MController.class.php 文件中就可以看到 display() 函数的调用

熟悉Tp框架的应该知道 I 方法时用来接收参数,而第20行 I('get.type'...) 说明 $type 可以通过get方式从前端获取

可见,这里将 $type 参数传入 display() 函数,display() 函数是 ThinkPHP 中展示模板的函数。然后又将参数传入 View 类的 display() 函数,最后调用 fetch() 函数,导致文件包含漏洞

使用自带的 favicon.ico 做下试验,看是否能成功包含:

成功包含。

如果想要包含我们构造的恶意文件,需要满足两个条件:

  1. 可以将恶意文件上传到服务器

  2. 有文件的绝对路径

注册一个账户,登录后台寻找文件上传的地方:

个人用户创建简历后支持上传 docx 格式的简历。上传一个内容为PHP原生模板的 docx 文件,将其作为模板。数据包如下:

上传文件的绝对路径为:/74cms_v4.1.5/upload/data/upload/word_resume/2009/14/5f5f8bdb56593.docx

再将这个文件名作为type的值,成功执行代码:

首先通过搜索关键字定位到导致漏洞的代码:coreviewView.php  ——>  parser()

根据payload,参数大概调用过程如上图

漏洞的关键点是 include $tpl_c_file,文件包含模板文件导致getshell。

parser() 方法接受传过来的模板文件 $file,经过 preg_replace() 方法来过滤掉相对路径(例如:https://www.cnblogs.com/bmjoker/,..),这里使用了不安全的替换,因为 preg_replace() 匹配到不安全的字符不是直接exit,而是选择替换成空,利用这个可以尝试构造绕过,像下图这样:

然后将替换过后的 $file 传入if 循环,第一个if判断 $file 是否是以 / 开头,第二个elseif判断 $file 是否包含 @ ,如果都不满足进入else拼接,$tpl_file = 模板路径 + / + $file

$tpl_file 是模板文件,$tpl_c_file 是要编译的文件。

继续看代码发现在121行又做了一次拼接,$tpl_c_file = 模板路径 + / + md5($tpl_file) + .php。紧接这是一个if判断,判断文件是否存在,判断 $tpl_c_file 文件的修改时间是否小于 $tpl_file,判断读取配置文件是否成功,很尴尬,全都是false,直接跳过if循环,到达关键地方,直接 include 包含我们构造的文件,导致漏洞产生。

这里可能有的人会有疑问,因为在到达 include 的时候,$tpl_c_file是 模板路径 + / + md5($tpl_file) + .php 这种形式,我们构造的文件路径早已面目全非。这个地方需要注意这个漏洞的根本原因是PbootCMS2.07内核处理缺陷导致的一个前台任意文件包含漏洞,他的内核函数在生成编译文件的时候造成任意文件读取。

parser() 方法已经分析完毕,现在需要寻找调用了parser函数的地方,且参数可控

进入 Controller.php 文件

这里看到显示模板,解析模板都有调用到 parser 方法,继续跟踪判断哪里调用

显示模板 display() 方法发现没有参数可控,但是解析模板 parser() 方法,发现有变量传入

先来看 SearchController.php 文件

index() 方法中,接收前端传递过来的参数,进入正则匹配,这正则匹配任意的字符,还包括-,.,/,最后直接传入 parser() 方法中,直接构造利用读取robots.txt:

同样构造利用的还有 TagController.php 文件

包含写入shell的txt文件:

最新文章
卖一辆亏5万,知情人称极越亏损已超百亿:百度曾想零对价卖给吉利
专题:供应商讨债?经营遇困?极越启动大规模裁员!CEO夏一平被员工围堵在办公室  来源:腾讯汽车  特约作者谢婉  今年7月,百度董事长李彦宏和吉利董事长李书福在北京有过一次会面,话题是关于两家公司共同投资的汽车企业极越。吉利
赋能发展 出奇“智”胜 智能制造创业沙龙
随着科技进步和信息技术的飞速发展,智能制造已经成为了推动工业升级的重要动力。为了促进智能制造领域的技术交流和合作,展示最新的智能制造技术和应用,我们计划举办一场智能制造沙龙活动。本次活动将邀请行业内的专家、企业代表和相关机
有意思,没毛病的奥迪A5 这才是年轻人要的中型车
从外观来看,2020款延续了现款设计风格,六边形进气格栅配合奥迪的logo极具辨识度。而更是科技感十足,配合s-line套件,使整个前脸更显动感时尚。此外,新车还将增加s动感型和s-line运动型两种外观风格供消费者进行选择。新款奥迪a5的内饰
“AI+医疗”里程碑时刻 迈瑞医疗推出启元重症大模型 12月14日,国产医疗器械龙头 迈瑞医疗 (300760.SZ)在中国北京发布全球首个临床落地的重症医疗大模型
来源:雪球App,作者: 证券市场周刊市场号,(https://xueqiu.com/2994748381/316885950)12月14日,国产医疗器械龙头(300760.SZ)在中国北京发布全球首个临床落地的重症医疗大模型——“启元重症大模型”。中国学术年会大会主席、中国工
校园纯情游戏攻略:精彩视频解析
最近,“校园纯情游戏”这个话题在玩家群体中掀起了一股热潮。这款游戏以其清新唯美的画风、恰到好处的剧情设置和引人入胜的游戏玩法而备受好评。然而,对于一些玩家来说,游戏中的一些关卡设计、任务攻略、角色技能等方面还是稍显困难,因
揭秘未来航路气象,预测2024年12月10日全球航路实时气象图展示揭晓!
随着科技的进步和全球气候变化的关注度不断提高,准确预测航路气象状况对于航空安全、航班准时以及全球气候研究具有重要意义,本文将重点讨论如何通过现代气象学知识和技术手段,对2024年12月10日的全球航路实时气象图进行猜测与分析,我们
百度TOP位设计_百度Top设计教程
摘要:百度TOP位设计,百度Top设计教程,新片场素材小编苗睿安百度TOP位设计,百度Top设计教程相关内容整理,如果您对百度TOP位设计,百度Top设计教程感兴趣欢迎访问免费阅读。百度TOP位设计,百度Top设计教程一、百度TOP位在线设计教程介绍如
可视化微信小程序(企业版)插件
1.数据同步,一站式管理。2.成本低,别的平台上千每年的续费成本,咱们插件一次付费百来块终身使用!3.可视化编辑,小白也可以diy自己拼接出个性风格。4.模板精美,多套现成模板风格任意切换,短时间搞出高逼格的效果。5.更多亮点,大家可
狼雨SEO空间,揭秘高效SEO优化秘籍,让你的网站独领风
狼雨SEO空间专注于揭秘高效SEO优化策略,助您网站在搜索引擎中脱颖而出。通过专业指导,提供实用技巧,帮助您提升网站排名,吸引更多流量,实现网络营销目标。随着互联网的不断发展,搜索引擎优化(SEO)已经成为网站中不可或缺的一环,在
yyygcms一元云购夺宝源码 php版 V4.5
yyygcmsV4.5云购是采用php+mysql,Thinkphp为内核,乐清市一元杀网络有限公司自主开发的云购系统源码。一元杀网络从事云购实际开发维护经验4年,以客户售后为重点。yyygcmsV4.5云购管理系统详细部分功能表:据库备份恢复APP端微信登录微信分
相关文章
推荐文章
发表评论
0评