这里主要想写一下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/),就可以看到服务启动成功了