
Демонстрации proof-of-concept и библиотека libkdump, демонстрирующие микропроцессорную атаку Meltdown, приводящую к утечке памяти ядра и физической памяти на уязвимых процессорах Intel.
Этот репозиторий содержит несколько приложений, демонстрирующих уязвимость Meltdown. Техническую информацию об уязвимости см. в статье:
Приложения в этом репозитории собраны с использованием libkdump — библиотеки, разработанной нами для статьи. Эта библиотека упрощает эксплуатацию уязвимости за счёт автоматической адаптации к определённым свойствам окружения.
Этот репозиторий содержит несколько видео, демонстрирующих Meltdown
Этот репозиторий содержит пять демонстраций, показывающих различные варианты использования. Все демонстрации протестированы на Ubuntu 16.04 с Intel Core i7-6700K, но должны работать на любой системе Linux с любым современным процессором Intel, выпущенным после 2010 года.
Для наилучших результатов мы рекомендуем быстрый процессор с поддержкой Intel TSX (например, любой Intel Core i7-5xxx, i7-6xxx или i7-7xxx). Кроме того, каждую демонстрацию следует привязать к одному ядру CPU, например, с помощью taskset.
В качестве предварительного условия необходимо установить glibc-static на вашей машине.
Для систем на основе RPM:
sudo yum install -y glibc-static
test)Это самая базовая демонстрация. Она использует Meltdown для чтения доступных адресов из собственного адресного пространства, не нарушая никаких механизмов изоляции.
Если эта демонстрация не работает у вас, остальные, скорее всего, тоже не будут работать. Причины могут быть разными, например: процессор может быть слишком медленным, не поддерживать внеочередное исполнение, таймер высокого разрешения может быть недостаточно точным (особенно в виртуальных машинах), операционная система может не поддерживать пользовательские обработчики сигналов и т. д.
make
taskset 0x1 ./test
Если вы увидите вывод, похожий на этот
Expect: Welcome to the wonderful world of microarchitectural attacks
Got: Welcome to the wonderful world of microarchitectural attacks
значит, базовая демонстрация работает.
kaslr)Начиная с ядра Linux 4.12, KASLR (Kernel Address Space Layout Randomization — рандомизация размещения адресного пространства ядра) активна по умолчанию. Это означает, что расположение ядра (а также прямой физической карты, которая отображает всю физическую память) меняется при каждой перезагрузке.
Эта демонстрация использует Meltdown для утечки (секретной) рандомизации прямой физической карты. Для ускорения процесса этой демонстрации требуются права root. В статье описан вариант, не требующий прав root.
make
sudo taskset 0x1 ./kaslr
Через несколько секунд вы должны увидеть что-то похожее на это
[+] Direct physical map offset: 0xffff880000000000
reliability)Эта демонстрация проверяет, насколько надёжно можно читать физическую память. Для этой демонстрации вам либо нужно смещение прямой физической карты (например, из демонстрации №2), либо необходимо отключить KASLR, указав nokaslr в командной строке ядра.
Соберите и запустите reliability. Если у вас включён KASLR, первый параметр — это смещение прямой физической карты. В противном случае программа не требует параметров.
make
sudo taskset 0x1 ./reliability 0xffff880000000000
Через несколько секунд вы должны получить вывод, похожий на этот:
[-] Success rate: 99.93% (read 1354 values)
physical_reader)Эта демонстрация читает память другого процесса, напрямую считывая физическую память. Для этой демонстрации вам либо нужно смещение прямой физической карты (например, из демонстрации №2), либо необходимо отключить KASLR, указав nokaslr в командной строке ядра.
В принципе, эта программа может читать произвольные физические адреса. Однако, поскольку физическая память содержит много нечитаемых человеком данных, мы предоставляем тестовый инструмент (secret), который помещает читаемую человеком строку в память и напрямую сообщает физический адрес этой строки.
Для демонстрации сначала запустите secret (от имени root), чтобы получить физический адрес читаемой человеком строки:
make
sudo ./secret
Он должен вывести что-то вроде этого:
[+] 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
Пока программа secret работает, запустите physical_reader. Первый параметр — это физический адрес, выведенный secret. Если у вас не отключён KASLR, второй параметр — это смещение прямой физической карты.
taskset 0x1 ./physical_reader 0x390fff400 0xffff880000000000
Через несколько секунд вы должны получить вывод, похожий на этот:
[+] Physical address : 0x390fff400
[+] Physical offset : 0xffff880000000000
[+] Reading virtual address: 0xffff880390fff400
If you can read this, this is really bad
memdump)Эта демонстрация выгружает содержимое памяти. Как и демонстрации №3 и №4, она использует прямую физическую карту для выгрузки содержимого физической памяти в формате, подобном hexdump.
Опять же, поскольку физическая память содержит много нечитаемых человеком данных, мы предоставляем тестовый инструмент для заполнения больших объёмов физической памяти читаемыми человеком строками.
Для демонстрации сначала запустите memory_filler, чтобы заполнить память читаемыми человеком строками. Первый аргумент — это объём памяти (в гигабайтах) для заполнения.
make
./memory_filler 9
Затем запустите инструмент memdump для выгрузки содержимого памяти. Если вы до этого запускали memory_filler, вы должны увидеть некоторые фрагменты строк.
Если у вас запущены Firefox или Chrome с несколькими вкладками, вы также можете увидеть части открытых или недавно закрытых веб-сайтов.
Первый параметр — это физический адрес, с которого должен начаться дамп (оставьте пустым, чтобы начать с первого гигабайта). Второй параметр — это количество байтов, которое вы хотите прочитать; чтобы прочитать всё, укажите -1. Если у вас не отключён KASLR, третий параметр — это смещение прямой физической карты.
taskset 0x1 ./memdump 0x240000000 -1 0xffff880000000000 # start at 9 GB
Вы должны получить hexdump частей памяти (возможно, даже содержащий секреты, такие как пароли, см. пример в статье), например:
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 |
Работает ли это на Windows / Ubuntu on Windows (WSL) / Mac OS?
Нет. Этот PoC работает только на Linux, так как использует свойства, специфичные для ядра Linux, например прямую физическую карту.
Могу ли я запустить PoC в виртуальной машине?
Да, PoC также работает в виртуальных машинах. Однако из-за дополнительного слоя, вносимого виртуальной машиной, он может работать не так хорошо, как на реальном оборудовании.
Программа KASLR (kaslr) не находит смещение!
Инструмент kaslr выполняет очень мало измерений, чтобы быть быстрым. Если он не находит смещение, есть две возможности:
kaslr.c: config.retries = 1000;kaslr_offset для прямого чтения смещения из ядра. Установите заголовки ядра для вашего ядра (sudo apt-get install linux-headers-`uname -r` ) и запустите sudo ./direct_physical_map.shВы сказали, что это работает на некэшированной памяти, но все ваши демонстрации обеспечивают кэширование памяти!
Заставить это работать на некэшированной памяти сложнее, и часто требуется немного подправить параметры. Поэтому в PoC мы обеспечиваем кэширование памяти, чтобы упростить воспроизведение. Однако вы можете просто удалить код, который кэширует значения, и заменить его на clflush, чтобы протестировать эксплойт на некэшированной памяти (см. Видео №5 для примера).
Хотя этого не было в оригинальном посте в блоге Google, это также подтвердили независимые исследователи (например, , , ).
Предупреждение №1: Мы предоставляем этот код как есть. Вы несёте ответственность за защиту себя, своего имущества и данных, а также других от любых рисков, вызванных этим кодом. Этот код может вызвать неожиданное и нежелательное поведение на вашей машине. Этот код может не обнаружить уязвимость на вашей машине.
Предупреждение №2: Если вы обнаружите, что компьютер подвержен уязвимости Meltdown, возможно, вам стоит избегать его использования в качестве многопользовательской системы. Meltdown нарушает защиту памяти процессора. На машине, подверженной уязвимости Meltdown, один процесс может читать все страницы, используемые другими процессами или ядром.
Предупреждение №3: Этот код предназначен только для тестирования. Не запускайте его на любых продуктивных системах. Не запускайте его на любой системе, которая может использоваться другим человеком или организацией.
У меня это просто не работает на моём компьютере, что я могу сделать?
Причин может быть много. Мы собрали несколько вещей, которые вы можете попробовать:
libkdump/libkdump.c в строке #define MELTDOWN meltdown_nonull. Попробуйте, например, meltdown вместо meltdown_nonull, что работает намного лучше на некоторых машинах (но совсем не работает на других).stress с stress -i 2 (или другими значениями параметра i, в зависимости от количества ядер).