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
codeql-workshop-cve-2021-21380 — Un taller de CodeQL que cubre CVE-2021-21380 | Kitploit
Herramientas/GitHubGitHub/rvermeulen/codeql-workshop-cve-2021-21380
Análisis EstáticoAnálisis de VulnerabilidadesAnálisis de CódigoSeguridad WebAprendizaje y EducaciónLabs y Práctica
GitHubrvermeulen/codeql-workshop-cve-2021-21380

codeql-workshop-cve-2021-21380

Un taller de CodeQL que cubre CVE-2021-21380

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
Ver Repositorio
125hace 1 añoAún no revisado

Taller de CodeQL para Java: Encontrar una inyección SQL

En este taller utilizaremos el razonamiento sintáctico y semántico para encontrar una inyección SQL en el componente de calificación de la plataforma XWiki documentado por CVE-2021-21380

Contenidos

  • Taller de CodeQL para Java: Encontrar una inyección SQL
    • Contenidos
    • Requisitos previos e instrucciones de configuración
      • En tu máquina local
        • Instalación
        • Pasos de configuración
    • Taller
      • Aprendizajes
      • Planteamiento del problema
      • Ejercicios
        • Ejercicio 1
        • Intermedio 1
        • Ejercicio 2
        • Ejercicio 3
        • Intermedio 2
        • Ejercicio 4
        • Ejercicio 5
        • Intermedio 3
        • Ejercicio 6
        • Ejercicio 7
        • Ejercicio 8
    • ¿Qué sigue?

Requisitos previos e instrucciones de configuración

En tu máquina local

Por favor, completa esta sección antes del taller, si es posible.

Instalación

  • Instala Visual Studio Code.

  • Instala la extensión CodeQL para Visual Studio Code.

  • No necesitas instalar la CLI de CodeQL: la extensión se encargará de esto por ti.

  • Clona este repositorio:

    root@kitploit:~
    git clone https://github.com/advanced-security/codeql-workshop-cve-2021-21380.git
    

Pasos de configuración

  • Importa la base de datos de CodeQL que se usará en el taller:
    • Haz clic derecho en el archivo xwiki-platform-CVE-2021-21380.zip en la vista del Explorador y selecciona el comando CodeQL: Set Current Database.
    • La base de datos aparecerá en la vista de bases de datos de CodeQL, accesible desde el icono de QL en la Barra de Actividades.
  • Instala las dependencias para analizar código Java y ejecutar las pruebas de los ejercicios y soluciones.
    • Desde la Paleta de Comandos (Cmd/Ctrl+Mayús+P), busca y ejecuta el comando CodeQL: Install Pack Dependencies.
    • En la parte superior de tu ventana de VS Code, escribe github en la caja para filtrar la lista.
    • Marca la casilla junto a cve-2021-21380-exercises, cve-2021-21380-exercises-tests, cve-2021-21380-solutions y cve-2021-21380-solutions-tests.
    • Haz clic en OK/Enter.
  • Valida que todo funcione como se espera ejecutando las pruebas de las soluciones.

Taller

Aprendizajes

El taller está dividido en varios ejercicios que introducen el soporte del lenguaje QL para Java y termina con una consulta final para encontrar la inyección SQL conocida. En estos ejercicios aprenderás:

  • Cómo razonar sobre información sintáctica.
  • Cómo razonar sobre información semántica.
  • Explorar el soporte del lenguaje QL para Java para expresar patrones.
  • Explorar cómo reutilizar y extender el modelado existente.
  • Usar múltiples bloques de construcción para componer la consulta final.

Planteamiento del problema

En este taller buscaremos vulnerabilidades de inyección SQL conocidas en el componente de API de calificaciones de la Plataforma XWiki. Tales vulnerabilidades pueden ocurrir en aplicaciones cuando información controlada por un usuario externo llega al código de la aplicación que construye de manera insegura una consulta SQL y la ejecuta.

La inyección SQL conocida que se discute en este taller está revisada en GHSA-79rg-7mv3-jrr5 en la Base de Datos de Avisos de GitHub. Para encontrar la inyección SQL, y posibles variantes, abordaremos los siguientes subproblemas:

  • Identificar la fuente de información no confiable y modelarla en QL.
  • Identificar el sumidero, el método que ejecuta consultas SQL, y modelarlo en QL.
  • Combinar las soluciones anteriores para determinar si hay un flujo de información entre la fuente y el sumidero usando seguimiento de contaminación (taint tracking).

Ejercicios

