json 类框架踩点思路
0x01 json 框架区分
给定正常对象 User
public class User {
String username;
int password;
float id;
}
利用报错信息、回显信息来区分json框架最直接的方式是更改原json数据构造错误语法(比如删去 "
) ,通过异常信息中的关键字识别。
这种方式需要的最重要的一个前置条件就是报错需要回显,且需要是json框架的报错。比如在实战中遇到一些做了统一错误处理的站点,原本用来判断 jackson 的方式(添加字符破坏的方式),在参数处理时就已经触发Exception,这种情况其实是不好确定的。
fstjson
- 浮点精度不丢失
其他 json 解析库在解析json时都会丢失,但fastjson不会
{
"username": "1234",
"password": 1.111111111111111111111111111111111,
"id": 1.1111111111111111111111111111111111111
}
- 响应状态
如果是fastjson会对@type做出响应
{
"@type": "whatever"
}
- DNSLOG
DNSLOG 这种方式可以无回显探测fastjson,是较为高效的一种方法,但不适用于不出网环境,具体探测方式在后文展开
{
"x": {
"@type": "java.net.InetSocketAddress"{
"address":,
"val": "dnslog"
}}
}
jackson
- 严格要求与bean对象对齐,可少不能多,因此添加多余kv 报错
{
"username": "1234",
"password": "123",
"a": 1
}
- 无法解析单引号 报错
{
'username': '1234',
'password': '123'
}
- 无法识别注释符 报错
{
"username": "1234",
"password": "123"
}/**/
gson
- 浮点无法转整数 报错
向 int 类型的值传浮点数无法解析会报错 NumberFormatException
{
"username": "1234",
"password": 1.111111111111111111111111111111111,
"id": 1
}
- 特有解析
org.json 与 gson 在遇到 ## 时都会当注释符处理,可以用来识别这两个框架
#\n{"username": "1234", "password": 1, "id": 1.1}
而gson 在不开启 JsonReader.setLenient(true)
的情况下(默认未开启),再拼接一个json字符串时会报错,可以用来区分这两个框架
#\n{a: 1}\n{\"username\":\"1234\",\"password\":1,\"id\":1.1}
org.json
- 特有解析
org.json 打印会调用 toString() 所以可以插入\n \r
等字符改变输出,如结合前面的#
再加上\r
#{"username": "\r"}