Bootstrap

某Github开源物联网系统RCE

Author:Ha1ey

全局搜索找到代码中有一处关于newInstance实例化方法的调用,位于jetlinks-supports-1.2.3-SNAPSHOT.jar!/org/jetlinks/supports/protocol/management/jar/JarProtocolSupportLoader.class类的lookupProvider方法中

代码如下:

图片

不难发现providerType.getDeclaredConstructor().newInstance()在这个位置有一处调用构造方法实例化返回一个ProtocolSupportProvider对象。

向上找到org.jetlinks.community.protocol.AutoDownloadJarProtocolSupportLoader#load这个方法有两处调用,一处是location参数是http形式的

图片

另一处则是参数为fileid指定的文件:

图片

最后定位到入口点org.jetlinks.community.device.web.ProtocolSupportController#convertToDetail,web根路径是/api,所以对应的路由是/api/protocol/convert

图片

后面动态调试一下求证一下前面的猜想

断点放在org.jetlinks.community.device.web.ProtocolSupportController#convertToDetail方法中,会调用到org.jetlinks.community.protocol.SpringProtocolSupportLoader#load这个方法

图片

再往下就到了我们关注的org.jetlinks.community.protocol.AutoDownloadJarProtocolSupportLoader#load这个load方法,这个方法有两部分加载方式,首先看第一种

图片

获取参数location的值,判断是否是http,把值md5后找一下临时目录中的jar包,如果存在就直接调用org.jetlinks.supports.protocol.management.jar.JarProtocolSupportLoader#load方法处理,如果文件不存在,就从指定的url下载jar包到本地,然后再调用load去加载,

图片

另一种则是通过我们指定fileId参数去指定加载目标本地的一个jar包。

图片

上述两种获取jar的方式最后都会走到org.jetlinks.supports.protocol.management.jar.JarProtocolSupportLoader#load这里主要是获取一个classloader

图片

最后调用sink点

图片

org.jetlinks.supports.protocol.management.jar.JarProtocolSupportLoader#lookupProvider方法中有一处

            loaderScanner.walkClass((loader, name, clazz) -> {
                this.visitor.validate(name, clazz);
            });

这里调用ASM去检查了我们jar包的classname是否包含com.googleorg.apachecn.hutool这几个包名

图片

如果不是以上述包名开头的类,就检查方法调用的黑名单

图片

图片

这里很好绕过,可以直接使用反射加载字节码的方式进行恶意类加载。不过需要注意的是这套系统是基于netty的响应式web。

两种加载恶意jar的方式

第一种;

利用系统自带的upload接口去上传一个jar,拿到id

图片

然后进行加载

图片

第二种:

直接出网远程加载一个jar

图片

本文首发先知社区:https://xz.aliyun.com/t/16848

本文章仅供学习交流使用,文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!

;