这里主要想写一下fastjson这类万金油漏洞的具体打法 主要也是学习一些java的知识。对这个漏洞的停留我也只是停留在扫描器扫描 然后网上随便复制个poc直接打 迄今为止我也没复现成功过这玩意 所以想着先复现一次rce 然后跟两篇高质量文章 但估计也跟不完 明天还是得给客户完善一下答辩的事情 唉 好难
vulhub-1.2.24
用插件直接扫能发现洞 会自动检测所有数据包 然后进行探测
https://github.com/pmiaowu/BurpFastJsonScan/releases
漏洞分析文章
https://forum.butian.net/share/3055
https://forum.butian.net/share/3096
fastjson的序列化与反序列化
package org.example; import com.alibaba.fastjson.JSON;
public class Main {
public static void main(String[] args) { Person person = new Person("Alice", 18); String jsonString = JSON.toJSONString(person); System.out.println(jsonString);
String jsonString2 = "{\"age\":20,\"name\":\"Bob\"}"; Person person2 = JSON.parseObject(jsonString2, Person.class); System.out.println(person2.getName() + ", " + person2.getAge()); }
public static class Person { private String name; private int age;
public Person(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public int getAge() { return age; } } }
|
fastjson的注释
@JSONField
注解来指定Java
类的属性和JSON
字段之间的映射关系
@JSONType(orders = {"name", "age"})
来指定属性的序列化顺序
@type
是fastjson
中的一个特殊注解,用于标识JSON
字符串中的某个属性是一个Java
对象的类型。具体来说,当fastjson
从JSON
字符串反序列化为Java
对象时,如果JSON
字符串中包含@type
属性,fastjson
会根据该属性的值来确定反序列化后的Java
对象的类型。
直接使用@type访问java.lang.Runtime来进行rce 这里要注意jdk的版本 太高了和太低了都不行 我这里是idea里面自己下的jdk11
由于fastjson
在1.2.24
之后默认禁用@type,因此这里我们通过ParserConfig.getGlobalInstance().addAccept("java.lang");
来开启,否则会报错autoType is not support
。
package org.example; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import java.io.IOException;
public class Main { public static void main(String[] args) throws IOException { String json = "{\"@type\":\"java.lang.Runtime\",\"@type\":\"java.lang.Runtime\",\"@type\":\"java.lang.Runtime\"}"; ParserConfig.getGlobalInstance().addAccept("java.lang"); Runtime runtime = (Runtime) JSON.parseObject(json, Object.class); runtime.exec("calc.exe"); } }
|
这里是调用了恶意类java.lang.Runtime
那正常的类是啥呢?
导入com.alibaba.fastjson.serializer.SerializerFeature
并且在序列化的时候SerializerFeature.WriteClassName
即可输出本身所属的类
调用toJSONString
方法的时候,参数里面多了一个SerializerFeature.WriteClassName
方法。传入SerializerFeature.WriteClassName
可以使得Fastjson
支持自省,开启自省后序列化成JSON
的数据就会多一个@type
,这个是代表对象类型的JSON
文本。FastJson
的漏洞就是他的这一个功能去产生的,在对该JSON
数据进行反序列化的时候,会去调用指定类中对于的get/set/is
方法
package org.example; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature;
public class Main {
public static void main(String[] args) { Person person = new Person("Alice", 18); String jsonString = JSON.toJSONString(person,SerializerFeature.WriteClassName); System.out.println(jsonString);
}
public static class Person { private String name; private int age;
public Person(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public int getAge() { return age; } } }
|
三种反序列化字符串的方法
Person user = new Person(); user.setAge(18); user.setName("xiaoming"); String s1 = JSON.toJSONString(user, SerializerFeature.WriteClassName); JSONObject jsonObject = JSON.parse(s1); System.out.println(jsonObject);
Person user = new Person(); user.setAge(18); user.setName("xiaoming"); String s = JSON.toJSONString(user); Person user1 = JSON.parseObject(s, Person.class); System.out.println(user1);
Person user = new Person(); user.setAge(18); user.setName("xiaoming"); String s1 = JSON.toJSONString(user, SerializerFeature.WriteClassName); Person user1 = JSON.parseObject(s1,Person.class); System.out.println(user1);
|
JNDI
JNDI
是Java
平台的一种API
,它提供了访问各种命名和目录服务的统一方式。JNDI
通常用于在JavaEE
应用程序中查找和访问资源,如JDBC
数据源、JMS
连接工厂和队列等。需要安装一个tomcat
https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.0-M22/bin/apache-tomcat-11.0.0-M22.zip
tomcat解压后把bin目录放到环境变量下
然后再新建一个名为CATALINA_HOME
的路径,值为tomcat
的根目录
JAVA_HOME
和JRE_HOME
的也要在用户变量中配置一下 放jdk的根目录
双击tomcat
的bin
目录下的startup.bat
,然后访问[http://localhost:8080/](http://localhost:8080/)
,就可以看到服务启动成功了