LINUX.ORG.RU

Уязвимости Dirty Frag, изменяющие страничный кэш для получения root в любых дистрибутивах Linux

 dirtyfrag, , pagecache, ,


0

2

В ядре Linux выявлены две уязвимости, по своей сути аналогичные несколько дней назад раскрытой уязвимости Copy Fail, но проявляющиеся в других подсистемах - xfrm-ESP и RxRPC. Серии уязвимостей присвоено кодовое имя Dirty Frag (также встречается упоминание Copy Fail 2). Уязвимости позволяют непривилегированному пользователю получить права root, перезаписав данные процесса в страничном кэше. Доступен эксплоит, работающий во всех актуальных дистрибутивах Linux. Информация об уязвимости раскрыта до публикации исправлений, но есть обходной метод блокирования проблемы.

Dirty Frag охватывает две разные уязвимости: первая в модуле xfrm-ESP, используемом для ускорения операций шифрования в IPsec с использованием протокола ESP (Encapsulating Security Payload), а вторая в драйвере RxRPC, реализующем семейство сокетов AF_RXRPC и одноимённый RPC-протокол, работающий поверх UDP. Каждая из уязвимостей по-отдельности позволяет добиться получения прав root. Уязвимость в xfrm-ESP проявляется в ядре Linux с января 2017 года, а уязвимость в RxRPC - с июня 2023 года. Обе проблемы вызваны оптимизациями, допускающими прямую запись в страничный кэш.

Для эксплуатации уязвимости в xfrm-ESP у пользователя должны быть права на создание пространств имён, а для эксплуатации уязвимости в RxRPC должна быть возможность загрузки модуля ядра rxrpc.ko. Например, в Ubuntu в правилах AppArmor непривилегированному пользователю запрещено создание пространств имён, но по умолчанию загружается модуль rxrpc.ko. В каких-то дистрибутивах отсутствует модуль rxrpc.ko, а но не блокируется создание пространств имён. Выявивший проблему исследователь подготовил комбинированный эксплоит, способный атаковать систему через обе уязвимости, что позволяет эксплуатировать проблему во всех крупных дистрибутивах. Работа эксплоита подтверждена в Ubuntu 24.04.4 с ядром 6.17.0-23, RHEL 10.1 с ядром 6.12.0-124.49.1, openSUSE Tumbleweed с ядром 7.0.2-1, CentOS Stream 10 c ядром 6.12.0-224, AlmaLinux 10 с ядром 6.12.0-124.52.3 и Fedora 44 с ядром 6.19.14-300.

Как и в случае с уязвимостью Copy Fail, проблемы в xfrm-ESP и RxRPC вызваны выполнением расшифровки данных по месту c использованием функции splice(), передающей данные между файловыми дескрипторами и каналами (pipe) без копирования, путём передачи ссылок на элементы в страничном кэше. Смещения для операции записи рассчитывались без должных проверок, учитывающих использование прямой ссылки на элементы в страничном кэше, что позволяло через отправку специально оформленных запросов перезаписать 4 байта по выбранному смещению и изменить находящееся страничном кэше содержимое любого файла.

Все операции чтения из файлов в первую очередь отдают содержимое из страничного кэша. В случае модификации данных в страничном кэше операции чтения из файла приведут к возвращению не реально хранимой на накопителе информации, а подменённых данных. Эксплуатация уязвимости сводится к изменению страничного кэша для исполняемого файла с флагом suid root. Например, для получения прав root можно прочитать исполняемый файл /usr/bin/su для его помещения в страничный кэш, после чего добиться подстановки своего кода в загруженное в страничный кэш содержимого этого файла. Последующий запуск утилиты «su» приведёт к тому, что в память будет загружен не оригинальный исполняемый файл с накопителя, а изменённая копия из страничного кэша.

Раскрытие информации об уязвимостях и скоординированный выпуск обновлений с устранением проблем было намечено на 12 мая, но из-за утечки информации сведения об уязвимости пришлось опубликовать до публикации исправлений. В конце апреля в публичном списке рассылки netdev были опубликованы патчи к rxrpc, ipsec и xfrm, без упоминания, что они связаны с устранением уязвимости. 5 мая мэйнтейнер подсистемы IPsec принял в git-репозиторий netdev изменение c предлагаемым исправлением в модуле xfrm-esp, описание к которому во многом повторяло описание проблемы, приведшей к уязвимости Copy Fail в модуле algif_aead. Один из исследователей безопасности заинтересовался этим исправлением, сумел создать рабочий эксплоит и опубликовал его, не зная о том, что на раскрытие сведений о проблеме до 12 мая введено эмбарго.

