Категория > Новости > Погружение в недра. Разбираем kernel exploitation, чтобы добраться до рута на виртуалке c Hack The Box - «Новости»
Погружение в недра. Разбираем kernel exploitation, чтобы добраться до рута на виртуалке c Hack The Box - «Новости»7-02-2021, 00:00. Автор: Харитон |
Разбираем V8» и «Куча приключений» мы проложили себе путь к пользователю r4j на хардкорной виртуалке RopeTwo. Чтобы добраться до рута, остается последний шаг, но какой! Нас ждет ROP (не зря же виртуалку так назвали) и kernel exploitation. Мозги будут закипать, обещаю! Запасайся попкорном дебаггером и поехали!РазведкаКак и в случае с флагом пользователя из предыдущей статьи, первым делом запускаем LinPEAS и внимательно смотрим, за что можно зацепиться. В глаза бросаются две подозрительные строчки:
[+] Looking for Signature verification failed in dmseg
[ 13.882339] ralloc: module verification failed: signature and/or required key missing - tainting kernel
--
[+] Readable files belonging to root and readable by me but not world readable
-rw-r----- 1 root r4j 5856 Jun 1 2020 /usr/lib/modules/5.0.0-38-generic/kernel/drivers/ralloc/ralloc.ko
Видим, что в системе от пользователя root загружен неподписанный модуль ядра, доступный нам для чтения. А это значит, что впереди kernel exploitation! Статический анализПервое, что нам нужно, — это скачать себе ralloc.ko и натравить на него «Гидру». Видим, что ralloc — это LKM, который выполняет различные операции с памятью при получении системных вызовов ioctl. По сути, это самописный драйвер управления памятью, (Superfast memory allocator, как описывает его сам автор), очевидно, что не без уязвимостей. LKM (loadable kernel module) — объектный файл, содержащий код, который расширяет возможности ядра операционной системы. В нем реализованы всего четыре функции:
Ниже дизассемблированный и приведенный в читаемый вид листинг этих функций:
case 0x1000: // Функция выделения памяти ядра
if ((size < 0x401) && (idx < 0x20)) {
if (arr[idx].size== 0) {
ptr = __kmalloc(size, 0x6000c0);
arr[idx].data = ptr;
if (ptr != 0) {
arr[idx].size = size_alloc + 0x20;
return_value = 0;
}
}
}
break;
case 0x1001: // Функция освобождения памяти ядра
if ((idx < 0x20) && arr[idx].data != 0)) {
kfree(arr[idx].ptr);
arr[idx].size = 0;
return_value = 0;
}
break;
case 0x1002: // Функция копирования из user space в kernel space
if (idx < 0x20) {
__dest = arr[idx].data;
__src = ptrUserSpace;
if ((arr[idx].data != 0x0) && ((size & 0xffffffff) <= arr[idx].size)) {
if ((ptrUserSpace & 0xffff000000000000) == 0) {
memcpy(__dest, __src, size & 0xffffffff);
result = 0;
}
}
}
break;
case 0x1003: // Функция копирования из kernel space в user space
if (idx < 0x20) {
__dest = ptrUserSpace;
__src = arr[idx].data;
if ((__src != 0x0) && ((size & 0xffffffff) <= arr[idx].size)) {
if ((ptrUserSpace & 0xffff000000000000) == 0) {
memcpy(__dest, __src, size & 0xffffffff);
result = 0;
}
}
}
break;
Посмотри внимательно на листинг. Возможно, ты найдешь уязвимость, она почти сразу бросается в глаза! А пока займемся подготовкой стенда. Разворачиваем стендОчевидно, что для отладки ядра нам понадобится виртуальная машина. Да не одна, а целых две! Одна сыграет роль хоста, где установлено ядро с отладочными символами и где мы применим отладчик GDB, вторая будет запускаться в режиме KGDB (отладчик ядра Linux). Связь между виртуальными машинами устанавливается либо по последовательному порту, либо по локальной сети. Схематично это выглядит так. Схема отладки ядра Linux Существует несколько сред виртуализации, на которых можно развернуть стенд: VirtualBox, QEMU (самый простой вариант) или VMware. Я выбрал первый вариант. Если захочешь попрактиковаться с QEMU, то на GitHub есть руководство. Также я нашел неплохое видео, которое подробно показывает настройку VirtualBox для отладки ядра. Остановимся на главных моментах. Первым делом посмотрим, какая версия ядра используется в RopeTwo:
Скачиваем и разворачиваем ВМ с Ubuntu 19.04. Далее устанавливаем ядро нужной версии (и свои любимые средства отладки и утилиты):
apt-get install linux-image-5.0.0-38-generic
Теперь можно сделать клон ВМ. На хост нам нужно загрузить ядро с символами отладки. Нам нужен файл На таргете нужно включить режим отладки ядра (KGDB). Для этого сначала настроим загрузчик, изменим в файле
GRUB_CMDLINE_LINUX="kgdboc=ttyS0,115200"
GRUB_CMDLINE_LINUX_DEFAULT="consoleblank=0 nokaslr"
Тем самым мы даем KGDB команду слушать подключения отладчика на порте ttyS0, а также отключаем KASLR (kernel address space layout randomization) и очистку консоли. Выполняем команду Если бы мы хотели отлаживать само ядро, было бы необходимо добавить параметр Далее проверим, что у нас в системе включены прерывания отладки:
и текущие флаги прерываний:
Включим на таргете все функции «магических» прерываний системы:
echo "1" >/proc/sys/kernel/sysrq
echo "kernel.sysrq = 1" >>/etc/sysctl.d/99-sysctl.conf
Подробнее о них можно почитать в документации. Теперь, если ты введешь Осталось связать хост и таргет между собой. Для этого необходимо включить в настройках обеих ВМ Serial Port. На таргете это выглядит так. Настройки Serial port на таргете А на хосте — так. Настройки Serial port на хост Обрати внимание, что на хосте установлена галочка Connect to existing pipe/socket! Поэтому сначала мы загружаем ВМ таргета и только потом ВМ хоста. Теперь вся готово для отладки, проверяем. Проверка работы KGDB KGDB также можно активировать «магической» комбинацией клавиш в VirtualBox: Alt-PrintScr-g. Закидываем в таргет модуль ralloc.ko и загружаем его командой
После загрузки модуля можем посмотреть его карту адресов командой Карта адресов модуля ralloc Для отладки нам понадобятся адреса областей .text, .data и .bss:
Посмотрим, какие защитные механизмы включены в ядре.
Видим, что SMEP включен, а SMAP — нет. В этом можно убедиться следующим образом:
Supervisor mode execution protection (SMEP) и supervisor mode access prevention (SMAP) — функции безопасности, которые используются в последних поколениях CPU. SMEP предотвращает исполнение кода из режима ядра в адресном пространстве пользователя, SMAP —непреднамеренный доступ из режима ядра в адресное пространство пользователя. Эти опции контролируются включением определенных битов в регистре CR4. Подробнее об этом можно почитать в документации Intel (PDF). Также включен KASLR — это умолчательный вариант в новых версиях ядра Linux. Пишем эксплоитИтак, какая же уязвимость присутствует в ralloc? Разгадка кроется в строке Перейти обратно к новости |