Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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
CVE-2025-40019-POC — Una prueba de concepto para CVE-2025-40019 | Kitploit
Herramientas/GitHubGitHub/0xatharv/cve-2025-40019-poc
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHub0xatharv/cve-2025-40019-poc

CVE-2025-40019-POC

Una prueba de concepto para CVE-2025-40019

Ver Repositorio
8hace 8 mesesAún no revisado

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

prueba de concepto para CVE-2025-40019

CVE-2025-40019 es el mecanismo de Vector de Inicialización Sal-Sector Cifrado (crypto/essiv.c) que tiene una validación insuficiente de la longitud de los Datos de Autenticación Asociados (AAD) en relación con el tamaño del Vector de Inicialización (IV), lo que provoca un acceso a memoria fuera de los límites. El código proporcionado en este repositorio es solo un desencadenante del error, pero este error es fácilmente explotable.

Entrada de KernelCTF

Me topé con este error en la hoja de cálculo de kernelctf aquí. Como no había ningún blogpost o prueba de concepto asociado con este error, decidí explorar el subsistema criptográfico del kernel de Linux para descubrir qué causó el problema.

img

Antecedentes: Teoría del Cifrado de Disco y ESSIV

Para entender la necesidad de ESSIV, debemos observar cómo se almacenan los datos en el disco. El cifrado de disco (como LUKS o dm-crypt) normalmente opera en sectores. Cada sector debe cifrarse de forma independiente para que leer un sector no requiera leer todo el disco.

El Ataque de Marca de Agua

En el modo CBC (Cipher Block Chaining) estándar, se requiere un Vector de Inicialización (IV) para cada operación de cifrado. Las implementaciones tempranas de cifrado de disco usaban el Número de Sector como el IV.

Sin embargo, debido a que los números de sector son predecibles, un atacante puede realizar un "ataque de marca de agua". Al escribir datos especialmente diseñados en un sector conocido, el atacante puede observar patrones en el texto cifrado que revelan la presencia de archivos específicos, eludiendo efectivamente la confidencialidad del cifrado.

La Solución ESSIV

ESSIV (Encrypted Salt-Sector Initialization Vector) fue diseñado para hacer que el IV sea impredecible. Funciona de la siguiente manera:

  1. Aplica hash a la clave de cifrado secreta ($K$) para derivar una "Sal" ($S = H(K)$).
  2. Cifra el Número de Sector ($SN$) usando un cifrado separado con la Sal como clave ($IV = E_S(SN)$).
  3. El $IV$ resultante se usa luego para el cifrado real de los datos de ese sector.

Esto asegura que incluso si un atacante conoce el número de sector, no puede predecir el IV sin conocer la clave secreta.


Cada algoritmo, ya sea un cifrado base como AES o un envoltorio como ESSIV, implementa una estructura que el kernel usa para enrutar las llamadas:

struct skcipher_alg {
    int (*setkey)(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen);
    int (*encrypt)(struct skcipher_request *req);
    int (*decrypt)(struct skcipher_request *req);
    // ...
    struct skcipher_alg_common co; // Contiene ivsize, chunksize, etc.
};

Causa Raíz

La vulnerabilidad es un caso clásico de asumir que los metadatos proporcionados por el usuario (la longitud de AAD) siempre satisfarán los requisitos internos de la transformación criptográfica. En la ruta "in-place" o de descifrado (!enc), el código calcula un desplazamiento: req->assoclen - crypto_aead_ivsize(tfm). Pero nunca verifica si req->assoclen < ivsize. lo que significa que este desplazamiento puede ser negativo.

static int essiv_aead_crypt(struct aead_request *req, bool enc)
{
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	const struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
	struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
	struct aead_request *subreq = &rctx->aead_req;
	struct scatterlist *src = req->src;
	int err;

	crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv);

	/*
	 * dm-crypt incrusta el número de sector y el IV en la región AAD, por lo que
	 * debemos copiar el IV convertido en el scatterlist correcto antes
	 * de pasarlo.
	 */
	rctx->assoc = NULL;
	if (req->src == req->dst || !enc) {
		scatterwalk_map_and_copy(req->iv, req->dst,
					 req->assoclen - crypto_aead_ivsize(tfm),    // <------- error !
					 crypto_aead_ivsize(tfm), 1);
	} else {
		u8 *iv = (u8 *)aead_request_ctx(req) + tctx->ivoffset;
		int ivsize = crypto_aead_ivsize(tfm);
		int ssize = req->assoclen - ivsize;
		struct scatterlist *sg;
		int nents;
        .
        .
        .

Observando la función scatterwalk_map_and_copy, podemos ver que simplemente hace memcpy al scatterlist sg:

static inline void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
					    unsigned int start,
					    unsigned int nbytes, int out)
{
	if (out)
		memcpy_to_sglist(sg, start, buf, nbytes);
	else
		memcpy_from_sglist(buf, sg, start, nbytes);
}

El Parche

El parche para este error fue muy simple: solo verifica si assoclen es menor que ivsize.


diff --git a/crypto/essiv.c b/crypto/essiv.c
index d003b78fcd855a..a47a3eab693519 100644
--- a/crypto/essiv.c
+++ b/crypto/essiv.c
@@ -186,9 +186,14 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc)
 	const struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
 	struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
 	struct aead_request *subreq = &rctx->aead_req;
+	int ivsize = crypto_aead_ivsize(tfm);
+	int ssize = req->assoclen - ivsize;
 	struct scatterlist *src = req->src;
 	int err;
 
+	if (ssize < 0)
+		return -EINVAL;
+
 	crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv);
 
 	/*
@@ -198,19 +203,12 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc)
 	 */
 	rctx->assoc = NULL;
 	if (req->src == req->dst || !enc) {
-		scatterwalk_map_and_copy(req->iv, req->dst,
-					 req->assoclen - crypto_aead_ivsize(tfm),
-					 crypto_aead_ivsize(tfm), 1);
+		scatterwalk_map_and_copy(req->iv, req->dst, ssize, ivsize, 1);
 	} else {
 		u8 *iv = (u8 *)aead_request_ctx(req) + tctx->ivoffset;
-		int ivsize = crypto_aead_ivsize(tfm);
-		int ssize = req->assoclen - ivsize;
 		struct scatterlist *sg;
 		int nents;
 
-		if (ssize < 0)
-			return -EINVAL;
-
 		nents = sg_nents_for_len(req->src, ssize);
 		if (nents < 0)
 			return -EINVAL;

Caída

Descargar herramienta