Root vulnerability sa Linux kernel at pagtanggi ng serbisyo sa systemd

Ang mga mananaliksik ng seguridad mula sa Qualys ay nagsiwalat ng mga detalye ng dalawang kahinaan na nakakaapekto sa Linux kernel at sa systemd system manager. Ang isang kahinaan sa kernel (CVE-2021-33909) ay nagbibigay-daan sa isang lokal na gumagamit na makamit ang pagpapatupad ng code na may mga karapatan sa ugat sa pamamagitan ng pagmamanipula ng mga direktoryo na may mataas na nested.

Ang panganib ng kahinaan ay pinalala ng katotohanan na ang mga mananaliksik ay nakapaghanda ng mga gumaganang pagsasamantala na gumagana sa Ubuntu 20.04/20.10/21.04, Debian 11 at Fedora 34 sa default na pagsasaayos. Nabanggit na ang iba pang mga pamamahagi ay hindi pa nasubok, ngunit ayon sa teorya ay madaling kapitan din sa problema at maaaring atakehin. Ang buong code ng mga pagsasamantala ay ipinangako na mai-publish pagkatapos na maalis ang problema sa lahat ng dako, ngunit sa ngayon ay isang prototype lamang ng limitadong pag-andar ang magagamit, na nagiging sanhi ng pag-crash ng system. Ang problema ay naroroon mula noong Hulyo 2014 at nakakaapekto sa mga paglabas ng kernel simula sa 3.16. Ang pag-aayos ng kahinaan ay nakipag-ugnayan sa komunidad at tinanggap sa kernel noong ika-19 ng Hulyo. Ang mga pangunahing distribusyon ay nakabuo na ng mga update sa kanilang mga kernel package (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Ang kahinaan ay sanhi ng pagkabigo na suriin ang resulta ng isang size_t sa int na conversion bago magsagawa ng mga operasyon sa seq_file code, na lumilikha ng mga file mula sa isang pagkakasunud-sunod ng mga tala. Ang pagkabigong suriin ay maaaring magresulta sa mga out-of-bound na pagsusulat sa buffer kapag gumagawa, nag-mount, at nagde-delete ng napaka-nest na istraktura ng direktoryo (laki ng path na higit sa 1 GB). Bilang resulta, makakamit ng isang attacker ang isang 10-byte na string na "//deleted" na nakasulat sa isang offset na "-2 GB - 10 bytes" na tumuturo sa lugar kaagad na nauuna sa inilaan na buffer.

Ang handa na pagsasamantala ay nangangailangan ng 5 GB ng memorya at 1 milyong libreng inode upang gumana. Gumagana ang pagsasamantala sa pamamagitan ng pagtawag sa mkdir() upang lumikha ng hierarchy ng humigit-kumulang isang milyong subdirectory upang makamit ang laki ng path ng file na lampas sa 1 GB. Ang direktoryo na ito ay naka-mount sa pamamagitan ng bind-mount sa isang hiwalay na namespace ng user, pagkatapos kung saan ang rmdir() function ay pinapatakbo upang alisin ito. Kasabay nito, ang isang thread ay nilikha na naglo-load ng isang maliit na eBPF program, na na-block sa yugto pagkatapos suriin ang eBPF pseudocode, ngunit bago ang JIT compilation nito.

Sa unprivileged userid namespace, ang file /proc/self/mountinfo ay binuksan at ang mahabang pathname ng bind-mounted directory ay binabasa, na nagreresulta sa string na "//deleted" na isinusulat sa lugar bago magsimula ang buffer. Pinipili ang posisyon para sa pagsulat ng linya upang ma-overwrite nito ang pagtuturo sa nasubok na ngunit hindi pa pinagsama-samang eBPF program.

Susunod, sa antas ng programa ng eBPF, ang hindi nakokontrol na out-of-buffer na pagsusulat ay binago sa kontroladong kakayahang magbasa at magsulat sa iba pang mga istruktura ng kernel sa pamamagitan ng pagmamanipula ng mga istruktura ng btf at map_push_elem. Bilang resulta, tinutukoy ng pagsasamantala ang lokasyon ng buffer ng modprobe_path[] sa memorya ng kernel at ino-overwrite ang "/sbin/modprobe" na landas dito, na nagbibigay-daan sa iyong simulan ang paglulunsad ng anumang executable na file na may mga karapatan sa ugat sa kaganapan ng isang request_module() na tawag, na isinasagawa, halimbawa, kapag gumagawa ng netlink socket.

Nagbibigay ang mga mananaliksik ng ilang mga solusyon na epektibo lamang para sa isang partikular na pagsasamantala, ngunit hindi inaalis ang problema mismo. Inirerekomenda na itakda ang "/proc/sys/kernel/unprivileged_userns_clone" sa 0 para hindi paganahin ang mga mounting directory sa isang hiwalay na user ID namespace, at "/proc/sys/kernel/unprivileged_bpf_disabled" sa 1 para hindi paganahin ang paglo-load ng mga eBPF program sa kernel.

Kapansin-pansin na habang sinusuri ang isang alternatibong pag-atake na kinasasangkutan ng paggamit ng mekanismo ng FUSE sa halip na bind-mound upang i-mount ang isang malaking direktoryo, ang mga mananaliksik ay nakatagpo ng isa pang kahinaan (CVE-2021-33910) na nakakaapekto sa systemd system manager. Ito ay lumabas na kapag sinusubukang i-mount ang isang direktoryo na may sukat ng landas na higit sa 8 MB sa pamamagitan ng FUSE, ang proseso ng pagsisimula ng kontrol (PID1) ay naubusan ng memorya ng stack at mga pag-crash, na naglalagay sa system sa isang "panic" na estado.

Ang problema ay sinusubaybayan at pinapa-parse ng systemd ang mga nilalaman ng /proc/self/mountinfo, at pinoproseso ang bawat mount point sa unit_name_path_escape() function, na nagsasagawa ng strdupa() na operasyon na naglalagay ng data sa stack sa halip na sa dynamically allocated memory. . Dahil ang maximum na laki ng stack ay limitado sa pamamagitan ng RLIMIT_STACK, ang pagpoproseso ng masyadong malaking path patungo sa mount point ay nagiging sanhi ng pag-crash ng proseso ng PID1 at pagpapahinto sa system. Para sa isang pag-atake, maaari mong gamitin ang pinakasimpleng FUSE module kasabay ng paggamit ng isang mataas na nested na direktoryo bilang isang mount point, ang laki ng path na lumampas sa 8 MB.

Ang problema ay lumilitaw mula noong systemd 220 (Abril 2015), ay naayos na sa pangunahing systemd repository at naayos sa mga distribusyon (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Kapansin-pansin, sa systemd release 248 ang pagsasamantala ay hindi gumagana dahil sa isang bug sa systemd code na nagiging sanhi ng pagpoproseso ng /proc/self/mountinfo upang mabigo. Kapansin-pansin din na noong 2018, lumitaw ang isang katulad na sitwasyon at nang subukang magsulat ng isang pagsasamantala para sa kahinaan ng CVE-2018-14634 sa kernel ng Linux, ang mga mananaliksik ng Qualys ay nakatagpo ng tatlong kritikal na kahinaan sa systemd.

Pinagmulan: opennet.ru

Magdagdag ng komento