1.naming Դ?源码?
2.Nacos 1.4.1源码解析之服务注册--AP
3.nacos是怎么进行服务注册的
4.Nacos 注册服务源码分析
5.java.naming.factory.initial
6.fastjson 1.2.24源码分析以及漏洞复现
naming Դ??
Nacos源码剖析 深入学习Nacos,解析源码,源码重点关注以下两点: 源码环境搭建从官方项目克隆Nacos源码,源码检出1.4.1版本,源码导入IDEA。源码
在本地MySQL中创建nacos-config数据库,源码歌曲批量下载源码执行resources/META-INF/nacos-db.sql脚本创建表。源码
修改console模块下的源码application.properties文件,配置相关参数。源码
启动console模块的源码启动类,非集群模式启动Nacos服务端。源码
访问本地Nacos服务:/p/...有详细介绍。源码
在启动nacos Client时,源码首先开启自动装配功能,源码接着初始化discovery配置参数。源码紧接着,注册NacosServiceRegistry,然后注册服务自动注册bean NacosAutoServiceRegistration。豆客娱乐源码在Spring容器启动完成时,启动发布监听事件。此过程中,NacosAutoServiceRegistration实现ApplicationListener,监听springBoot web容器启动事件,于Spring容器启动的finishRefresh阶段启动web容器后发布。接收到消息后执行onApplicationEvent,设置服务端口。 服务元数据初始化通过NacosRegistration,用户可以通过配置文件配置,或使用API进行服务注册。服务注册通过rest请求至/nacos/v1/ns/instance实现,官方文档提供详细指导。 nacos server端的API服务主要由com.alibaba.nacos.naming.controllers.InstanceController入口控制。它采用缓存结构,第一层为namespace,第二层为group分组。授权导游源码橘子在service中,clusterMap按照集群分组,集群内才是实例列表。在添加、修改实例或基于集群纬度修改实例时,使用copyOnWrite方式替换。流程图展示基本操作流程。nacos是怎么进行服务注册的
今天,我们从源码的角度出发,看看nacos是如果进行服务注册,服务调用,负载均衡,心跳检测等功能。首先大家我们去github上拉取代码,/alibaba/nacos,打开后我们先从注册实例作为入口开始看,注册实例的window golang源码编译接口在API模块:服务注册点进去发现里面有不同的方法,我们以第一个为例,
他是先初始化一个Instance对象,赋值后调用registerInstance()方法,通过clientProxy.registerService()去注册实例,继续往下追踪
这个NamingClientProxy()接口有多个实现类(根据实现类的名称我们看到他这里用了策略模式来处理HTTP还是RPC请求)我们先看HTTP实现类是如果处理的:
心跳检测发送关注下我圈起来的地方,这里就是心跳机制的开始喽,他先创建一个BeanInfo对象,然后交给beatReactor.addBeanInfo()这个方法。这个beatReactor看起来像个容器,那我们就去看一下他是怎么处理的。
这个类有个定时任务线程池,看到这里,我们大概就猜得出他的心跳检测机制应该是通过定时任务线程池去处理的。然后我们再看他的addBeatInfo()方法做了什么?
果然不出所料,先创建BeatTask对象然后交给定时任务线程池去定时处理这个实例信息,但是他的定时任务应该只执行一次呀,他是源码导出类结构怎么一直不断的检测的呢,我们进BeatTask这个内部类看看他是怎么循环处理的:
通过这段代码我们可以清楚的看到他是通过在BeanTask的run()方法重复执行定时任务达到一直循环检测的需求。然后我们返回继续注册实例
封装请求参数,调用API
最后发送注册实例的HTTP请求,一个注册实例的完整链路就走完啦。
负载均衡我们看获取实例的时候nacos是怎么处理的
先尝试从serviceInfoHolder获取服务信息如果没获取到,则通过clientProxy调用API去获取所有实例列表
但是我只要一个,他应该返回我哪一个呢?注意这个Balancer.RandomByWeight.selectHost(serviceInfo);就是负载均衡的关键,
最后从ref里面通过随机数获取一个实例返回。当然他的负载均衡有好几种策略。有轮询,weight权重,ip_hash,fair,等。大家有兴趣的可以自己去翻一翻都是怎么实现的。
最后如果有理解的不对的地方,欢迎大家指正纠正,一起进步。希望今天的文章对小伙伴们有帮助。
Nacos 注册服务源码分析
Nacos 注册服务源码分析
首先,从nacos-example样例工程入手,寻找注册服务的关键入口。在NamingExample的main方法中,我们关注的两行代码揭示了整个过程的起点。
从NamingFactory#createNamingService开始,这个方法通过构造函数创建了一个NacosNamingService。值得注意的是,虽然创建过程看似简单,但构造方法中包含了属性的初始化和处理,这在非Spring项目中尤为重要,通常通过静态代码块或构造方法自行完成。
真正注册服务的核心在于registerInstance方法。这个方法内部调用了clientProxy.registerService,跟踪这个过程是理解Nacos注册服务的关键。
进一步追踪NamingService的构造方法,可以看到它内部创建了NamingClientProxyDelegate代理类。这个代理类实际上是设计模式中的代理模式,用于将请求委托给grpcClientProxy或.sun.rowset.JdbcRowSetImpl`来执行内部方法。由此,我们能利用Fastjson提供的便利,通过调用对应的函数来验证漏洞。
在渗透测试中,漏洞的验证通常需要满足几个条件:判断指纹和指纹回显,Fastjson的特性使得这一步变得简单。然而,在利用过程中,要考虑到Fastjson本身的限制、JDK的限制以及可能的安全配置限制。因此,POC验证方案需考虑这些限制的版本和配置。
Fastjson通过JSON抽象类实现JSONAware接口,并提供两个常用方法:`toJSONString`用于对象转换为JsonString,`parseObject`用于将JSON字符串转换为对象。这次的漏洞主要与反序列化相关。
反序列化的执行发生在`DefaultJSONParser.java`类中。关键代码中,固定键`@type`对应反序列化类的全路径,其中`typeName`为传入类的全路径。在Fastjson 1.2.版本中,`loadClass`方法未进行任何过滤,允许传入任何JVM加载的类,并执行`setKey`方法,其中Key为可变参数。
要利用这个反序列化漏洞,需要满足以下条件:JVM加载的类、有非静态set方法和传入一个参数。使用RPC远程执行代码的思路实现POC,此处使用了`com.sun.rowset.JdbcRowSetImpl`实现。
JNDI全称为Java Naming and Directory Interface,主要提供应用程序资源命名与目录服务。其底层实现之一是RMI(Remote Method Invocation),用于Java环境的远程方法调用。在`com.sun.rowset.JdbcRowSetImpl`类中,关注点在于`getDataSourceName()`和`setAutoCommit()`方法。`getDataSourceName()`用于传值,`setAutoCommit()`用于确认调用set方法。
实现过程包括引用`com.sun.rowset.JdbcRowSetImpl`类、设置`dataSourceName`传值以及通过`autoCommit`属性触发执行方法。完成方法确认后,使用`marshalsec`项目启动RMI服务并加载远程类。
POC的实现步骤如下:首先确认目标是否使用Fastjson且存在漏洞;利用Fastjson的反序列化功能传输引用类和执行方法;使用`com.sun.rowset.JdbcRowSetImpl`执行验证POC的脚本,并观察回显结果;最后,完成漏洞利用。
具体操作包括搭建环境,如使用CentOS虚拟机作为RMI服务器和远程调用服务,KALI机器作为靶机和抓包测试。进行指纹确认、安装maven、构建RMI服务器和客户端、调用测试文件,并观察DNS日志以验证漏洞成功利用。通过DNS日志确认漏洞利用成功后,可以进一步尝试反弹shell,实现远程控制。
综上所述,Fastjson的反序列化漏洞是一个可以被利用的安全问题,通过合理的利用,可以实现远程代码执行。了解和研究这类漏洞有助于增强对Fastjson以及类似技术的防御能力。