
Драйвер ядра Linux для захвата физической памяти, обеспечивающий доступ на чтение к любому физическому адресу, включая зарезервированную память и дыры в памяти, с информацией о CR3 и сервисами трансляции виртуальных адресов в физические.

Как и его аналог для Windows, Winpmem, это не традиционный дампер памяти. Linpmem предоставляет API для чтения с любого физического адреса, включая зарезервированную память и дыры памяти, но также может использоваться для обычного дампа памяти. Кроме того, драйвер предлагает различные режимы доступа для чтения физической памяти, такие как байтовый, словесный, двойной словесный, четверной словесный и буферный режим, причем буферный режим подходит в большинстве стандартных случаев. Если чтение требует выровненного чтения байт/слово/двойное слово/четверное слово, Linpmem сделает именно это.
В настоящее время Linpmem включает:
Управление кэшем будет добавлено в будущем для поддержки специализированных режимов чтения.
По крайней мере сейчас, вы должны скомпилировать драйвер Linpmem самостоятельно. Метод загрузки предварительно скомпилированного драйвера Linpmem на других системах Linux в настоящее время находится в разработке, но еще не завершен. Тем не менее, скомпилировать драйвер Linpmem несложно, в основном это выполнение команды 'make'.
Вам понадобятся make и компилятор C. (Мы рекомендуем gcc, но clang также должен работать).
Убедитесь, что у вас установлены linux-headers (используя любой пакетный менеджер вашего целевого дистрибутива Linux). Точное имя пакета может отличаться в вашем дистрибутиве. Быстрый (независимый от дистрибутива) способ проверить, установлен ли пакет:
ls -l /usr/lib/modules/`uname -r`/
Вот и все, можно переходить к шагу 2.
Чужая система: В настоящее время, если вы хотите скомпилировать драйвер для другой системы, например, потому что вы хотите создать дамп памяти, но не можете скомпилировать на целевой системе, вам необходимо загрузить пакет заголовков непосредственно из репозиториев пакетов дистрибутива Linux этой системы. Дважды проверьте, что версия пакета точно соответствует релизу и версии ядра, работающим на чужой системе. Если другая система использует самостоятельно скомпилированное ядро, вам необходимо получить копию каталога сборки этого ядра. Затем укажите расположение любого из этих каталогов в переменной окружения KDIR.
export KDIR=path/to/extracted/header/package/or/kernel/root
Скомпилировать драйвер просто, просто введите:
make
Возможно, вы захотите проверить precompiler.h перед сборкой и выбрать, компилировать для релиза или отладки (например, с отладочной печатью). Сейчас не так много других настроек прекомпилятора.
Модуль linpmem.ko можно загрузить с помощью insmod path-to-linpmem.ko и выгрузить с помощью rmmod path-to-linpmem.ko. (Это загрузит драйвер только на время работы.) Если вы компилировали для отладки, также посмотрите вывод dmesg.
После загрузки, для взаимодействия с драйвером, необходимо создать устройство:
mknod /dev/linpmem c 42 0
Если не удается связаться с драйвером, возможно, проверьте в логе dmesg, что '42' действительно является зарегистрированным major-номером:
[12827.900168] linpmem: registered chrdev with major 42
Хотя обычно ядро пытается действительно назначить этот номер.
Вы можете использовать chown на устройстве, чтобы передать его вашему пользователю, если вы не хотите все время держать открытой root-консоль. (Или просто продолжайте использовать его в root-консоли.)
Существует пример кода, демонстрирующий и подробно объясняющий, как взаимодействовать с драйвером. Ссылка на пользовательский API также находится в ./userspace_interface/linpmem_shared.h.
Этот код важен, если вы хотите понять, как напрямую взаимодействовать с драйвером вместо использования библиотеки. Его также можно использовать как краткий функциональный тест.
Существует (опциональный) базовый инструмент командной строки для Linpmem, pmem CLI tool. Он доступен здесь: https://github.com/vobst/linpmem-cli. Помимо исходного кода, есть также предварительно скомпилированный CLI-инструмент, а также предварительно скомпилированная статическая библиотека и заголовочные файлы, которые можно найти здесь (подписано). Примечание: это предварительная версия, обязательно проверяйте обновления, так как вскоре последуют многие дополнения и улучшения.
Инструмент pmem CLI можно использовать для тестирования различных функций Linpmem (относительно) безопасным и удобным способом. Linpmem также может быть загружен этим инструментом вместо использования insmod/rmmod, с некоторыми дополнительными опциями в будущем. Это также имеет преимущество — pmem автоматически создает нужное устройство для немедленного использования. Он чрезвычайно портативен и работает на любой системе Linux (и, фактически, был протестирован даже на Linux 2.6).
$ ./pmem -h
Command-line client for the linpmem driver
Usage: pmem [OPTIONS] [COMMAND]
Commands:
insmod Load the linpmem driver
help Print this message or the help of the given subcommand(s)
Options:
-a, --address <ADDRESS> Address for physical read operations
-v, --virt-address <VIRT_ADDRESS> Translate address in target process' address space (default: current process)
-s, --size <SIZE> Size of buffer read operations
-m, --mode <MODE> Access mode for read operations [possible values: byte, word, dword, qword, buffer]
-p, --pid <PID> Target process for cr3 info and virtual-to-physical translations
--cr3 Query cr3 value of target process (default: current process)
--verbose Display debug output
-h, --help Print help (see more with '--help')
-V, --version Print version
Если вы хотите скомпилировать CLI-инструмент самостоятельно, перейдите в его каталог и следуйте инструкциям в (cli) Readme для сборки. В противном случае просто загрузите предварительно собранную программу — она должна работать на любом Linux. Чтобы загрузить драйвер ядра с помощью CLI-инструмента:
# pmem insmod path/to/linpmem.ko
Преимущество использования инструмента pmem для загрузки драйвера в том, что вам не нужно создавать файл устройства самостоятельно, и он предложит (в следующих версиях) выбор владельца устройства linpmem.
Интерфейс командной строки pmem — это лишь тонкая обертка вокруг небольшой библиотеки Rust, которая предоставляет API для взаимодействия с драйвером. Более опытные пользователи также могут использовать эту библиотеку. Библиотека автоматически компилируется (как статическая портативная библиотека) вместе с pmem CLI при сборке из https://github.com/vobst/linpmem-cli, а также включена (предварительно скомпилирована) здесь (подписано). Примечание: это предварительная версия, скоро последуют другие.
Если вы не хотите использовать пользовательскую библиотеку и предпочитаете напрямую взаимодействовать с драйвером самостоятельно, вы можете найти его пользовательский API/интерфейс и документацию в ./userspace_interface/linpmem_shared.h. Мы также предоставляем пример кода в demo/test.c, который объясняет, как напрямую использовать драйвер.
LinPyMem: обертка на Python для драйвера linpmem. Доступна на PyPI.
Пока не реализовано.
Если при загрузке модуля система сообщает следующую ошибку, это может быть связано с Secure Boot:
$ sudo insmod linpmem.ko
insmod: ERROR: could not insert module linpmem.ko: Operation not permitted
Существуют разные способы все же загрузить модуль. Самый очевидный — отключить Secure Boot в настройках UEFI.
Если ваш дистрибутив это поддерживает, более элегантным решением будет подписать модуль перед использованием. Это можно сделать с помощью следующих шагов (проверено на Ubuntu 20.04).
$ sudo apt install mokutil
$ openssl req -new -newkey rsa:4096 -keyout mok-signing.key -out mok-signing.crt -outform DER -days 365 -nodes -subj "/CN=Some descriptive name/"
$ sudo mokutil --import mok-signing.crt
$ /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 path/to/mok-singing/MOK.key path/to//MOK.cert path/to/linpmem.ko
После этого вы сможете загрузить модуль.
Обратите внимание, что с точки зрения готовности к криминалистическому анализу, вы должны подготовить подписанный модуль до того, как он вам понадобится, так как система перезагрузится дважды в ходе описанного выше процесса, уничтожая большую часть ваших энергозависимых данных в памяти.
(Пожалуйста, сообщайте о потенциальных проблемах, если вы столкнетесь с чем-либо.)
Linpmem, так же как и Winpmem, не существовали бы без работы наших предшественников из (ныне закрытого) проекта REKALL: https://github.com/google/rekall.
Наши участники открытого проекта: