Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
shiro-cve-2020-17523 — Análisis de dos técnicas de bypass de la vulnerabilidad shiro-cve-2020-17523 y el entorno de vulnerabilidad asociado. | Kitploit
Herramientas/GitHubGitHub/jweny/shiro-cve-2020-17523
Autenticación y AutorizaciónAnálisis de VulnerabilidadesExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubjweny/shiro-cve-2020-17523

shiro-cve-2020-17523

Análisis de dos técnicas de bypass de la vulnerabilidad shiro-cve-2020-17523 y el entorno de vulnerabilidad asociado.

Ver Repositorio
11811hace 5 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Análisis de dos métodos para evadir la autenticación en Apache Shiro (CVE-2020-17523)

0x01 Descripción de la vulnerabilidad

Apache Shiro es un framework de seguridad Java potente y fácil de usar que realiza autenticación, autorización, gestión de contraseñas y sesiones. Con la API fácil de entender de Shiro, puede obtener rápida y fácilmente cualquier aplicación, desde la aplicación móvil más pequeña hasta las aplicaciones web y empresariales más grandes.

Cuando se utiliza junto con Spring, bajo ciertas reglas de coincidencia de permisos, un atacante puede evadir la autenticación mediante la construcción de paquetes de solicitud HTTP especiales.

Versiones afectadas: Apache Shiro < 1.7.1

0x02 Configuración del entorno de la vulnerabilidad

shiro 1.7.0

https://github.com/jweny/shiro-cve-2020-17523 Los entornos de vulnerabilidad de los dos métodos ya se han actualizado.

0x03 Prueba del PoC

Método uno:

http://127.0.0.1:8080/admin/%20 o http://127.0.0.1:8080/admin/%20/

El uso de caracteres en blanco como los espacios permite evadir la autenticación de Shiro.

image-20210205120522547

Método dos:

Tras intercambiar ideas con el maestro p0desta, se descubrió que existe otra forma de explotación en un escenario especial.

http://127.0.0.1:8080/admin/%2e o http://127.0.0.1:8080/admin/%2e/

Sin embargo, . (y también /) en las reglas de coincidencia de rutas de Spring representan separadores de ruta y no se comparan como caracteres normales. Por lo tanto, en condiciones predeterminadas, acceder a /admin/. devuelve 404.

Pero en el escenario de ruta completa habilitada, setAlwaysUseFullPath(true) permite una coincidencia normal.

image-20210205102100797

0x04 Análisis de la vulnerabilidad

En Shiro, la obtención y coincidencia de la URL se realiza en org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain.

Primero echemos un vistazo rápido a este método getChain:

carbon (2)

image-20210205103341569

Este método primero comprueba si requestURI termina con /; si es así, elimina el último /.

Luego, en el bucle de coincidencia de rutas, primero comprueba si el patrón de ruta pathPattern termina con /; si es así, también lo elimina. Después llama al método pathMatches() para realizar la coincidencia de rutas.

Por lo tanto, en los dos métodos de explotación, no importa si se termina con /, porque se elimina en cuanto se pasa por el método getChain.

4.1 Análisis de la evasión con espacios

Prestemos atención al método pathMatches():

Abra Evaluate y calcule respectivamente pathMatches("/admin/*","/admin/1") y pathMatches("/admin/*","/admin/ "); el primero coincide normalmente, mientras que el segundo falla.

image-20210203134044268

image-20210203134119174

Comience la depuración; al iniciarla, pasará por un largo proceso de F7. Hasta llegar a doMatch("/admin/*","/admin/ "). Se puede observar que los pathDirs devueltos por tokenizeToStringArray ya no contienen la segunda capa de la ruta. Por lo tanto, /admin/* y /admin no coinciden.

image-20210203150854085

Al rastrear el método tokenizeToStringArray, se descubre que, cuando se le llama, el parámetro trimTokens es true.

image-20210203150959413

Y el método tokenizeToStringArray, cuando el parámetro trimTokens es true, pasa por el procesamiento de trim(), lo que provoca que los espacios se eliminen. Al volver a getChain, el último / se elimina. Por lo tanto, los pathDirs devueltos por tokenizeToStringArray no contienen la segunda capa de la ruta.

image-20210203151053344

En resumen: en las versiones vulnerables de Shiro, dado que al llamar al método tokenizeToStringArray el parámetro trimTokens es true por defecto, los espacios pasan por el procesamiento de trim(), por lo que se eliminan. Al volver a getChain, el último / se elimina, de modo que /admin y /admin/* no coinciden, lo que provoca la evasión de la autenticación. Mientras tanto, la ruta de acceso que recibe Spring es /admin/%20 y devuelve la respuesta siguiendo la lógica normal, lo que resulta en la evasión de permisos.

4.2 Análisis de la evasión con /./

Al ver /. y /./ del segundo método, ¿no te recuerda a un método familiar? Exacto, es normalize().

carbon (3)

En pocas palabras:

CondiciónEjemplo
La barra normal se procesa como barra invertida\ -> /
La doble barra invertida se procesa como barra invertida

Por lo tanto, /admin/., después de procesarse como /admin/./, se convierte en /admin/.

image-20210205113301788

Después de pasar por el procesamiento de org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain, como termina en /, si es así, se elimina el último /, convirtiéndose en /admin. ``/adminno coincide con/admin/*`, por lo que se evita la autenticación de Shiro.

image-20210205113518970

Mientras tanto, la solicitud que recibe Spring es /admin/.. Si la coincidencia de ruta completa no está habilitada, en Spring . y / actúan como separadores de ruta y no participan en la coincidencia de rutas. Por lo tanto, no se encuentra ningún mapping y devuelve 404.

image-20210205114350972

Si la coincidencia de ruta completa está habilitada, se compara toda la URL, por lo que Spring devuelve 200.

Aquí se adjunta el código para habilitar la coincidencia de ruta completa:

root@kitploit:~
@SpringBootApplication
public class SpringbootShiroApplication extends SpringBootServletInitializer implements BeanPostProcessor {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootShiroApplication.class);
    }

    public static void main(String[] args) {

        SpringApplication.run(SpringbootShiroApplication.class, args);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping) bean).setAlwaysUseFullPath(true);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }
}

0x05 Solución oficial

Según el análisis anterior, las causas de la evasión de permisos de Shiro son dos:

  1. La función tokenizeToStringArray no maneja correctamente los espacios.
  2. La lógica de procesamiento del último / no debería estar antes de la lógica del bucle de coincidencia de rutas.

Por lo tanto, la solución oficial es:

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

  1. Establecer el parámetro trimTokens de tokenizeToStringArray en false.image-20210203154342100
  2. Ajustar la lógica de eliminación del último /. Modificarla para que primero se compare con la ruta original y, si la comparación falla, se ejecute la lógica de eliminar el último /.image-20210205115522098

0x06 Sobre trim

En teoría, trim() elimina todo el whitespace situado al principio y al final de la cadena; el espacio es solo uno de ellos. Sin embargo, en las pruebas se descubrió que otros whitespace distintos del espacio, como %08, %09, %0a, devuelven 400 al ser procesados por Spring + Tomcat.

Por lo tanto, para el primer método, aparte del espacio, aún no se han encontrado otros payloads útiles.

0x07 Referencias

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

https://www.anquanke.com/post/id/216096

https://www.cnblogs.com/syp172654682/p/9257282.html

Descargar herramienta
// -> /
Termina en /. o /.., se añade / al final/. -> /./ /.. -> /../
Normalización de /.//./ -> /
Salto de ruta/aaa/../bbb -> /bbb