Google'ın Project Zero'su, Samsung'un Knox Hypervisor'ının Nasıl Atlanacağını Keşfetti (Ocak Yaması'nda Düzeltildi)

En son Project Zero blog yazısında ekip, Knox Hypervisor adı verilen, Samsung'un gerçek zamanlı çekirdek korumasını atlamanın bir yolunu keşfetti.

Google'ın Project Zero ekibi, Samsung'un sözde güvenli Samsung Knox güvenlik paketini çalıştıran telefonlarının saldırıya uğramasına olanak tanıyan bir dizi güvenlik açığını doğruladı. Blog, tüm güvenlik açıklarının Samsung'a aktarıldığını ve Samsung'un Ocak ayı yazılım güncellemesinde bunlar için düzeltmeler yayınladığını belirtiyor.


Arka plan

Samsung tarafından tanıtılan Samsung Knox güvenlik yazılım paketinin bir parçası olarak, Android uygulamaları ile çekirdek arasında yer alan ve adı verilen bir yazılım parçası bulunmaktadır. Hipervizör. Bu, Android cihazların güvenliğini artırmak için ek bir katman olarak kullanılabilir. Samsung Knox Hypervisor'ın adı "Gerçek Zamanlı Çekirdek Koruması" veya kısaca RKP, bu makalenin geri kalanında ona atıfta bulunacağım.

Çekirdek, Android yazılım yığınında RKP'nin altında yer alır ve cihazda çalışan uygulamalar en üstte yer alır. RKP'nin ardındaki fikir, tüm istekler (bellek ve diğer kaynaklar) tarafından yapıldığından cihaz için ekstra bir güvenlik katmanı sağlamaktır. Çekirdeğe yapılan uygulamaların önce Knox'tan geçmesi gerekir; bu, bir uygulamanın bir şey yapıp yapmadığını tespit etmeye çalışır. yapmamalı. RKP ayrıca bir uygulamanın cihazı tehlikeye atmak için kullanabileceği hassas bilgileri gizlemek için ekstra bir katmanla gizlilik yoluyla güvenlik sağlar.

Blog, Android belleğinin, RKP'nin ve İşletim Sistemlerinin genel olarak nasıl çalıştığını oldukça derinlemesine anlatıyor, bu yüzden keşfedilenlere hızlı bir genel bakış sağlamak için onu özetledim ve basitleştirdim. Yine de zamanınız varsa makalenin tamamını okumanızı tavsiye ederim, zira oldukça aydınlatıcıdır.


İstismar #1:

KASLR veya Çekirdek Adres Alanı Düzeni Rastgeleleştirme, çekirdek kodunun bellekteki konumunu önyükleme sırasında rastgele bir miktarda değiştirme işlemidir. Cihaz her başlatıldığında çekirdek farklı bir adres alanına (bellekteki alan) yüklenir. Buradaki fikir, çekirdek koduna saldırmak için çekirdek kodunun nerede bulunduğunu bulmayı zorlaştırmaktır çünkü her önyüklemeden sonra çekirdek kodu, bellekte rastgele bir miktarda "kayır". Bu, olası saldırganları önlemek için harika bir adım gibi görünüyor ancak yakın zamanda araştırma KASLR'ın yerel saldırganlara karşı sağlam bir şekilde uygulanması aslında çok zor olduğundan, bir yazılım hatası veya güvenlik açığı gerektirmeden bunu gerçekten yenebileceğinizi gösterdi.

RKP yazılımı söz konusu olduğunda, KASLR'yi bypass etme yeteneği aslında yukarıda bahsedilen araştırmadan daha basittir. Tüm android cihazların hafızasına işaretçiler tarafından başvurulur ve cihazları saldırılara karşı korumak için, android cihazlar yazdırıldığında veya çıktı alındığında (ekrana veya ekrana) Günlükleri veya hata ayıklamayı dosyalamak için), işaretçi referansları anonimleştirilir, bu da işaretçinin gerçekte nereye işaret ettiğini bulmayı imkansız hale getirir. çıktı.

Bellek işaretçilerini, bir konuma işaret eden bir sokak tabelası gibi düşünün ve anonimleştirmeyi, onu bulanıklaştırmak olarak düşünün. Tıpkı televizyonda olduğu gibi, anonimleştirme çekimden sonra yapılıyor; Android de bu anonimleştirmeyi çıktı zamanında ve yalnızca anonimleştirme doğru şekilde yapılandırılmışsa uyguluyor ve yazar şöyle belirtiyor: karşılaştığı her cihazın işaretçi anonimleştirmesinin doğru şekilde yapılandırıldığını. Bunu kırmak çok zor gibi görünebilir, ancak yapmanız gereken tek şey anonimleştirilmemiş (bulanıklaştırılmamış) tek bir işaretçi (sokak tabelasını düşünün) bulmaktır. işaretçi günlüklere veya başka bir konuma yazıldığında çekirdek geliştiricisi tarafından (bunun ortalama Android uygulama geliştiriciniz olmadığına dikkat edin) ör. ekran veya bir dosya.

Yani anonimleştirilmemiş bir işaretçi bulabilirseniz, çekirdeğin rastgele adres kaymasını ikisi arasındaki fark olarak hesaplayabilirsiniz. İlginç bir şekilde yazar, çekirdekte sömürülebilir bir işaretçi bulamadı ancak onu RPK'nın içinde buldu. geliştiricilerin hata ayıklama (günlüğe kaydetme) çıktısındaki bir işaretçiyi anonimleştirmeyi unuttukları yer; yazım hatası. Android'deki işaretçileri anonimleştirmek için özel bir kod kullanmanız gerekir ve RPK geliştiricilerinin yanlışlıkla bir kod kullandıkları ortaya çıktı. küçük harf 'k' bir yerine büyük 'K'. Bu nedenle çekirdek kodunun rastgele kayma miktarını bulmak ve ona saldırmak nispeten basitti.


İstismar #2:

Bir sonraki istismar biraz daha karmaşık: Samsung Knox, kötü amaçlı kodları durdurmak için cihazın belleğine bir dizi kural uygulayarak cihazınızı korur. Kurallar aşağıdaki gibidir:

  1. Çekirdek kodu dışındaki tüm sayfalar (bellekteki kod), "Ayrıcalıklı Hiçbir Zaman Yürütme" olarak işaretlenmiştir (buradaki kod hiçbir zaman çalıştırılamaz anlamına gelir)
  2. Çekirdek veri sayfaları (program tarafından bellekte kullanılan veriler) hiçbir zaman yürütülebilir olarak işaretlenmez (bu nedenle buradaki kod hiçbir zaman çalıştırılamaz)
  3. Çekirdek kod sayfaları (bellekteki kod) hiçbir zaman yazılabilir olarak işaretlenmez (böylece hiçbir kötü amaçlı kod bunu değiştiremez)
  4. Tüm çekirdek sayfaları, 2. aşama çeviri tablosunda (uygulamaların gerçek bellek konumlarını bilmesini daha da önlemek için uygulama ile çekirdek arasında yer alan tablo) salt okunur olarak işaretlenmiştir.
  5. Tüm bellek çeviri girişleri uygulamalar için salt okunur olarak işaretlenmiştir.

Yazarın yukarıdaki kuralların uygulanmasında bir sorun bulduğu yer burası olduğundan kural 3'e odaklanacağız. RPK aslında çekirdeğin belleğini salt okunur olarak işaretler, ancak KASL'de bir hata olarak bir delik keşfedildi ve bu da sözde "salt okunur" bölümüne kod yazmak. Önyükleme sırasında çekirdeğin konumunu gizlemek için çekirdeğe bellek ayrılır, ancak bu bellek miktarı çekirdeğin metin bölümünden çok daha büyüktür. Daha büyük miktarda bellek tahsis edilmesi, herhangi bir yerde olabilecek gerçek çekirdek kodunun bulunmasını çok daha zorlaştırır ve yukarıda gördüğümüz gibi, cihazın her açılışında rastgele hareket ettirilir.

_text ve _etext korunan aralığı işaretler

Yazar, çekirdek tarafından kullanılan belleğin gerçekten "salt okunur" olarak işaretlendiğini ancak çekirdeği gizlemek için kullanılan büyük miktardaki belleğin geri kalanının "salt okunur" olarak işaretlendiğini doğrulayabildi. Olumsuz "salt okunur" olarak işaretlendi. Bunun nedeni, RKP'nin yalnızca KASLR slaydını uyguladıktan sonra çekirdek metnini içeren bölgeyi korumasıdır.


İstismar #3

Üçüncü istismarda yazar, salt okunur olarak sınırlandırılması gereken başka bir hafıza alanına erişebildi. RKP belleği korur ve Hiper Yönetici Yapılandırma Kaydı (HCR) temel çekirdek işlemlerini kontrol etmek için. HCR'nin amacı, geçerli ve gerçek çekirdek işlemlerinin kayıtlara erişmesine ve kötü niyetli saldırıları engellemesine izin vermektir. Bunu, sanallaştırma özelliklerini yöneten kayıtlara yapılan çağrıları kontrol ederek yapar. HCR, RKP'nin bir isteğe izin verip vermemeyi seçmesine olanak tanıyacak şekilde normal olarak gerçekleştirilecek belirli işlemleri engelleyecek şekilde yapılandırılmıştır.

Bu istismarda HCR kontrolü iki kaydı kapsamıyor bunun çok önemli olduğu ortaya çıktı. Yazar, ARM Referans kılavuzunun derinliklerine indi ve ilk kaydın, uygulamalar için temel olarak RKP'yi kapatmasına izin verdiğini keşfetti. "EL1 için Sistem Kontrol Kaydı (SCTLR_EL1), bellek sistemi de dahil olmak üzere sistem üzerinde üst düzey kontrol sağlar." Mükemmel bir dünyada uygulama, RKP aracılığıyla eşlenen belleği kullanır, böylece RKP, uygulamanın neye erişebileceğini kontrol edebilir. Ancak bu kaydın kapatılması, RKP devre dışı bırakılacak cihazı etkili bir şekilde RKP kurulmadan önceki durumuna döndürerek; bu, cihazın RKP tarafından sağlanan ekstra güvenlik olmadan fiziksel belleğe eşlendiği anlamına gelir. Bu da yazarın, RKP yazılımı tarafından orijinal ve doğru bir şekilde engellenen belleği okuyup yazabileceği anlamına geliyordu.

Gözden kaçırılan ikinci kaydın daha hafif bir etkisi oldu ama sonuçta güvenlik açısından aynı derecede yıkıcıydı. EL1 için Çeviri Kontrol Kaydı (TCR_EL1) kaydı doğrudan bir uygulamanın çalıştığı sayfa adı verilen bellek miktarıyla ilgilidir. AARCH64 Linux çekirdekleri (Android gibi) 4KB çeviri boyutu kullandığından, RKP 4kb sayfa boyutuna sabit kodlanmıştır. Söz konusu kayıt (TCR_EL1), ARM yonga setlerini döndürülecek belleğin boyutuna ayarlar. Şekline dönüştü bu kayıt HCR tarafından korunmuyor ve bu nedenle bir saldırgan, yazarın onu 64kb sayfa boyutuna değiştirdiği gibi değiştirebilir.

Bunun anlamı, istek RKP tarafından yerine getirildiğinde erişilebilen gerçek bellek miktarının artık 4kb yerine 64kb olmasıdır. Bunun nedeni, ARM yonga setinin hâlâ sayfa boyutunu kontrol etmesi ve bu açıktan yararlanılarak 64kb'ye ayarlanmış olmasıdır. RKP, istismar #2'de listelenen kuralların bir parçası olarak belleğin üzerine yazılmasını engellediğinden, bellek aslında hala korunmaktadır. Ancak sorun şu ki, RKP 4kb'ye sabit kodlanmış olduğundan, kayıt güncellendiğinde 64kb sayfa boyutuna değişmez, dolayısıyla belleğin yalnızca ilk 4kb'lik kısmı korunur Saldırganın bunu yapmasına izin vermek kalan 60kb ile ne isterse.


İstismar #4

Yazarın gösterdiği son istismar, RKP yazılımının bulunduğu hafızaya referans vermektir, böylece saldırgan RKP yazılımının kendisine saldırabilir. Linux çekirdeklerinin de kullandığı bu tür saldırıları durdurmanın bir yolu, programınızın sanal bellek adres alanından eşlemesini kaldırmaktır, böylece hiçbir uygulama ona referans veremediği için ona saldıramaz.

Belleğin tamamen fiziksel belleği sanal belleğe eşleyen işaretçiler ve tablolarla ilgili olduğunu unutmayın. Bu tür saldırılarda normal savunma gereği RKP, saldırıya uğramaması için kendi haritasını kaldırır. Ancak çekirdeğin bu tür yetenekleri sağlamadığı durumlarda RKP, bir bellek parçasının Okuma/Yazma olarak eşlenmesine ve işaretlenmesine izin verir. Tek kontrol, RKP'nin eşlenmesi istenen adreslerin RKP'nin bellekte bulunduğu alan olup olmadığını görmek için hiçbir kontrol yapmaması nedeniyle bunun temeldeki çekirdeğin kendisi olmamasıdır. Temel olarak RKP kendisinin yeniden haritalandırılmasına izin verir uygulamaların erişebileceği adres alanına geri döner ve bir yan olarak bellek otomatik olarak Okuma/Yazma olarak işaretlenir böylece bir saldırgan artık belleği istediği gibi kullanabilir.


Çözüm

Yukarıda listelenen dört açıktan yararlanmanın en büyük sorunlarından biri, yazarın, temel Android çekirdeğindeki işlevlerin eksikliği nedeniyle bunları gerçekleştirmenin ne kadar zor olacağını belirtmesidir. İronik bir şekilde, güvenli RKP Hipervizörü, saldırıları gerçekleştirmek için gereken tüm araçları sağladı. Bazen iyi niyetli yazılımların çözdüğünden daha fazla soruna yol açtığını gösteriyor ve aramızda bu konuda çalışanlarımız olduğu için şanslıyız. Ellerini kirletmeye ve dokümantasyonun yazılımın gerçekte neyle eşleştiğini test etmeye istekli Gal Beniamini gibi yapmak.

Bu istismarlar korkutucu görünse ve Knox'u çok savunmasız gösterse de, herkese bu sorunların çözüldüğüne dair güvence vermek isterim. Ocak güncellemesinde düzeltildi Samsung'dan. Ayrıca, bu istismarlar ARM işlemcileri ve programlaması hakkında çok derin bir anlayış gerektirir, dolayısıyla bu istismarları kullanmanın önündeki engel astronomik derecede yüksektir.


Kaynak: Proje Sıfır