En los primeros ejercicios razonaremos sobre información sintáctica, usando el Árbol de Sintaxis Abstracta (AST), para identificar:

  • el método descrito en el aviso de seguridad para comprender la vulnerabilidad
  • parámetros que contienen datos no confiables, nuestras fuentes
  • llamadas a métodos que aceptan sentencias SQL, nuestros sumideros

Ejercicio 1

Encuentra todos los métodos con el nombre getAverageRating y su tipo declarante en el programa completando la consulta exercise1.ql

Pistas
  • El módulo java proporciona una clase Method para razonar sobre métodos en un programa.
  • La clase Method proporciona los predicados miembro getName y hasName para razonar sobre el nombre de un método.
  • La clase Method proporciona el miembro getDeclaringType para razonar sobre el tipo que declara el método.

Una solución se puede encontrar en la consulta exercise1.ql

Intermedio 1

Una solución al ejercicio 1 devuelve una lista de métodos. Algunos están definidos en una interfaz llamada RatingsManager y otros en las clases AbstractRatingsManager y RatingsScriptService.

De la información devuelta por la consulta y la documentación de componentes de XWiki podemos deducir que:

  • XWiki utiliza un diseño orientado a componentes para permitir extensiones y personalizaciones.
  • El método vulnerable es parte de un componente.
  • Un componente consiste en una interfaz, anotada con Role, y una implementación anotada con Component.
  • Un componente que extiende ScriptService se hace accesible a las páginas wiki a través de scripting.

Ejercicio 2

Encuentra todas las clases anotadas con la anotación Component completando la consulta exercise2.ql. Ten en cuenta que el nombre completamente calificado del tipo de la anotación es org.xwiki.component.annotation.Component.

Pistas
  • El tipo de dominio /clase/, la intersección de sus supertipos, se puede acceder usando la palabra clave this en el predicado característico.
  • La clase Class proporciona un método getAnAnnotation para obtener las anotaciones asociadas.
  • La clase Annotation proporciona el predicado miembro getType para razonar sobre su tipo.
  • La clase Type proporciona los predicados miembro getName y hasName para razonar sobre el nombre de un tipo.
  • La clase RefType, que representa clases e interfaces, proporciona los predicados miembro getQualifiedName y hasQualifiedName para razonar sobre el nombre completamente calificado del reftype.

Una solución se puede encontrar en la consulta exercise2.ql

Ejercicio 3

Encuentra todos los componentes que implementan la interfaz ScriptService completando la consulta excercise3.ql

Pistas
  • El tipo Class proporciona el predicado miembro getASuperType para razonar sobre los supertipos de una clase, es decir, los tipos que extiende o implementa.

Una solución se puede encontrar en la consulta exercise3.ql

Intermedio 2

En este punto hemos identificado sintácticamente los métodos que pueden ser llamados por un usuario y cuyos parámetros consideraremos fuentes de datos no confiables más adelante en el taller.

En el siguiente ejercicio vamos a investigar e identificar posibles sumideros. De los resultados del ejercicio 1 podemos deducir que una de las implementaciones llama al método getAverageRatingFromQuery. Usando una consulta similar podemos encontrar los tipos declarantes de getAverageRatingFromQuery, lo que nos permite establecer que la implementación en la clase AbstractRatingsManager construye una sentencia SQL que se pasa al método search.

El método search está implementado en una dependencia y, por lo tanto, su implementación no está disponible. En los siguientes ejercicios vamos a usar la información de tipo disponible para identificar esta llamada al método search y su tipo declarante.

Ejercicio 4

Encuentra todas las llamadas a métodos al método search e identifica su tipo declarante completando la consulta exercise4.ql

Pistas
  • El tipo MethodCall nos proporciona los medios para razonar sobre llamadas a métodos.
  • El tipo MethodAccess proporciona el predicado miembro getMethod para razonar sobre el destino de una llamada a método.

Una solución se puede encontrar en la consulta exercise4.ql

Ejercicio 5

Encuentra todas las llamadas a métodos declarados por la interfaz XWikiStorageInterface (con el nombre calificado com.xpn.xwiki.store.XWikiStoreInterface) completando la consulta exercise5.ql

Pistas
  • La palabra clave instanceof se puede usar para afirmar que un valor pertenece al conjunto de valores representados por un tipo. Por ejemplo, para identificar todas las llamadas a métodos de interfaz:

    root@kitploit:~
    import java
    
    from MethodCall ma
    where ma.getMethod.getDeclaringType() instanceof Interface
    select ma
    

