Linux çekirdeğinde kök güvenlik açığı ve systemd'de hizmet reddi

Qualys'in güvenlik araştırmacıları, Linux çekirdeğini ve systemd sistem yöneticisini etkileyen iki güvenlik açığının ayrıntılarını ortaya çıkardı. Çekirdekteki bir güvenlik açığı (CVE-2021-33909), yerel bir kullanıcının yüksek düzeyde iç içe geçmiş dizinleri değiştirerek kök haklarıyla kod yürütmesine olanak tanır.

Güvenlik açığı tehlikesi, araştırmacıların varsayılan yapılandırmada Ubuntu 20.04/20.10/21.04, Debian 11 ve Fedora 34 üzerinde çalışan çalışan güvenlik açıkları hazırlayabildikleri gerçeğiyle daha da kötüleşiyor. Diğer dağıtımların henüz test edilmediği ancak teorik olarak soruna duyarlı olduğu ve saldırıya uğrayabileceği belirtiliyor. Açıklardan yararlanmanın tam kodunun, sorun her yerde giderildikten sonra yayınlanacağına söz veriliyor, ancak şimdilik yalnızca sınırlı işlevselliğe sahip bir prototip mevcut ve bu da sistemin çökmesine neden oluyor. Sorun Temmuz 2014'ten beri mevcut ve 3.16'dan itibaren çekirdek sürümlerini etkiliyor. Güvenlik açığı düzeltmesi toplulukla koordine edildi ve 19 Temmuz'da çekirdeğe kabul edildi. Ana dağıtımlar halihazırda çekirdek paketlerine yönelik güncellemeler oluşturdu (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Güvenlik açığı, bir kayıt dizisinden dosyalar oluşturan seq_file kodunda işlemler gerçekleştirilmeden önce size_t'den int'ye dönüştürme işleminin sonucunun kontrol edilememesinden kaynaklanıyor. Denetimin yapılmaması, çok iç içe geçmiş bir dizin yapısı (yol boyutu 1 GB'den büyük) oluştururken, bağlarken ve silerken ara belleğe sınırların dışında yazma yapılmasına neden olabilir. Sonuç olarak, bir saldırgan, tahsis edilen arabelleğin hemen öncesindeki alana işaret eden, "-10 GB - 2 bayt" ofseti ile yazılmış 10 baytlık bir "//silinmiş" dizesi elde edebilir.

Hazırlanan istismarın çalışması için 5 GB bellek ve 1 milyon boş inode gerekiyor. Bu istismar, 1 GB'yi aşan bir dosya yolu boyutuna ulaşmak için yaklaşık bir milyon alt dizinden oluşan bir hiyerarşi oluşturmak üzere mkdir() öğesini çağırarak çalışır. Bu dizin, ayrı bir kullanıcı ad alanına bağlama-bağlama aracılığıyla bağlanır ve ardından onu kaldırmak için rmdir() işlevi çalıştırılır. Paralel olarak, eBPF sözde kodunun kontrol edilmesinden sonraki aşamada, ancak JIT derlemesinden önce engellenen küçük bir eBPF programını yükleyen bir iş parçacığı oluşturulur.

Ayrıcalıksız kullanıcı kimliği ad alanında, /proc/self/mountinfo dosyası açılır ve bağlamaya bağlanan dizinin uzun yol adı okunur, bu da arabellek başlamadan önce alana "//deleted" dizesinin yazılmasıyla sonuçlanır. Satırı yazma konumu, halihazırda test edilmiş ancak henüz derlenmemiş eBPF programındaki talimatın üzerine yazacak şekilde seçilir.

Daha sonra, eBPF program düzeyinde, kontrolsüz arabellek dışı yazma, btf ve map_push_elem yapılarının manipülasyonu yoluyla diğer çekirdek yapılarını okuma ve yazma konusunda kontrollü yeteneğe dönüştürülür. Sonuç olarak, istismar modprobe_path[] arabelleğinin çekirdek belleğindeki konumunu belirler ve içindeki "/sbin/modprobe" yolunun üzerine yazar; bu da herhangi bir yürütülebilir dosyanın kök haklarıyla başlatılmasını başlatmanıza olanak tanır. request_module() çağrısı, örneğin netlink soketi oluşturulurken gerçekleştirilir.

Araştırmacılar, yalnızca belirli bir istismar için etkili olan ancak sorunun kendisini ortadan kaldırmayan çeşitli geçici çözümler sunmaktadır. Ayrı bir kullanıcı kimliği ad alanındaki dizinlerin bağlanmasını devre dışı bırakmak için "/proc/sys/kernel/unprivileged_userns_clone" değerinin 0 olarak ayarlanması ve eBPF programlarının çekirdeğe yüklenmesini devre dışı bırakmak için "/proc/sys/kernel/unprivileged_bpf_disabled" değerinin 1 olarak ayarlanması önerilir.

Araştırmacıların, büyük bir dizini bağlamak için bağlama höyüğü yerine FUSE mekanizmasının kullanımını içeren alternatif bir saldırıyı analiz ederken, systemd sistem yöneticisini etkileyen başka bir güvenlik açığıyla (CVE-2021-33910) karşılaşmaları dikkat çekicidir. FUSE aracılığıyla yol boyutu 8 MB'ı aşan bir dizini bağlamaya çalışırken, kontrol başlatma işleminin (PID1) yığın belleğinin tükendiği ve çöktüğü, bunun da sistemi "panik" durumuna soktuğu ortaya çıktı.

Sorun, systemd'nin /proc/self/mountinfo içeriğini izlemesi ve ayrıştırması ve verileri dinamik olarak ayrılmış bellek yerine yığına yerleştiren bir strdupa() işlemi gerçekleştiren birim_adı_yol_escape() işlevindeki her bağlama noktasını işlemesidir. . Maksimum yığın boyutu RLIMIT_STACK aracılığıyla sınırlandığından, bağlama noktasına giden çok büyük bir yolun işlenmesi PID1 işleminin çökmesine ve sistemin durmasına neden olur. Bir saldırı için, en basit FUSE modülünü, yol boyutu 8 MB'ı aşan, yüksek oranda iç içe geçmiş bir dizini bağlama noktası olarak kullanarak birlikte kullanabilirsiniz.

Sorun systemd 220'den (Nisan 2015) beri ortaya çıkıyor, zaten ana systemd deposunda düzeltildi ve dağıtımlarda (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch) düzeltildi. Özellikle, systemd sürüm 248'de, sistemd kodundaki /proc/self/mountinfo işleminin başarısız olmasına neden olan bir hata nedeniyle bu istismar çalışmıyor. 2018 yılında da benzer bir durumun ortaya çıkması ve Qualys araştırmacılarının Linux çekirdeğindeki CVE-2018-14634 güvenlik açığı için bir istismar yazmaya çalışırken systemd'de üç kritik güvenlik açığıyla karşılaşması da ilginçtir.

Kaynak: opennet.ru

Yorum ekle