高版本场景说明
在某些产品的JDK版本中,未来会逐渐出现JDK9,JDK11等高版本,这是编程语言发展的必经之路,新的特性必然带来新的攻防场景,比如高版本的场景中逐渐限制了下面Demo的应用
场景1:
在JDK8的时代,攻击者会经常使用当前线程的contextClassLoader去反射调用defineClass方法,然而JDK11会抛出警告,有的场景还会直接不让调用。
默认情况下JDK 9不允许访问封装的包以及深度反射其他模块(包括平台模块)中的代码 。
为了便于将基于类路径的应用程序迁移到Java 9,在对平台模块中的类应用深度反射时,或者使用反射来访问非导出包中的类型时,"JVM默认显示警告",而后续的尝试将不会产生额外的错误或警告。如果想要进一步调查问题的原因,可以使用——illegal-access 命令行标志的不同设置来调整行为:
——illegal-access=permit 默认行为。允许对封装类型进行非法访问。当第一次尝试通过反射进行非法访问时会生成一个警告
——illegal-access=warn 与permit一样,但每次非法访问尝试时都会产生错误
——illegal-access=debug 同时显示非法访问尝试的堆栈跟踪。
——illegal-access=deny 不允许非法的访问尝试。这将是未来的默认行为
0x01 unsafe的用法
如果想要绕过上述高版本的限制,那么需要在启动JVM进程的时候加入以下参数:
java ——illegal-access=permit exec.class
显然,这种解决方案不能满足实际攻防场景的应用。
而unsafe的使用是可以绕过代码层面的限制的,直接在内存层面操作,实现的Demo有两种
unsafe类
如果是JDK9-11的话如何注入内存马呢?
unsafe类中有一个方法是defineAnonymousClass,在defineAnonymousClass中再使用defineClass是不会被拦截的。
以JDK11版本下注入tomcat内存马为例,JSP的Demo如下
冰蝎连接:
confluenceMem
CVE-2021-26084,该漏洞产生的原因是OGNL表达式注入,基于已经给出的POC和EXP,最后的基本Demo如下:
执行代码的是靠Jscript触发的,那么问题就来了,如何能让不同的JDK版本都能够顺畅地执行Jscript代码,经过向feihong师傅请教和不断地fuzz,得到的结果如下:
解决JDK7和JDK8的内存马注入问题主要是defineClass参数的接收问题,这里需要稍微做下转变,JDK7的时候需要先进行Integer类型强转,JDK8的Demo则如下,JDK8是不需要进行强转的。
到了JDK9以上的时候,就需要用到高版本的unsafe方法,这里给出的Demo如下:
至于注入内存马的问题,建议参考以下两篇文章:
https://xz.aliyun.com/t/9914
https://mp.weixin.qq.com/s/kfN6uU3A-jR72fyK8epnGw
confluence是以tomcat启动的,直接修改catalina.bat文件的debug配置即可:
confluence对应版本的JDK和tomcat信息可以参考官网信息:
https://confluence.atlassian.com/doc/bundled-tomcat-and-java-versions-1005786018.html
参考文章
https://xz.aliyun.com/t/9914
https://mp.weixin.qq.com/s/kfN6uU3A-jR72fyK8epnGw
https://paper.seebug.org/1785
https://www.cnblogs.com/nice0e3/p/14102892.html
https://docs.oracle.com/en/java/javase/16/migrate/migrating-jdk-8-later-jdk-releases.html#GUID-7744EF96-5899-4FB2-B34E-86D49B2E89B6
https://bugs.openjdk.java.net/browse/JDK-8266760
https://confluence.atlassian.com/doc/bundled-tomcat-and-java-versions-1005786018.html
作者:水木逸轩@深蓝攻防实验室
原文始发于微信公众号(谢公子学安全):CVE-2021-26084-Confluence命令执行 全版本内存马注入
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论