
Applicazione web Java minima per riprodurre CVE-2022-32532, un bypass dell'autenticazione Apache Shiro RegExPatternMatcher tramite caratteri newline negli URL.
Questa è un'applicazione Web minimale per riprodurre CVE-2022-32532 (bypass dell'autenticazione Apache Shiro RegExPatternMatcher).
RegExPatternMatcher non esegue un ancoraggio corretto dell'espressione regolare, il che può consentire un bypass del percorso. Nello specifico, usa la logica di corrispondenza delle regex predefinita di Java: quando il simbolo . viene usato come espressione regolare, ignora caratteri speciali come \r (%0d) e \n (%0a). È necessario usare esplicitamente una regola di corrispondenza basata sulla modalità Pattern.DOTALL per gestire correttamente i simboli \r e \n. Le versioni precedenti a shiro-1.9.1, invece, usano tutte la logica di corrispondenza predefinita, quindi non gestiscono correttamente \r e \n, causando il bypass dell'autenticazione.Avvia l'applicazione
启动ShiroCve202232532Application
L'URL che con l'autenticazione Shiro normale restituisce access denied è il seguente
http://localhost:8080/permit/xxx, dove l'ultimo xxx può essere sostituito con qualsiasi carattere
L'URL che aggira l'autenticazione Shiro e restituisce success è il seguente
http://localhost:8080/permit/xxx, cioè inserire nell'ultimo xxx il carattere di nuova riga \n (%0a) o il ritorno a capo \r (%0d)
Soluzione
1)Copia l'intero contenuto di RegExPatternMatcher.java e PatternMatcher.java da https://github.com/apache/shiro/blob/shiro-root-1.9.1/core/src/main/java/org/apache/shiro/util/.
2)Usa jdk11 per compilare questi due file Java in RegExPatternMatcher.class e .
3)Usa WinRAR per inserire questi 2 file class in all'interno di .
4)Per il test di verifica della correzione, copia il codice di da in questo progetto, rinominandolo in ; poi sostituisci alla riga 15 di e alla riga 29 di con . E il gioco è fatto.
5)La logica di implementazione di in è la seguente:
/*
* 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;
}
}
PatternMatcher.classorg/apache/shiro/util/shiro-core-1.6.0.jarRegExPatternMatcher.javashiro-core-1.9.1RegExPatternMatcher191.javanew RegExPatternMatcher()MyFilterMyShiroFilterFactoryBeannew RegExPatternMatcher191()RegExPatternMatchershiro-core-1.9.1