Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2025-40019-POC — Une preuve de concept pour CVE-2025-40019 | Kitploit
Outils/GitHubGitHub/0xatharv/cve-2025-40019-poc
Criminalistique MémoireAnalyse des VulnérabilitésExploitationArticles et RechercheApprentissage et ÉducationExploitation de Binaires
GitHub0xatharv/cve-2025-40019-poc

CVE-2025-40019-POC

Une preuve de concept pour CVE-2025-40019

Voir le dépôt
9il y a 8 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

preuve de concept pour CVE-2025-40019

CVE-2025-40019 concerne le mécanisme de vecteur d'initialisation encrypté salt-sector (crypto/essiv.c) qui présente une validation insuffisante de la longueur des données d'authentification associées (AAD) par rapport à la taille du vecteur d'initialisation (IV), entraînant un accès mémoire hors limites. Le code fourni dans ce dépôt est simplement un déclencheur de bogue, mais ce bogue est facilement exploitable.

Entrée KernelCTF

Je suis tombé sur ce bogue dans le tableur kernelctf ici. Comme il n'y avait ni billet de blog ni PoC associé à ce bogue, j'ai décidé d'explorer le sous-système crypto du noyau Linux pour comprendre ce qui causait le problème.

img

Contexte : Théorie du chiffrement de disque et ESSIV

Pour comprendre la nécessité d'ESSIV, nous devons examiner comment les données sont stockées sur le disque. Le chiffrement de disque (comme LUKS ou dm-crypt) fonctionne généralement sur des secteurs. Chaque secteur doit être chiffré indépendamment afin que la lecture d'un secteur n'exige pas la lecture de tout le disque.

L'attaque par tatouage

En mode CBC (Cipher Block Chaining) standard, un vecteur d'initialisation (IV) est requis pour chaque opération de chiffrement. Les premières implémentations de chiffrement de disque utilisaient le numéro de secteur comme IV.

Cependant, parce que les numéros de secteur sont prévisibles, un attaquant peut effectuer une "attaque par tatouage". En écrivant des données spécialement conçues sur un secteur connu, l'attaquant peut observer des motifs dans le texte chiffré qui révèlent la présence de fichiers spécifiques, contournant ainsi efficacement la confidentialité du chiffrement.

La solution ESSIV

ESSIV (Encrypted Salt-Sector Initialization Vector) a été conçu pour rendre l'IV imprévisible. Il fonctionne en :

  1. Hachant la clé de chiffrement secrète ($K$) pour dériver un "sel" ($S = H(K)$).
  2. Chiffrant le numéro de secteur ($SN$) à l'aide d'un chiffrement séparé avec le sel comme clé ($IV = E_S(SN)$).
  3. L'$IV$ résultant est ensuite utilisé pour le chiffrement réel des données de ce secteur.

Cela garantit que même si un attaquant connaît le numéro de secteur, il ne peut pas prédire l'IV sans connaître la clé secrète.


Chaque algorithme, qu'il s'agisse d'un chiffrement de base comme AES ou d'un wrapper comme ESSIV, implémente une structure que le noyau utilise pour acheminer les appels :

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; // Contient ivsize, chunksize, etc.
};

Cause racine

La vulnérabilité est un cas classique où l'on suppose que les métadonnées fournies par l'utilisateur (la longueur AAD) satisferont toujours les exigences internes de la transformation cryptographique. Dans le chemin "sur place" ou de déchiffrement (!enc), le code calcule un décalage : req->assoclen - crypto_aead_ivsize(tfm). Mais il ne vérifie jamais si req->assoclen < ivsize. ce qui signifie que ce décalage peut être négatif.

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 intègre le numéro de secteur et l'IV dans la région AAD, donc
	 * nous devons copier l'IV converti dans le bon scatterlist avant de le transmettre.
	 */
	rctx->assoc = NULL;
	if (req->src == req->dst || !enc) {
		scatterwalk_map_and_copy(req->iv, req->dst,
					 req->assoclen - crypto_aead_ivsize(tfm),    // <------- bogue !
					 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;
        .
        .
        .

En regardant la fonction scatterwalk_map_and_copy, on voit qu'elle copie simplement en mémoire vers le 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);
}

Le correctif

Le correctif pour ce bogue était très simple : il vérifie simplement si assoclen est inférieur à 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;

Crash

Télécharger l’outil