
Linux local root exploit for CVE-2014-0038
Системный вызов X86_X32 recvmmsg неправильно проверяет указатель тайм-аута, передаваемый из пользовательского пространства.
Передача указателя на адрес ядра в качестве тайм-аута для recvmmsg. Если исходный байт по этому адресу известен, его можно перезаписать известными данными. Если наименее значимый байт равен 0xff, ожидание 255 секунд превратит его в 0x00.
Первое длинное целое по переданному адресу (tv_sec) должно быть положительным, а второе длинное целое (tv_nsec) должно быть меньше 1000000000.
Цель — указатель на функцию release структуры ptmx_fops, расположенной в неинициализированной (и, следовательно, доступной для записи) памяти ядра. Обнуляем три наиболее значимых байта, превращая его в указатель на адрес, отображаемый в пользовательском пространстве. Указатель release выбран, потому что за ним следуют 16 нулевых байтов (так tv_nsec корректен). Открываем /dev/ptmx, закрываем и наслаждаемся.
Не очень красиво, но должно быть достаточно надёжным, если символы можно разрешить.
Протестировано на Ubuntu 13.10
См. также http://blog.includesecurity.com/2014/03/exploit-CVE-2014-0038-x32-recvmmsg-kernel-vulnerablity.html
Получите адреса из /proc/kallsyms и запустите эксплойт:
./build.sh && ./timeoutpwn
Если вы хотите собрать бинарник для удалённого сервера, попробуйте следующее:
ssh user@host 'cat /proc/kallsyms' > syms.txt
CFLAGS=-static ./build.sh syms.txt
scp timeoutpwn user@host:
...
Если ptmx_fops не найден в kallsyms, попробуйте извлечь его из vmlinux,
предоставляемого с пакетом заголовков (linux-headers в Arch Linux):
nm /lib/modules/$(uname -r)/build/vmlinux > syms.txt