Una solución se puede encontrar en la consulta exercise5.ql

Intermedio 3

En este punto hemos descrito sintácticamente posibles fuentes y sumideros usando QL. Para determinar si la información fluye entre estos puntos en el programa, vamos a analizar semánticamente el programa usando seguimiento de contaminación. Las bibliotecas estándar de los lenguajes que soportamos proporcionan dos mecanismos de flujo de datos:

  1. El módulo DataFlow soporta flujo de información que preserva los valores.
  2. El módulo TaintTracking soporta flujo de información incluso si los valores son modificados.

Este último es de interés, porque en vulnerabilidades de inyección como la inyección SQL es común que los datos no confiables se conviertan en parte de una sentencia más grande sobre la que se actúa.

En este taller vamos a reutilizar una configuración existente de seguimiento de contaminación para inyección SQL y extenderla con nuestras fuentes y sumideros modelados para encontrar la inyección SQL. Para entender cómo podemos extender la configuración, comenzamos mirando la definición de la configuración a continuación.

root@kitploit:~
class QueryInjectionFlowConfig extends TaintTracking::Configuration {
  QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }

  override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

  override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }

  override predicate isSanitizer(DataFlow::Node node) {
    node.getType() instanceof PrimitiveType or
    node.getType() instanceof BoxedType or
    node.getType() instanceof NumberType
  }

  override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
    any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
  }
}

Tanto el predicado isSource como isSink utilizados por la configuración para identificar esas ubicaciones del programa usan la palabra clave instanceof que hemos visto antes. Tanto la clase RemoteFlowSource como QueryInjectionSink son clases abstract. Este es un patrón común que encontrarás en las bibliotecas estándar y este patrón nos permite extender el conjunto de valores representados por las clases RemoteFlowSource y QueryInjectionSink. Una class de QL que extiende una abstract class no refina el conjunto de valores representados por la superclase, sino que agrega los valores representados por la subclase a la superclase.

En los siguientes ejercicios vamos a implementar estas subclases y construir nuestra consulta final.

Ejercicio 6

Extiende el conjunto de valores de RemoteFlowSource con los parámetros de los métodos públicos de las clases de componentes identificadas en el ejercicio 3 completando la consulta exercise6.ql.

Pistas
  • La palabra clave instanceof se puede usar para afirmar que un valor pertenece al conjunto de valores representados por un tipo. Por ejemplo, para identificar todas las llamadas a métodos de interfaz:

    root@kitploit:~
    import java
    
    from MethodCall ma
    where ma.getMethod.getDeclaringType() instanceof Interface
    select ma
    

Una solución se puede encontrar en la consulta exercise6.ql

Ejercicio 7

Extiende el conjunto de valores de QueryInjectionSink con los argumentos de las llamadas a los métodos de la interfaz de almacenamiento identificados en el ejercicio 5 completando la consulta exercise7.ql

Pistas
  • La fórmula exists permite la introducción de variables temporales sobre las que se puede razonar en el ámbito del exists.

    El siguiente ejemplo usa la expresión exists para reducir el conjunto de métodos a aquellos que son llamados.

    root@kitploit:~
    from Method m
    where m.hasName("foo") and exists(MethodCall ma | ma.getMethod() = m)
    select m
    
  • La clase MethodCall proporciona el predicado miembro getQualifier para razonar sobre el calificador del acceso al método.

Una solución se puede encontrar en la consulta exercise7.ql

Ejercicio 8

Combina tus soluciones de los ejercicios anteriores en una solución final completando la consulta exercise8.ql.

Una solución se puede encontrar en la consulta exercise8.ql

¿Qué sigue?

  • La consulta incluye un módulo para modelar partes del framework XWiki. Refactorízalo en su propio archivo de módulo y úsalo en tu consulta.
  • Limitamos nuestra fuente de datos no confiables a componentes de servicio de script. Mira cómo expandir esto con otras fuentes.
  • Para el sumidero nos limitamos al uso directo de XWikiStoreInterface. Expande el sumidero para incluir usos directos de implementaciones de la interfaz. La clase Class proporciona el predicado miembro extendsOrImplements y la clase Method proporciona el predicado miembro overridesOrInstantiates que pueden ser de ayuda.
  • Usa la definición de fuentes para encontrar usos interesantes de datos no confiables con la consulta 'Untrusted data passed to external API'
Descargar herramienta
  • Abre la vista de pruebas y presiona ejecutar pruebas (el icono de reproducción aparece al pasar el ratón sobre las soluciones) junto al elemento de soluciones en el árbol.