Root-уразлівасць у ядры Linux і адмова ў абслугоўванні ў systemd

Даследнікі бяспекі з кампаніі Qualys расчынілі дэталі двух уразлівасцяў, якія закранаюць ядро ​​Linux і сістэмны мэнэджар systemd. Уразлівасць у ядры (CVE-2021-33909) дазваляе лакальнаму карыстачу дамагчыся выкананні кода з правамі root праз маніпуляцыі з каталогамі вялікай укладзенасці.

Небяспека ўразлівасці пагаршаецца тым, што даследнікам атрымалася падрыхтаваць працоўныя эксплоіты, якія працуюць у Ubuntu 20.04/20.10/21.04, Debian 11 і Fedora 34 у канфігурацыі па змаўчанні. Адзначаецца, што іншыя дыстрыбутывы не правяраліся, але тэарэтычна таксама схільныя да праблемы і могуць быць атакаваныя. Поўны код эксплоітаў абяцаюць апублікаваць пасля паўсюднага ўхілення праблемы, а пакуль даступны толькі абмежаваны ў функцыянальнасці прататып, які выклікае крах сістэмы. Праблема праяўляецца з ліпеня 2014 года і закранае выпускі ядра пачынаючы з 3.16. Выпраўленне ўразлівасці было скаардынавана з супольнасцю і прынята ў склад ядра 19 ліпеня. Асноўныя дыстрыбутывы ўжо сфарміравалі абнаўленні пакетаў з ядром (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Уразлівасць выкліканая адсутнасцю праверкі выніку пераўтварэнні тыпу size_t у int перад выкананнем аперацый у кодзе seq_file, які здзяйсняе стварэнне файлаў з паслядоўнасці запісаў. Адсутнасць праверкі можа прывесці да запісу ў вобласць па-за межамі буфера пры стварэнні, мантаванні і выдаленні структуры каталогаў з вельмі вялікім узроўнем укладзенасці (памер шляху больш за 1 ГБ). У выніку, атакавалы можа дамагчыся запісы 10-байтавага радка "//deleted" са зрушэннем "- 2 ГБ - 10 байт", якія паказваюць на вобласць, непасрэдна папярэднюю вылучанаму буферу.

Падрыхтаваны эксплоіт патрабуе для працы 5 ГБ памяці і 1 мільён вольных inode. Праца эксплоіта зводзіцца да стварэння праз выклік mkdir() іерархіі з каля мільёна ўкладзеных каталогаў для дасягнення памеру файлавага шляху, які перавышае 1 ГБ. Дадзены каталог манціруецца праз bind-mount у асобнай прасторы імёнаў ідэнтыфікатараў карыстальнікаў (user namespace), пасля чаго запускаецца функцыя rmdir() для яго выдалення. Паралельна ствараецца струмень, які загружае невялікую eBPF-праграму, які блакуецца на стадыі пасля праверкі псеўдакода eBPF, але да яго JIT-кампіляцыі.

У непрывілеяванай прасторы імёнаў ідэнтыфікатараў карыстачоў адчыняецца файл /proc/self/mountinfo і пачынаецца чытанне доўгага шляху каталога, прымантаванага пры дапамозе bind-mount, што прыводзіць да запісу радка «//deleted» у вобласць да пачатку буфера. Пазіцыя для запісу радка выбіраецца такім чынам, што яна перазапісвае інструкцыю ва ўжо праверанай, але яшчэ не скампіляванай праграме eBPF.

Далей на ўзроўні праграмы eBPF некантралюемы запіс па-за буферам трансфармуецца ў кіраваную магчымасць чытання і запісы ў іншыя структуры ядра праз маніпуляцыю са структурамі btf і map_push_elem. У выніку, эксплоіт вызначае месцазнаходжанне буфера modprobe_path[] у памяці ядра і перазапісвае ў ім шлях "/sbin/modprobe", што дазваляе ініцыяваць запуск любога выкананага файла з правамі root у выпадку выканання выкліку request_module(), які выконваецца, напрыклад, пры стварэнні сокета netlink.

Даследнікамі прыводзіцца некалькі абыходных метадаў абароны, якія эфектыўныя толькі для пэўнага эксплоіту, але не ўхіляюць саму праблему. Рэкамендуецца ўсталяваць параметр "/proc/sys/kernel/unprivileged_userns_clone" у значэнне 0 для забароны мантавання каталогаў у асобнай прасторы імёнаў ідэнтыфікатараў карыстачоў, а таксама "/proc/sys/kernel/unprivileged_bpf_disabled" у 1 для забароны загрузкі праграм eBPF у e

Характэрна, што разбіраючы альтэрнатыўны варыянт нападу, злучаны з выкарыстаннем механізму FUSE замест bind-mound для мантавання вялікага каталога, даследнікі натыкнуліся на яшчэ адну ўразлівасць (CVE-2021-33910), якая закранае сістэмны мэнэджар systemd. Аказалася, што пры спробе мантавання праз FUSE каталога c памерам шляху, які перавышае 8 МБ, у кіраўніку працэсе ініцыялізацыі (PID1) надыходзіць вычарпанне памяці стэка і крах, які прыводзіць сістэму ў стан «panic».

Праблема звязана з тым, што systemd адсочвае і разбірае змесціва /proc/self/mountinfo, і апрацоўвае кожную кропкі мантавання ў функцыі unit_name_path_escape(), у якой выконваецца аперацыя strdupa(), якая размяшчае дадзеныя ў стэку, а не ў дынамічна вылучанай памяці. Бо максімальны памер стэка абмежаваны праз RLIMIT_STACK апрацоўка занадта вялікага шляху да кропкі мантавання прыводзіць да краху працэсу PID1 і прыпынку працы сістэмы. Для нападу можна выкарыстоўваць найпросты модуль FUSE у спалучэнні з выкарыстаннем у якасці кропкі мантавання каталога з вялікім узроўнем укладзенасці, памер шляху ў якім перавышае 8 МБ.

Праблема выяўляецца пачынальна з systemd 220 (красавік 2015), ужо ўхіленая ў асноўным рэпазітары systemd і выпраўлена ў дыстрыбутывах (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Характэрна, што ў выпуску systemd 248 эксплоіт не працуе з-за памылкі ў кодзе systemd, якая прыводзіць да збою пры апрацоўцы /proc/self/mountinfo. Таксама цікава, што ў 2018 годзе ўзнікла падобная сітуацыя і пры спробе напісаць эксплоіт да ўразлівасці CVE-2018-14634 у ядры Linux, даследчыкі Qualys натыкнуліся на тры крытычныя ўразлівасці ў systemd.

Крыніца: opennet.ru

Дадаць каментар