Fastjson
首先我们看demo的源码,启动类里面使用FastJsonHttpMessageConverter(这个是fastjson的)替换了原生的HttpMessageConverters,所以对传递过来的消息会进行一个json的处理(这里的demo可以换种写法,直接使用传递过来的data做一个JSON.parse也行,作为一个懒货我就不改代码了,看不懂也不要问我这是啥,我也不知道)
因为知道了会做一个反序列化操作,所有我们把断点打到下图这里:
然后启动这个demo,把对应的payload发送到我们写好controller中,可以看到我们的断点接收到了这个请求,在text中就是具体的请求体(这个自己看去我就不截图了):
在接下来的代码中通过switch语句匹配lexer.token,所以我们直接看case所匹配到的地方:
我们继续跟进,由于前三个条件不匹配,所以会执行到箭头所指的位置,我们继续执行
在if (ch == '"')这一行表示 {之后的字符的为"则进入方法:
我们继续执行他执行了lexer.scanSymbol这个方法,我们往下跟,在这个方法里面可以看到,拿到的返回的key是@type:
我们接着往下走,睁大眼睛,重点来了:
你看这是啥,这不是传说中的反射嘛,你看那个名字不正是payload传递进来的嘛(看TypeUtils.loadClass这个名,用脚丫子想也知道他是干啥的了,我就不跟了),类加载了,我们继续走:
到这里之后别走了,我们继续跟进到com.alibaba.fastjson.parser.deserializer的parseField方法中:
往后执行:
看到没,这是不是payload的rmi那里嘛,到了这之后接着往后走:
在setAutoCommit这个方法中调用了conn方法,然后我们跟进到connect中(看到这个lookup了没得就它了):
在connect方法执行两遍后就会弹出计算器了,使用JdbcRowSetImpl做利用链的过程大致就是这样了,至于为什么fastjson会把加载@type的类请看这篇,讲的非常详细了。如果有哪有问题,不要问我,我不会,下期看看是换个语言(c#或者php)的案例还是再拿个java的框架来写,或者说这个的绕过和其他利用链(嗯。。。我考虑一下写啥)
缓解措施
- 升级fastjson版本
- 上安全设备如waf、ips等