Apache Log4j是一个基于Java的日志框架,已于2015年8月5日停止维护。Log4j2是其重构升级版本,新增的Lookups方法设计用于通过多种途径动态引入外部变量。log4j2版本 < log4j-2.15.0-rc2可由JNDI注入实现远程代码执行。

执行流程

当POC作为message传递给Logger类的errorfatal等方法后,略去一些非关键流程,会进入到MessagePatternConverterformat方法对${内容进行解析替换:

之后进入Interpolator类的lookup方法,由前缀值jndi获取到JndiLookup类:

最终调用对应的lookup方法发起请求,也就是遍地开花的dnslog。。。

利用流程

JDK版本<8u191,可通过LDAP引入外部JNDI Reference:

JDK版本>=8u191,当存在org.apache.naming.factory.BeanFactorycom.springsource.org.apache.el等依赖时,可在返回的JNDI Reference中指定相应工厂类及setter方法,或是由LDAP引入序列化链实现RCE:

同时可以结合一些其它StrLookup适当变形,以及配合官方测试用例中脏数据"?Type=A Type&Name=1100110&Char=!"绕过rc1。

RC2版本对此异常进行了捕获。。。

参考链接

Log4j2 Manual Lookups

LOG4J2-3201 - Limit the protocols JNDI can use by default