Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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é.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2025-40019-POC — A Proof Of Concept for CVE-2025-40019 | Kitploit
Outils/GitHubGitHub/0xatharv/cve-2025-40019-poc
Memory ForensicsVulnerability AnalysisExploitationPapers & ResearchLearning & EducationBinary Exploitation
GitHub0xatharv/cve-2025-40019-poc

CVE-2025-40019-POC

A Proof Of Concept for CVE-2025-40019

Voir le dépôt
il y a 7 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 :

root@kitploit:~
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.

root@kitploit:~
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 :

root@kitploit:~
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.

root@kitploit:~

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

Lorsque nous fournissons assoclen < ivsize, cela entraîne ce crash. Ce bogue peut être exploitable en façonnant des objets sur le tas et en les plaçant à côté du scatterlist.

root@kitploit:~
root@syzkaller:/mnt/shared# ls
pwn  pwn.c
root@syzkaller:/mnt/shared# ./pwn
aad_len=8, ivsize=16
[   28.256679] BUG: kernel NULL pointer dereference, address: 000000000000000c
[   28.258348] #PF: supervisor read access in kernel mode
[   28.259377] #PF: error_code(0x0000) - not-present page
[   28.260349] PGD 0 P4D 0
[   28.260904] Oops: Oops: 0000 [#1] SMP PTI
[   28.261605] CPU: 0 UID: 0 PID: 178 Comm: pwn Not tainted 6.17.0-rc1-00082-gc0d36727bf39 #8 PREEMPT(voluntary)
[   28.263236] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014
[   28.264805] RIP: 0010:memcpy_to_sglist+0x3a/0x90
[   28.265607] Code: 00 41 54 55 53 48 83 ec 20 65 48 8b 05 27 31 c6 01 48 89 44 24 18 31 c0 48 89 e7 f3 ab 45 85 ed 74 3a 89 f3 49 89 d4 48 89 e5 <41> 8b 40 0c 39 d8 73 0fb
[   28.269176] RSP: 0018:ffffc900001e7c80 EFLAGS: 00010202
[   28.270229] RAX: 0000000000000000 RBX: 00000000ffffffb8 RCX: 0000000000000000
[   28.271392] RDX: ffff8881027a4930 RSI: 00000000fffffff8 RDI: ffff888102b3f820
[   28.272514] RBP: ffffc900001e7c80 R08: 0000000000000000 R09: 0000000000000000
[   28.273681] R10: 0000000000000011 R11: 0000000000000081 R12: ffff8881027a4930
[   28.274997] R13: 0000000000000010 R14: ffff888102b3fa90 R15: ffff888102b3f820
[   28.276423] FS:  00007fb27ef28540(0000) GS:ffff8881b8986000(0000) knlGS:0000000000000000
[   28.277835] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   28.278831] CR2: 000000000000000c CR3: 000000010298e000 CR4: 00000000000006f0
[   28.280253] Call Trace:
[   28.280723]  <TASK>
[   28.281147]  essiv_aead_crypt+0x6d/0x230
[   28.281845]  aead_recvmsg+0x442/0x500
[   28.282630]  sock_recvmsg_nosec+0x57/0x80
[   28.283493]  sock_read_iter+0x7a/0xc0
[   28.284209]  vfs_read+0x14c/0x1e0
[   28.284811]  ksys_read+0x74/0xc0
[   28.285368]  do_syscall_64+0xca/0x1c0
[   28.286120]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   28.287068] RIP: 0033:0x7fb27ee3e46e
[   28.287675] Code: c0 e9 b6 fe ff ff 50 48 8d 3d ce 07 0b 00 e8 69 01 02 00 66 0f 1f 84 00 00 00 00 00 64 8b 04 25 18 00 00 00 85 c0 75 14 0f 05 <48> 3d 00 f0 ff ff 77 5a8
[   28.290739] RSP: 002b:00007ffcc5ad39a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[   28.292152] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fb27ee3e46e
[   28.293253] RDX: 0000000000000040 RSI: 00007ffcc5ad3a60 RDI: 0000000000000004
[   28.294356] RBP: 00007ffcc5ad3ba0 R08: 0000000000000000 R09: 00007ffcc5ad3887
[   28.295495] R10: fffffffffffffd8d R11: 0000000000000246 R12: 000055995fbd3150
[   28.296693] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[   28.297842]  </TASK>
[   28.298208] Modules linked in:
[   28.298966] CR2: 000000000000000c
[   28.299630] ---[ end trace 0000000000000000 ]---
[   28.300389] RIP: 0010:memcpy_to_sglist+0x3a/0x90
[   28.301266] Code: 00 41 54 55 53 48 83 ec 20 65 48 8b 05 27 31 c6 01 48 89 44 24 18 31 c0 48 89 e7 f3 ab 45 85 ed 74 3a 89 f3 49 89 d4 48 89 e5 <41> 8b 40 0c 39 d8 73 0fb
[   28.304232] RSP: 0018:ffffc900001e7c80 EFLAGS: 00010202
[   28.305035] RAX: 0000000000000000 RBX: 00000000ffffffb8 RCX: 0000000000000000
[   28.306210] RDX: ffff8881027a4930 RSI: 00000000fffffff8 RDI: ffff888102b3f820
[   28.307396] RBP: ffffc900001e7c80 R08: 0000000000000000 R09: 0000000000000000
[   28.308668] R10: 0000000000000011 R11: 0000000000000081 R12: ffff8881027a4930
[   28.309798] R13: 0000000000000010 R14: ffff888102b3fa90 R15: ffff888102b3f820
[   28.310996] FS:  00007fb27ef28540(0000) GS:ffff8881b8986000(0000) knlGS:0000000000000000
[   28.312321] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   28.313229] CR2: 000000000000000c CR3: 000000010298e000 CR4: 00000000000006f0
Killed
Télécharger l’outil