Обновления с исправлениями для ядра Linux и пакетов с ядром в дистрибутивах пока не опубликованы, но доступны устраняющие проблемы патчи - xfrm-esp и rxrpc. CVE-идентификаторы не присвоены, что усложняет отслеживание обновления пакетов в дистрибутивах. В качестве обходного пути защиты можно заблокировать загрузку модулей ядра esp4, esp6 и rxrpc:

sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; rmmod esp4 esp6 rxrpc 2>/dev/null; true"

>>> Источник: OpenNET

★★

Проверено: dataman ()
Последнее исправление: maxcom (всего исправлений: 3)
Ответ на: комментарий от rOgret

Какая логика приводит к столь неожиданному выводу?

usermod
()

В ведроиде работают? Было бы хорошо, а то давно нормальных рутов не было, чтобы на любом смарте применялись.

Loki13 ★★★★★
()

перепишут куски на расте и всё станет шоколад..по крайней мере того-же цвета

PS/ imho это уже неисправимо, by-design, слишком большое монолитное ядро пусть даже с модулями. Кол-во ошибок и уязвимостей увеличивается нелинейно. Строгачём в дисциплине или новыми тех.средствами (проверками,анализом,ИИ, растом, etc) тенденцию не побороть

MKuznetsov ★★★★★
()
Ответ на: комментарий от zabbal

Разве в ведроидах нельзя к VPN использующим IPSec подключаться? А порутовать андроид-приставки некоторые очень бы не помешало, да и смарт свой я бы рутанул(на Huawei Pura 70 до сих пор рута нет насколько знаю).

Кстати, вот у меня на домашней генте:

~/Build> ./a.out --verbose
[su] installed 48 xfrm SAs
[su] wrote 192 bytes to /usr/bin/su starting at 0x0
[su] /usr/bin/su page-cache patched (entry 0x78 = shellcode)
home /home/user/Build #

Ядро 7.0.0. Видимо через ipsec, он у меня для подключения к рабочему впн используется.

Но мне пофиг, у меня на локалхосте и так беспарольный sudo.

Loki13 ★★★★★
()
Последнее исправление: Loki13 (всего исправлений: 3)
Ответ на: комментарий от Loki13

Разве в ведроидах нельзя к VPN использующим IPSec подключаться?

Можно != типичный use case. А ускорялка IPSec это всё же что-то для мест где это регулярная задача. Хотя могли и включить конечно по принципу «да насрать, много места не займёт» :)

zabbal ★★★★☆
()
Ответ на: комментарий от zabbal

Сомневаюсь - нафик там IPSec

А андроиде IPSec есть, совершенно штатно и «с завода». Если его «нет» - значит его вендор специально выпилил.

no-dashi-v2 ★★★★
()

Вполне вероятно, что сейчас пойдёт поток ошибок, которые будут находить нейросети, в том числе могут обнаружится и более опасные ошибки. Что тут можно сделать? Возможно в ряде случаев поможет добавление ещё одного межсетевого экрана, реализованного на другой системе. Вряд ли, допустим, в NetBSD такие же ошибки, как в Linux, то есть, пока будут исправлять уязвимость в одной из систем, другая будет обеспечивать безопасность (вряд ли сразу в двух разных системах найдут уязвимости, позволяющие удалённо взломать систему).

askh ★★★★
()
Ответ на: комментарий от Reset

такие новости будут сыпаться каждый день

и это только публичная часть.
у кого иишечка которая может в хороший, надёжный аудит С - волосы поди дыбом😢

etwrq ★★★★★
()
Ответ на: комментарий от MKuznetsov

Дак, тут же не в монолитности дело, а в оптимизации. И для микроядра придумали бы какие-нибудь механизмы, позволяющие одному драйверу писать в страничный кеш или ещё куда в обход другого для ускорения.

mky ★★★★★
()
Ответ на: комментарий от etwrq

Я даже больше скажу - rust ухудшит положение вещей, так как я не знаю ни одно rust’амана который сам бы писал код. Они все до единого вайбкодеры :)

Reset ★★★★★
()
Последнее исправление: Reset (всего исправлений: 1)
Ответ на: комментарий от mky

механизмы, позволяющие одному драйверу писать в страничный кеш или ещё куда в обход другого для ускорения

В микроядре это была бы изолированная проблема этих 2 конкретных драйверов, а не полная компрометация всей системы.

zabbal ★★★★☆
()
Ответ на: комментарий от Reset

и никакой rust не спасет

Спасёт разумеется - Rust гарантированно блокирует целые классы ошибок. Именно ради этого его и внедряют в первую очередь.

