Дан доступ по ssh на машину с флагом и образ машины (без флага, естесственно).

Что ж, выглядит этот таск очень тривиально (хотя, честно говоря, ядро я эксплуатировал впервые). Нам нужно проэксплуатировать CVE-2017–18344. В гугле есть готовый эксплойт.

В процессе мы сталкиваемся с двумя проблемами:

  1. Адреса функций и оффсеты полей в структурах нам нужно искать самим под наше ядро.
  2. В виртуалке нет ни сети, ни компиляторов, единственный канал передачи данных — консоль.

Адреса функций и переменных ядра

Тут всё просто — ищем наше ядро в репозиториях дебиана, качаем, вытаскиваем System.map, ищем в нём нужные адреса. У меня получилось вот так:

#define KERNEL_START            0xffffffff81000000ul
#define O_DIVIDE_ERROR          (0xffffffff8151be10ul - KERNEL_START)
#define O_INIT_TASK         (0xffffffff8181a460ul - KERNEL_START)
#define O_INIT_MM           (0xffffffff81865660ul - KERNEL_START)
#define O_PAGE_OFFSET_BASE      0

O_PAGE_OFFSET_BASE не нашёл, вроде как в таком случае он равен нулю.

Смещения полей в структурах

Самая большая боль. Стратегия примерно такая: ищем использование нужных нам полей в функциях, которые есть в System.map, сравниваем с тем, что есть у нас в IDA Pro и находим нужное нам смещение.

Выглядит примерно так:

get_task_mm в IDA Pro

get_task_mm в IDA Pro

get_task_mm в исходниках

get_task_mm в исходниках

Нетрудно догадаться, что в таком случае смещение mm в структуре task_struct равно 720.

В итоге получаем такие результаты:

#define O_TASK_STRUCT_TASKS     640
#define O_TASK_STRUCT_MM        720
#define O_TASK_STRUCT_PID       820
#define O_MM_STRUCT_MMAP        0
#define O_MM_STRUCT_PGD         64
#define O_VM_AREA_STRUCT_VM_START   0
#define O_VM_AREA_STRUCT_VM_END     8
#define O_VM_AREA_STRUCT_VM_NEXT    16
#define O_VM_AREA_STRUCT_VM_FLAGS   80

Теперь собираем наш эксплойт, линкуем статически:

gcc poc.c -static -o poc

Доставка эксплойта в нужное место