Fecha de publicación: Mar, 11/01/2022 - 09:17

Alerta de seguridad

Nivel de peligrosidad: Alto

CVE-2022–21661

Descripción

El núcleo de wordpress proporciona funciones para que los complementos (plugins) llamen y usen las funciones nativas de wordpress, como: formato de datos, consultas a la BD, etc. Entre las clases que proporciona wordpress, se ha encontrado que la clase utlizada para realizar consultas a la base de datos (WP_Query) es vulnerable a inyección SQL.

Análisis de errores

En la versión 5.8.3, wordpress ha corregido este error, en la comparación de cambios se puede ver que en la función `clean_query` se ha agregado una verificación `$query['field']` antes de procesar la variable `$query['terms']`. 

 

Comparación de código fuente con la actualización

 

La función `clean_query` se llama desde `get_sql_for_clause`. Al verificar el código de la función, se puede ver que el rol de esta función es crear cláusulas para la condición en una consulta SQL, específicamente su rol será procesar los datos recibidos, combinar esos datos en una condición en la consulta SQL y devolverla a la función principal. Por tanto, se pueden controlar los datos de retorno de esta función, lo que significa que podemos controlar la consulta SQL y realizar la inyección SQL. 

 

código fuente de la función get_sql_for_clause

 

Volviendo a la función `clean_query`, cuando no se ha realizado este cambio, por defecto los valores en `$query['terms']` solo se borrarán y luego se llamará a `$this->transform_query( $query, 'term_taxonomy_id');` . 

Para evitar caer en `if` (fila 561 en el gráfico), `$query['taxonomy']` debe estar vacío o se debe ingresar un valor para que al comparar en `is_taxonomy_hierarchical` devuelva `false`. 

 

Código fuente WordPress

 

La función `transform_query` verificará si `$query['field'] == $resulting_field`, en caso afirmativo, regresará y no hará más procesamiento, por lo que si la variable `$query['field']` es igual a `term_taxonomy_id`, podemos salir de la función sin cambiar el valor de la variable  `$query['terms']`.

 

Código fuente WordPress

 

Después de salir de la función, el flujo de código de regreso a la posición llamará a `clean_query` una función `get_sql_for_clause`. El valor de la variable `$query['terms']` se usará directamente como condición de consulta SQL y conducirá a la inyección SQL.

 

Código fuente WordPress

 

Entonces, en resumen, para que ocurra la inyección SQL, se deben cumplir dos condiciones:

- Que `$query['field']` sea igual a `term_taxonomy_id`

- Que `$query['taxonomy']` sea vacío o `is_taxonomy_hierarchical($query['taxonomy']) === false`

El flujo da como resultado el siguiente error:

 

Error que evidencia la vulnerabilidad a SQLi

 

Explotación

Aunque este error es del núcleo de wordpress, la forma en que el núcleo de wordpress lo usa no desencadena el error, por lo que el error se presenta en complementos (plugins) que realicen llamadas a la clase `WP_Query`, es decir cuando se realicen consultas a la base de datos. La forma de identificar el error es cuando el complemento usa `WP_Query($data)` y el parámetro `$data` se puede controlar.

Por ejemplo, `new WP_Query(json_decode($_POST['query_vars']))`, la carga útil (Payload) sería de la siguiente forma:

 

`query_vars = {"tax_query": {"0": {"field": "term_taxonomy_id", "terms": ["<inject>"]}}}

o

query_vars = {"tax_query": {"0": {"taxonomy": "nav_menu", "field": true, "terms": ["<inject>"]}}}` 

La manera más sencilla de identificar la vulnerabilidad es cuando el modo de depuración (modo debug) está habilitado.

Captura de paquete que evidencia la existencia de la vulnerabilidad

 

Recursos afectados

WP_Query, core de wordpress anteriores a 5.8.3

Solución/Mitigación

Actualizar WordPress a la versión 5.8.3.

Recomendaciones

Debido a que muchos complementos realizan consultas a la base de datos, se recomienda actualizar WordPress de manera urgente a la versión 5.8.3, también es recomendable mantener activa las actualizaciones automáticas.

Referencias

SQL Injection in Wordpress core (CVE-2022–21661)

WordPress Core WP_Query SQL Injection Information Disclosure Vulnerability