zabbal ★★★★☆
()
Ответ на: комментарий от Somebody

В убунте уже нашкодили так, что откатывать пришлось и возвращаться к православной Си-реализации стандартных тулзов :)

Reset ★★★★★
()
Ответ на: комментарий от zabbal

В смысле «ускорялка»? Либо отключать ESP в ядре (фактические ядерный IPSec), либо будет это xfrm-esp. Откуда сейчас в ведройде возмут user-space стек IPSec?

ИМХО, тут больше вопрос в том, можно ли так просто создать network namespace на андройде.

mky ★★★★★
()
Ответ на: комментарий от zabbal

Содержимое станичного кеша подменено. То есть при чтении файла будут прочитаны «нужные» данные. Чем это не полная компроментация всей системы? Микроядро не подразумевает, что нет root'а или что каждый процесс имеет свой файловый кеш. Поменяем нужные файлы, будет и вход root по ssh и нужный пароль (хеш пароля) в shadow...

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от rOgret

+1

sasha@amd635 ~/dirtyfrag $ ./exp --verbose

[su] add_xfrm_sa #0 failed
[su] corruption stage failed (status=0x200)

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1000 euid=1000 gid=1000
[!] socket(AF_RXRPC): Address family not supported by protocol — module not load                                                                        able?

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1000 euid=1000 gid=1000
[!] socket(AF_RXRPC): Address family not supported by protocol — module not load                                                                       able?

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1000 euid=1000 gid=1000
[!] socket(AF_RXRPC): Address family not supported by protocol — module not load                                                                       able?

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1000 euid=1000 gid=1000
[!] socket(AF_RXRPC): Address family not supported by protocol — module not load                                                                       able?
dirtyfrag: failed (rc=1)
sasha@amd635 ~/dirtyfrag $
alex4tomsk
()
Ответ на: комментарий от Desmond_Hume

Действительно кажется. Какой смысл переходить на ещё более дырявое решение где к тому же всё тормозит и отсутствует куча фич?

zabbal ★★★★☆
()
Ответ на: комментарий от zabbal

А почему нет?

Так тогда какой смысл в файловом кэше? Запускаешь второй процесс openoffice и он повторно грузит все свои данные с диска в память. И смысл в разделяемых библиотеках пропадает, если каждый процесс будет их повторно загружать.

monk ★★★★★
()
Ответ на: комментарий от Desmond_Hume

они стесняются иишечки, либо молча и сопя фиксят)

etwrq ★★★★★
()

В арче прилетело ядро 6.18.28
(на ядре 6.18.26-2 и 7.0.3-2 эксплоит срабатывает)

$ uname -a
Linux abhost625 6.18.28-1-lts #1 SMP PREEMPT_DYNAMIC Fri, 08 May 2026 07:04:32 +0000 x86_64 GNU/Linux
$  ./exp --verbose
[su] installed 48 xfrm SAs
[su] wrote 192 bytes to /usr/bin/su starting at 0x0
[su] post-write verify failed (target unchanged)

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1000 euid=1000 gid=1000
[+] rxrpc module autoloaded via dummy socket(AF_RXRPC)
[+] target /etc/passwd opened RO, size=2531, uid=0 gid=0 mode=0644
[+] mmap'd /etc/passwd page-cache at 0x7f25184de000 (PROT_READ|MAP_SHARED)
[+] /etc/passwd already patched (root::0:0...) — nothing to do
Пароль: 
su: Сбой при проверке подлинности
greenman ★★★★★
()
Последнее исправление: greenman (всего исправлений: 2)
Ответ на: комментарий от monk

Запускаешь второй процесс openoffice

И он грузит те же файлы что и IPSec, ага. Иди лучше в 1С что-нибудь попорти.

zabbal ★★★★☆
()

Это уже не так важно, если к вашей виртуалке и так полбангалора имеет рутовый доступ, официально и одобрено менеджментом.

seiken ★★★★★
()

Получается, линукс - дрявый? Кстати в последнее время часто новости такие, selectel недавно прислал дайджест дыр

gobot ★★★★
()
Ответ на: комментарий от gobot

Получается все дырявое. Просто к линуксу в первую очередь побежали с новыми игрушками для поиска дыр. И в BSD* тоже найдется куча дыр, просто дотуда еще не добрались.

t500s ★★★
()
Ответ на: комментарий от mky

Микроядро подразумевает не наш таймлайн. В нашем таймлайне, напоминаю, микроядерных ОС считай в продакшене не существует.

t500s ★★★
()
Ответ на: комментарий от a__

