Log4j rce 复现
log4j远程代码执行分析
由于log4j提供了对JNDI表达式的解析功能,从Log.error()中传入的poc会被log4j触发并执行。
log4j 执行过程
org.apache.logging.log4j.core.layout.PatternLayout.PatternSerializer#toSerializable(org.apache.logging.log4j.core.LogEvent, java.lang.StringBuilder)
方法循环调用
for(int i = 0; i < len; ++i) {
this.formatters[i].format(event, buffer);
}
关键触发点org.apache.logging.log4j.core.pattern.PatternFormatter#format
方法,format方法中又会对org.apache.logging.log4j.core.pattern.MessagePatternConverter#format
方法进行调用。Message类format方法会判断传入的字符串是否包含${}
关键字。
通过replace()
最终调用到了org.apache.logging.log4j.core.lookup.StrSubstitutor#resolveVariable
触发了整条链的关键方法lookup。
org.apache.logging.log4j.core.lookup.Interpolator#lookup
方法会截取传入的字符来决定将要使用的lookup查询方法,通过该方法体的处理,我们调到了JndiLookup类下的lookup方法。
通过JNDI#lookup
调到org.apache.logging.log4j.core.net.JndiManager#lookup
方法,通过JndiManager#lookup
调到InitalContext
类的lookup方法进行JNDI查询。
然后一系列的处理大致做了对传入的URl进行截取,截取到url中包含的class类名,然后通过loadClass()方法加载该类,最终执行我们远程存放的类的代码,创建一个文件。