某报表模板注入
某报表模板注入
这次公布的漏洞说是SQL注入,实际上是一个模板注入。
在产品中存在一个名为TemplateUtils
的类,这个类用来处理表达式相关的内容。
传进来的表达式会进入render
方法进行渲染:

进去看模板参数渲染使用的方法renderParameter4Tpl
,其中一直在调用同名方法render
,最开始传入了一个新的Calculator
:

中间有一个evalRenderAction
指定了RenderAction
,其他的信息不太重要,往后看:

进到最后一个renderTpl
后看到了解析表达式的位置,通过ParameterProvider.PARAMETERPATTERN
进行解析,然后就会获得表达式中的内容。


经过处理后这里就会取出${}
中的内容,然后送到下面用前面传入的RenderAction
进行渲染:


调用var2.render
自然也就是前面传进来的evalRenderAction
了:

继续往下,会走到evalString
,在这里,会将传入的内容转换为Expression

然后跟入这个eval
,发现了下一个eval
,这里就是前面的Calculator
下的方法了:

接下来会去调用下一个eval
,这里就是前面表达式的eval
,实际调用的是RelationExpression
父类BinaryExpression
的eval
:

然后就是是调用下一个Node
的eval
方法,这里的eval
是使用索引进行检测的,实际是获取表达式=
右边的内容,如果是函数的话就是FunctionCall
:

FunctionCall.eval
方法会去调用resolveMethod
,这也是这个漏洞的关键:

resolveMethod
最终会获取一个命名空间然后调用getMethod
:



到了函数调用,也就是漏洞发生的地方,存在getMethod
相关的实现类中DefaultNameSpace
类的getMethod
这里通过传入的内容去加载类:

实际会去调用com.fr.function.xxx
,这个包里面有很多函数可以调,返回后去调用evalExpression
:


网传为SQL
,看下SQL
类,应该不用多说了吧:


至于入口:
其实可玩性还是挺高的,也不一定非要用SQL的形式去做POC来检测。
现已加入豪华检测套餐: