Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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를 재현합니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

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. 애플리케이션 시작

    启动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 구현 로직은 다음과 같습니다:
/*
 * 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;
   }
}
도구 다운로드