Выдыхать не стоит. Динамическую загрузку модуля или вкомпилированность модуля в ядро никто не отменял.

BOOBLIK ★★★★
()
Ответ на: комментарий от zabbal

Каждому процессу свой кеш, может, где-то и нужен, но не является требованием микро-ядра. В описании Minix я не видел подобного. И монолитное ядро не запрещает сделать отдельный кеш каждому процессу, но не делают.

Есть, конечно, монстр-процессы, типа браузера, которым, может вобще дисковый кеш не нужен, они там всё сами. Но, так, процессы обычно живут не долго и делают что-то одно (утилита из sh-скрипта или gcc из make-файла). Если каждому процессу свой кеш, то те файлы, которые один процесс создавал (записывал) не будут доступны другому из кеша, в ряде задач производительность упадёт из-за дисковых операций.

mky ★★★★★
()
Ответ на: комментарий от t500s

Не знаю, тут же в 2017 году всплывала тема, что Minix Inside (в Интеле). Да и просто потеоретизировать можно, как это будет в гипотетической ОС с микроядром.

И тут вобще интересный момент, есть мнение, разделяемое в том числе и Линусом, что «Мнимая простота микроядра оборачивается тем, что взаимодействие и интерфейс между простыми частями микроядра создает сложности, которые нивелируют все ее «бумажные» преимущества». А тут, монолитное ядро довели до состояния, когда никто уже толком не понимает, как там что внутри взаимодействует. И этот уровень сложности расковырять может либо ИИ (недавняя ошибка в NFS), либо целенаправленный поиск в одной подсистеме (нашли одну дырку CopyFail, следом по аналогии ещё две).

mky ★★★★★
()
Ответ на: комментарий от mky

Каждому процессу свой кеш

Нет никакого смысла делать. Равно как и бессмысленно делать общий кэш для офисного пакета и сервисов удалённого доступа: они всё-равно не будут одни и те же файлы читать.

Более того, в GNU/Linux уже есть группировка процессов - она прям так и называется: cgroup. Однако сделать аналогично для разных драйверов ядра не получится - как раз из-за его монолитности. А вот в микроядерной ОС - без проблем: благодаря тому что там это тоже процессы, а не часть ядра. И именно за счёт этого подобные дыры там гораздо проще изолировать.

zabbal ★★★★☆
()
Последнее исправление: zabbal (всего исправлений: 1)

Вот уж РЕШЕТО так РЕШЕТО!

thunar ★★★★★
()
Ответ на: комментарий от zabbal

Он грузит те же файлы, что и первый процесс openoffice. Но zabbal спроектировал ОС так, чтобы у каждого процесса был свой файловый кэш, поэтому файлы от первого процесса из памяти прочитать нельзя, надо повторно загружать в память.

monk ★★★★★
()
Ответ на: комментарий от zabbal

Равно как и бессмысленно делать общий кэш для офисного пакета и сервисов удалённого доступа: они всё-равно не будут одни и те же файлы читать.

glibc у них общий. Может ещё какие библиотеки.

monk ★★★★★
()
Ответ на: комментарий от monk

glibc у них общий. Может ещё какие библиотеки.

Усраться какая потеря - одноразовая загрузка целых пары мегабайт. Можешь на эти 3 микросекунды взять себе отпуск :-D

zabbal ★★★★☆
()

в любых дистрибутивах Linux

Это голословно.

EvilFox ★★
()
Ответ на: комментарий от zabbal

А вот в микроядерной ОС - без проблем:

Это рассуждение уровня «знал бы где упасть, соломки подстелил». В Minix никаких cgroups нету, микроядро не означет автоматического отсутствия подобной уязвимости.

В предшествующей CopyFail, если я правильно понял, сначала производят запись 4 байт, а только потом проверяют, а можно ли было это делать и возвращают ошибку EBADMSG. Логическая ошибка в коде. Аналогично, у гипотетического микроядра с cgroups, с раздельным кешем можеть быть допущена ошибка в проверке можно ли этой cgroup в этот кеш обращаться...

благодаря тому что там это тоже процессы, а не часть ядра

Что процессы? Драйвер дисковых операций один, или вы для каждой cgroup хотите свой драйвер и чтобы они одновременно к одном диску обращались?

они всё-равно не будут одни и те же файлы читать.

Ну-ну. Столько всего завязано на тот же /etc/passwd. И в случае раздельных кешей нужно будет реализовывать, что как-только в этом файле что-то поменяли, сразу во всех кешах одновременно меняется содержимое. Это так, к вопросу о простоте.

mky ★★★★★
()
Ответ на: комментарий от mky

