image
由于上⾯的代码将服务端与客户端写到了⼀起,所以看着不那么清晰,我看到很多⽂章⾥吧JNDI⼯⼚初始化这⼀步操作划分到了服务端,我觉得是错误的,配置jndi⼯⼚与jndi的url和端⼝应该是客户端的事情。
可以对⽐⼀下前⼏章的rmi demo与这⾥的jndi demo访问远程对象的区别,加深理解
JNDI注⼊
注⼊的原理
我们来到JNDI注⼊的核⼼部分,关于JNDI注⼊,@pwntester在BlackHat上的讲义中写的已经很详细。我们这⾥重点讲⼀下和RMI反序列化相关的部分。接触过JNDI注⼊的同学可能会疑问,不应该是RMI服务器最终执⾏远程⽅法吗,为什么⽬标服务器lookup()⼀个恶意的RMI服务地址,会被执⾏恶意代码呢?
在JNDI服务中,RMI服务端除了直接绑定远程对象之外,还可以通过References类来绑定⼀个外部的远程对象(当前名称⽬录系统之外的对象)。绑定了Reference之后,服务端会先通过Reference()获取绑定对象的引⽤,并且在⽬录中保存。当客户端在lookup()查这
个远程对象时,客户端会获取相应的object factory,最终通过factory类将reference转换为具体的对象实例。
整个利⽤流程如下:
1. ⽬标代码中调⽤了InitialContext.lookup(URI),且URI为⽤户可控;
2. 攻击者控制URI参数为恶意的RMI服务地址,如:rmi://hacker_rmi_server//name;
3. 攻击者RMI服务器向⽬标返回⼀个Reference对象,Reference对象中指定某个精⼼构造的Factory类;
python转java代码4. ⽬标在进⾏lookup()操作时,会动态加载并实例化Factory类,接着调⽤ObjectInstance()获取外部远程对象实例;
5. 攻击者可以在Factory类⽂件的构造⽅法、静态代码块、getObjectInstance()⽅法等处写⼊恶意代码,达到RCE的效果;
在这⾥,攻击⽬标扮演的相当于是JNDI客户端的⾓⾊,攻击者通过搭建⼀个恶意的RMI服务端来实施攻击。我们跟⼊lookup()函数的代码中,可以看到JNDI中对Reference类的处理逻辑,最终会调⽤ObjectInstance():
实战案例
1. ⾸先创建⼀个恶意的对象
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论