Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
shiro-cve-2022-32532 — 최소한의 Java 웹 애플리케이션으로, URL의 개행 문자를 통한 Apache Shiro RegExPatternMatcher 인증 우회 취약점인 CVE-2022-32532를 재현합니다. | Kitploit
도구/GitHubGitHub/my0113/shiro-cve-2022-32532
Authentication & AuthorizationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubmy0113/shiro-cve-2022-32532

shiro-cve-2022-32532

최소한의 Java 웹 애플리케이션으로, URL의 개행 문자를 통한 Apache Shiro RegExPatternMatcher 인증 우회 취약점인 CVE-2022-32532를 재현합니다.

저장소 보기
21년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Apache Shiro CVE-2022-32532 재현 환경

CVE-2022-32532(Apache Shiro RegExPatternMatcher 인증 우회)를 재현하기 위한 최소한의 Web 애플리케이션입니다.

취약점 설명

  • CVE: CVE-2022-32532
  • 영향 버전: Shiro < 1.9.1
  • 원인: RegExPatternMatcher가 정규식을 올바르게 앵커링하지 않아 경로 우회가 발생할 수 있습니다. 구체적으로 Java의 기본 정규식 매칭 로직을 사용하면 정규식에서 . 기호를 만날 때 \r(%0d), \n(%0a) 같은 특수 문자를 무시합니다. \r, \n 문자를 올바르게 처리하려면 PATTERN.DOTALL 모드 기반의 정규식 매칭 규칙을 명시적으로 사용해야 합니다. 그런데 shiro-1.9.1 미만 버전은 모두 기본 정규식 매칭 로직을 사용하므로 \r, \n을 올바르게 처리하지 못해 인증 우회가 발생합니다.

재현 방법

  1. 애플리케이션 시작

    root@kitploit:~
    启动ShiroCve202232532Application
    
    
  2. Shiro 정상 인증을 통과하면 access denied를 반환하는 URL은 다음과 같습니다.
    http://localhost:8080/permit/xxx, 맨 마지막의 xxx는 임의의 문자로 바꿀 수 있습니다.

  3. Shiro 인증을 우회하면 success를 반환하는 URL은 다음과 같습니다.
    http://localhost:8080/permit/xxx, 즉 맨 마지막의 xxx에 줄 바꿈 문자 \n(%0a), 캐리지 리턴 문자 \r(%0d)를 삽입하면 됩니다.

  4. 해결 방법

    1. https://github.com/apache/shiro/blob/shiro-root-1.9.1/core/src/main/java/org/apache/shiro/util/ 에서 RegExPatternMatcher.java와 PatternMatcher.java의 전체 내용을 복사합니다.
    2. jdk11을 사용하여 이 두 java 파일을 RegExPatternMatcher.class와 PatternMatcher.class로 컴파일합니다.
    3. WinRAR을 사용하여 이 2개의 class 파일을 shiro-core-1.6.0.jar의 org/apache/shiro/util/ 아래에 넣습니다.
    4. 수정 테스트는 shiro-core-1.9.1의 RegExPatternMatcher.java 코드를 본 사례에 복사하여 RegExPatternMatcher191.java로 변경한 다음, MyFilter 15행과 MyShiroFilterFactoryBean 29행의 new RegExPatternMatcher()를 new RegExPatternMatcher191()로 바꾸면 됩니다.
    5. shiro-core-1.9.1의 RegExPatternMatcher 구현 로직은 다음과 같습니다:
root@kitploit:~
/*
 * 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.
 */
package org.apache.shiro.util;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * {@code PatternMatcher} implementation that uses standard {@link java.util.regex} objects.
 *
 * @see Pattern
 * @since 1.0
 */
public class RegExPatternMatcher implements PatternMatcher {

   private static final int DEFAULT = Pattern.DOTALL;

   private static final int CASE_INSENSITIVE = DEFAULT | Pattern.CASE_INSENSITIVE;

   private boolean caseInsensitive = false;

   /**
    * Simple implementation that merely uses the default pattern comparison logic provided by the
    * JDK.
    * <p/>This implementation essentially executes the following:
    * <pre>
    * Pattern p = Pattern.compile(pattern, Pattern.DOTALL);
    * Matcher m = p.matcher(source);
    * return m.matches();</pre>
    * @param pattern the pattern to match against
    * @param source  the source to match
    * @return {@code true} if the source matches the required pattern, {@code false} otherwise.
    */
   public boolean matches(String pattern, String source) {
      if (pattern == null) {
         throw new IllegalArgumentException("pattern argument cannot be null.");
      }
      Pattern p = Pattern.compile(pattern, caseInsensitive ? CASE_INSENSITIVE : DEFAULT);
      Matcher m = p.matcher(source);
      return m.matches();
   }

   /**
    * Returns true if regex match should be case-insensitive.
    * @return true if regex match should be case-insensitive.
    */
   public boolean isCaseInsensitive() {
      return caseInsensitive;
   }

   /**
    * Adds the Pattern.CASE_INSENSITIVE flag when compiling patterns.
    * @param caseInsensitive true if patterns should match case-insensitive.
    */
   public void setCaseInsensitive(boolean caseInsensitive) {
      this.caseInsensitive = caseInsensitive;
   }
}
도구 다운로드