В Minix никаких cgroups нету

Там вообще мало что есть кроме баттхёрта Танненбаума, у которого изрядно пригорело от того что из-за выбранной им лицензии он ни строчки кода от тех, кто это массово использует в проде не получил.

тут же в 2017 году всплывала тема, что Minix Inside (в Интеле)

Тот вариант никто кроме инженеров Интела не видел и сколько там осталось от исходного варианта знают только они. Не удивлюсь если только коммент «Танненбаум лох» от того инженера что решил халявный код прикарманить съэкономив корпорации пару сотен килобаксов на разработку.

Драйвер дисковых операций один

И? У тебя CopyFail отключением этого драйвера митигируется что-ли? Или DirtyFrag?

Столько всего завязано на тот же /etc/passwd

Дааа, его браузер с офисным пакетом раз в минуту читают. Чисто чтобы слишком быстро не работать.

zabbal ★★★★☆
()
Последнее исправление: zabbal (всего исправлений: 1)
Ответ на: комментарий от rOgret

и потом будете сожалеть, что опять все играются с эксплоитами, а на самосборе ничего не работает, т.к. модули не собраны, настройки не те и т.д..

Sylvia ★★★★★
()
Ответ на: комментарий от monk

Я не понимаю, зачем придумывать какие-то раздельные кеши вместо того, чтобы просто исправить баг? Вы по-моему ерундой какой-то страдаете. Нет никаких проблем в общих кешах.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от zabbal

Баттхёрт баттхертом, а Миникс одна из возможных и как-то работающих реализация микроядра. И, как-то, пока никто не горит желанием делать микроядро+обвязка с функционалом, первосходщим Линукс, со всем этим cgroups, namespaces и т.д. Может там вобще разработка сначала развалится на отдельные независимые группы, каждая что-то своё пишет, а потом встанет колом, так как не договорились о протоколах взаимодействия между подсистемами.

И? У тебя CopyFail отключением этого драйвера

И, если в драйвере будет ошибка, позволяющая изменять содержимое страничного кеша произвольной cgroups, то система будет уязвима.

/etc/passwd

В начале было:

они всё-равно не будут одни и те же файлы читать.

А теперь съзжаете только в сторону производительности, а про усложнение, что каждый процесс будет иметь свой кеш /etc/passwd или ещё каких файлов не хотите рассуждать.

А случай CopyFail интересен тем, что, есть утверждение, что смысла в том коммите 2017 год не было:

There is no benefit in operating in-place in algif_aead since the source and destination come from different mappings.

То есть, кто-то переписал (усложнил) код с использованием новомодного splice(). И без тестов, что стало быстрее, код приняли в ядро. И ладно, может автор патча действовал без злого умысла, но, тот кто патч принимал, тоже не стал вникать про «source and destination come from different mappings». А, если считать, что специально накосячили в коде, то никакое микроядро и rust не спасёт, напишут «нужный» код.

mky ★★★★★
()

https://www.opennet.ru/opennews/art.shtml?num=65407:

Предложен killswitch для экстренного отключения уязвимой функциональности в ядре Linux.

Саша Левин (Sasha Levin) из компании NVIDIA, занимающийся сопровождением LTS-веток ядра Linux и входящий в консультативный совет организации Linux Foundation, подготовил набор патчей с реализацией механизма killswitch для ядра Linux. Предложенная возможность позволяет мгновенно отключить доступ к определённой функциональности работающего ядра. Предполагается, что killswitch будет полезен для временного блокирования уязвимостей на время до установки обновления ядра с исправлением.

Управление killswitch осуществляется через файл "/sys/kernel/security/killswitch/control", позволяющий настроить перехват обращений к функциям ядра по их именам. Например, для блокирования уязвимости Copy Fail достаточно записать в управляющий файл команду "engage af_alg_sendmsg -1" для включения перехвата вызова функции af_alg_sendmsg и вместо её выполнения возвращения кода ошибки "-1".

В качестве имён могут использоваться любые символы, поддерживаемые подсистемой kprobes. Многие из недавно найденных в ядре серьёзных уязвимостей присутствуют в подсистемах, используемых относительной небольшим числом пользователей (например, AF_ALG, ksmbd, nf_tables, vsock, ax25). Для большинства пользователей неудобство из-за прекращения работоспособности отдельных функций не сравнится с риском использования в работе ядра с известной неисправленной уязвимостью на время до установки исправления. Механизм killswitch особо актуален в контексте сегодняшней уязвимости Dirty Frag, эксплоит для которой был опубликован раньше, чем проблема была устранена в ядре.
dataman ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.