Nika Wakulich’in “UEFI is the new BIOS” başlıklı yazısından yararlanılmıştır. Orijinal kaynak için tıklayınız.
Bu blog yazısı, UEFI tersine mühendislik, güvenlik açığı keşfi ve exploit geliştirme üzerine bir serinin ilk yazısıdır.
Giriş
Bir zamanlar, rootkit’lerin altın çağında ve internetin ana akım olarak benimsenmesinin şafağında, vahşi kötü amaçlı yazılım tehdit ortamı MBR bootkit’leri ve eski BIOS (Temel Giriş-Çıkış Sistemi) makinelerinin ünlü güvensiz işletim sistemi öncesi önyükleme ortamını hedef alan istismarlar tarafından istila edilmişti. Ancak UEFI’nin (Evrensel Genişletilebilir Ürün Yazılımı Arayüzü) ana akım olarak benimsenmesi kötü amaçlı yazılım tehdit ortamını sonsuza dek değiştirdikten sonra doğal bir soru ortaya çıktı: platform ürün yazılımı tasarımı ve uygulamasındaki yeni gelişmelerle birlikte, bir bootkit geliştiricisi ne yapmalıydı? Elbette, paradigmadaki bu yeni değişimle birlikte, önyükleme işlemi güvenliği geçmişte kaldı… değil mi?
Yine de size bir sır vereceğim: BIOS korsanlığı geri döndü ve her zamankinden daha kötü (ve daha iyi). UEFI, önyükleme sürecinde yeni yenilikler ve şimdiye kadar öngörülemeyen gelişmeler ve dolayısıyla klasik MBR önyükleme kitleri için hafifletmeler getirmiş olsa da, yeni bir dönem başlamak üzereydi – UEFI istismarları, UEFI tabanlı önyükleme kitleri ve UEFI ürün yazılımı implantları dönemi.
Ancak bir bootkit geliştiricisi bu yeni çağda ilerlemek istiyorsa yeni bir beceri setine ihtiyaç duyacaktır. Eski BIOS, MBR ve geçmiş günlerin önyükleme sürecinin anlaşılması rekabette önemli bir avantaj sağlarken ve önyükleme sürecindeki ve işletim sistemi öncesi ortamdaki güvenlik açıklarını tanımlamak için sağlam bir temel oluştururken, UEFI’nin anlaşılması kritik önem taşır.
Leviathan’da, UEFI tersine mühendislik ve istismar geliştirme konusundaki bilgi ve beceri setimizi geliştirmek ve müşterilerimizle yaptığımız çalışmalarda UEFI güvenlik açıklarını bulmak ve istismar etmek için yeni süreçler uygulamak için çok çalışıyoruz. Ben de size UEFI tersine mühendislik ve istismar geliştirmeyi öğretmek için buradayım, böylece siz de UEFI hatalarını bulmak ve istismar etmek, yaygın UEFI güvenlik açıklarını anlamak ve ürün yazılımı güvenlik tedarik zincirini daha iyi güvence altına almak için gerekli becerileri geliştirebilirsiniz.
Tecrübeli istismar geliştiricileri için bile, UEFI istismar geliştirme genellikle hem entrika hem de aşılmaz bir havaya sahiptir. UEFI yalnızca modern cihazların önyükleme sürecinden sorumlu platform ürün yazılımı için bir arayüz spesifikasyonu tanımlamakla kalmaz, aynı zamanda platform başlatma bileşenlerinin geniş ve karmaşık bir ortamını da kapsar. Eski bir BIOS makinesinin ayrı platform bileşenlerinin tümü artık UEFI’nin tekil şemsiyesi altına giriyor. Bu, bir tersine mühendis veya istismar geliştiricisi için iki ucu keskin bir kılıçtır: UEFI’nin geniş saldırı yüzeyi güvenlik açıklarını bulmak için geniş fırsatlar sunsa da, karmaşıklığı bu manzarada etkili bir şekilde gezinmek için bir yol haritası gerektirir.
Bu blog yazısı serisi, böyle bir yol haritası sağlamayı amaçlamaktadır. Bu serinin sonunda, başarılı UEFI tersine mühendislik, güvenlik açığı keşfi ve istismar geliştirme için gerekli olan UEFI ve UEFI güvenlik açıkları hakkında temel bilgilerle daha donanımlı olacaksınız.
“UEFI güvenlik açıkları” terimi, aygıt yazılımı veya donanımdan kaynaklanabilen hata sınıflarını kapsar.[1] Bir UEFI güvenlik açığının kaynağı ne olursa olsun, başarılı bir UEFI istismarının önyükleme işleminin ötesinde geniş kapsamlı etkileri olabileceğini anlamak önemlidir. Saldırganlar bu güvenlik açıklarından yararlanarak kalıcı aygıt yazılımı implantları veya bootkitler yüklemek, işletim sistemi düzeyindeki güvenlik azaltmalarını ve erişim kontrollerini atlamak ve deneyimli aygıt yazılımı adli tıp uzmanları hariç herkes tarafından tespit edilmemek gibi yıkıcı etkileri olan istismarlar gerçekleştirebilir.
Bu seri, UEFI’nin amacımızla ilgili çeşitli bileşenlerini tanıtmaktadır: başarılı tersine mühendislik, güvenlik açığı bulma ve UEFI ürün yazılımını hedefleyen istismar geliştirme. UEFI’nin birçok farklı yönünü ele alacak olsam da, UEFI/PI’ya ilişkin bu genel bakışın kapsamlı olmadığını belirtmek önemlidir, çünkü her ayrıntıyı ele almak ciltler doldurabilir. Okuyucuları bu makalenin sonundaki Referanslar bölümünde listelenen ek referanslara göz atmaya teşvik ediyorum.
Eski BIOS’tan UEFI’ye
UEFI spesifikasyonu, platform donanım yazılımı ile işletim sistemi (OS) arasındaki arayüz için platformdan bağımsız bir uygulama tanımlar. UEFI, platform başlatma ve işletim sistemi getirmenin ötesine geçen işlevselliği kapsıyor olsa da, büyük Vincent Zimmer’den[2] alıntı yapmak gerekirse, “Genel olarak … UEFI, önyükleme veya kontrolü bir sonraki kontrol katmanına, yani bir işletim sistemi yükleyicisine aktarmakla ilgilidir” (Zimmer, “Beyond BIOS,” sayfa 1) [1].
UEFI spesifikasyonu yalnızca DXE aşamasında başlayan platformdan bağımsız ürün yazılımı ve işletim sistemi arayüzü için bir uygulama tanımlar. Genel olarak “UEFI önyükleme süreci” olarak adlandırılan şey aslında UEFI/PI önyükleme akışı anlamına gelmektedir. PI, Platform Başlatma anlamına gelir ve UEFI Forum şemsiyesi altında kendi ayrı spesifikasyonuna sahiptir. Şekil 1a’da PI’nin önyükleme akışının SEC ve PEI aşamalarını kapsadığını görebiliriz. Bu bölümde, UEFI/PI önyükleme akışının tüm aşamalarını ele alacağız.
(Şekil 1a. UEFI/PI Önyükleme Süreci aşamaları)
(Resim kaynağı: (https://uefi.org/specs/PI/1.8/V2_Overview.html)
UEFI’yi incelemeye başlamadan önce, BIOS uygulamalarının geçmişi hakkında bilgi edinmek için hızlıca bir gezintiye çıkalım.
UEFI’nin “eski BIOS” yerine geçtiğini söylemek iyi ve güzel, ancak eski BIOS’un ne olduğunu ve UEFI’den nasıl farklı olduğunu anlamak, modern UEFI tehdit ortamını bağlamsallaştırmak için önemlidir. Ayrıca, eski BIOS ve UEFI arasındaki farkları anlamak, tersine mühendis, istismar geliştiricisi veya araştırmacı olarak rolünüzde size yardımcı olacaktır. Önemli bir bağlam sağlamak ve terminolojideki bazı karışıklıkları gidermek için, “eski BIOS” dediğimizde ne demek istediğimizi genişleterek başlayalım.
EFI/UEFI’nin ilk benimsenmesine kadar (1990’ların sonu-2000’ler civarı), eski BIOS, BIOS uygulamaları için standartlaştırılmamış standardı tanımlıyordu. BIOS, donanımı yapılandırmaktan ve bir işletim sistemi yüklenmeden önce sistemin durumunun hazır olmasını sağlamak için gerekli tüm hazırlıkları yapmaktan sorumlu platform ürün yazılımıdır.
Burada, BIOS kodunun belirli Bağımsız BIOS Satıcısı (IBV) tescilli uygulamalarını ifade etmek için “eski BIOS ”u daha uygun bir şekilde tanımlayacağız.
BIOS kodu aynı zamanda önyükleme bloğu kodu olarak da adlandırılırdı ve bugün UEFI’de gördüğümüzden birçok yönden önemli ölçüde farklıdır ve bunlardan birkaçı burada vurgulanmıştır:
Eski BIOS kodu 16-bit assembly ile yazılmış ve gerçek modda çalıştırılmıştır.
Her eski BIOS uygulaması IBV’ye özeldi; her büyük IBV’nin (örneğin AMI, Phoenix) özel bir BIOS uygulaması vardı. Standart bir BIOS spesifikasyonu olmadığından, her IBV’nin özel BIOS’unun tersine mühendisliği imkansız olmasa da oldukça zordu.
Son olarak, eski BIOS, bir işletim sisteminin yüklenmesine hazırlık olarak platform donanımının ve ürün yazılımının başlatılması da dahil olmak üzere sistem açısından kritik işlevleri yerine getirmekten sorumlu olsa da, eski bir BIOS sistemindeki işletim sistemi öncesi ortamın kısıtlamaları ve eski makinelerin donanım kısıtlamaları nedeniyle kapsam ve boyut açısından sınırlıydı.
Daha fazla ayrıntı için “Rootkitler ve Bootkitler”[2] ve “BIOS’un Ötesinde”[1] bölümlerine bakın.
Eski BIOS’un nesli tükenmiş bir teknoloji olmadığına dikkat etmek önemlidir. Giderek daha nadir görülse de, eski BIOS bugün hala sistemlerde kullanılmaktadır. Eski BIOS uygulamalarının tescilli doğası nedeniyle, hevesli tersine mühendis veya istismar geliştiricisine BIOS’un tüm 16 bit gerçek mod kodunu ayrıştırırken ve bir istismar oluşturmak için parçaları yavaşça bir araya getirmeye başlarken yardımcı olacak çok az kaynak mevcuttur.
Bu konuda öne çıkan kaynaklardan biri Darmawan Salihun (pinczakko) tarafından yazılan “BIOS Disassembly Ninjutsu Uncovered” kitabıdır [3]. Bu kitabın ilk baskısı pinczakko’nun GitHub’ında ücretsiz olarak mevcuttur: https://github.com/pinczakko/BIOS-Disassembly-Ninjutsu-Uncovered. Bu kitap, bir etkileşimde eski bir BIOS ile karşılaştığımız ve 16 bitlik assembly ile yazılmış BIOS’a özgü bir istismar geliştirmek istediğimiz nadir durumlarda bizim için paha biçilmez bir kaynak olmuştur.
IBV’ye göre uygulanan eski BIOS’un aksine UEFI, önyükleme işlemi ve platform başlatma için platformdan bağımsız bir arayüz spesifikasyonu sunar. Tüm UEFI uygulamalarında ortak olan temel bir dizi bileşen ve özelliği tanımlarken, aynı zamanda bir platform ürün yazılımı oluşturma özelleştirmesinin genişletilebilirliğini de sunar. Böylece, IBV’ler, OEM’ler ve diğer kuruluşlar UEFI spesifikasyonuna uygun özel UEFI ürün yazılımı uygulayabilir. Bu, (yukarıda belirtildiği gibi) genellikle aşırı spesifik uygulaması, satıcıya özgü BIOS kodu ve özelliklerinin dokümantasyon eksikliği ve tek tip olmayan ikili formatlar gibi faktörler nedeniyle tersine mühendislik yapılması daha zor olan eski BIOS’tan önemli bir değişimdir.
Son olarak, UEFI’nin endüstri genelinde yaygın olarak benimsenmesi eski BIOS’u eskimeye doğru daha da yaklaştırmaya devam ederken, araştırmacıların eski BIOS önyükleme sürecini birkaç nedenden dolayı güçlü bir şekilde kavramaları önemlidir:
Eski BIOS önyükleme sürecinin özellikleri UEFI’nin bir parçası olmaya devam etmektedir (örneğin, eski MBR hala disk üzerinde Silindir 0, Baş 0 Sektör 1’de kalmaktadır) ve eski MBR GUID Bölümleme Tablosuna (GPT) entegre edilmiştir. UEFI önyükleme sürecinin bir parçası olarak kalan eski BIOS bileşenlerini veya süreçlerini anlamak, UEFI önyükleme sürecinin sayısız bileşeni ve genel olarak UEFI BIOS uygulamaları hakkında sağlam bir kavrayışa sahip olmak için çok önemlidir.
Kötü amaçlı yazılımlar, hepimizi rahatsız eden teknoloji borcu olarak bilinen hayalet görüntü nedeniyle UEFI BIOS kullanan sistemlerle birlikte eski BIOS sistemlerini hedef almaya devam etmektedir.
UEFI/PI Önyükleme Süreci: UEFI/PI Önyükleme Aşamaları
Bugüne geldiğimizde, UEFI endüstri standardıdır ve bu PoC’ler kendi kendine yazılmayacaktır, o yüzden hadi başlayalım.
UEFI, selefine kıyasla şaşırtıcı bir derinlik ve genişlikte işlevselliği kapsayan zengin bir ekosistemdir. Bu derinlik ve genişlik beraberinde daha büyük bir saldırı yüzeyini de getiriyor. Biz aygıt yazılımı ve donanım tersine mühendisleri için bu, bir şeker fabrikasında çocuk olmak gibi bir şey!
(Şekil 1b. UEFI/PI Önyükleme Süreci aşamaları ve ortamı
(Resim kaynağı: https://uefi.org/specs/PI/1.8/V2_Overview.html)
UEFI ekosistemini anlamamızla ilgili bazı temel bilgileri ele alalım. En baştan başlayacağız – sıfırlama vektörü.
UEFI PI önyükleme süreci birden fazla aşamadan oluşur (bkz. Şekil 1b). Şimdi ilk dört aşamayı (SEC, PEI, DXE ve BDS) inceleyeceğiz çünkü bunlar platform ürün yazılımı başlatma ortamını tanımlar. UEFI PI önyükleme sürecine ilişkin bu daha ayrıntılı bilgi, bu erken platform ürün yazılımı başlatma aşamalarında benzersiz saldırı yüzeylerinin nasıl ortaya çıktığını anlamak için gerekli olacaktır. UEFI PI önyükleme süreci hakkında ek bilgi için Referanslar bölümündeki [12] ve [13]’e bakın.
Bu aşamaların her birinin kodunun bir SPI flash yongasının BIOS bölgesinde nasıl bölündüğüne dair bağlam sağlamak için, UEFITool’a yüklenmiş bir UEFI BIOS ürün yazılımı görüntüsünün (edk2-platforms deposundan X58I referans platformu için UEFI BIOS) ekran görüntülerini de ekledim (aşağıdaki şekil 2, 3 ve 4’e bakın). UEFITool’u ve kullanışlı özelliklerini bu serinin daha sonraki bir yazısında UEFI laboratuvar kurulumunu ele aldığımızda ele alacağız. Şimdilik, UEFITool’un istenen bir BIOS görüntüsünü açmak ve çeşitli bileşenlerini ayrıştırmak için kullanabileceğimiz açık kaynaklı bir UEFI ürün yazılımı görüntüleyicisi ve düzenleyicisi olduğunu bilmek yeterlidir.
Güvenlik (SEC): PI’nin bu ilk aşaması tüm sistem yeniden başlatma olaylarını ele alır, PEI aşaması için geçici RAM’i başlatır ve önemli verileri PEI Foundation’a iletir.
SEC aşaması kodu SPI flash üzerindeki kendi özel firmware biriminde bulunur. Aşağıdaki Şekil 2’de SEC aşaması kodunun yalnızca SEC çekirdeğinden oluştuğunu görebiliriz. Bu küçük kod boyutu, SEC aşaması sırasında mevcut olan sınırlı ortam ve SEC aşaması kodunun PEI aşaması kodu için minimum bir çalışma ortamı hazırlamadaki rolü göz önüne alındığında mantıklıdır.
(Şekil 2. X58ICH10 Board UEFI BIOS’unun UEFITool görünümü – SEC faz kodu)
SEC aynı zamanda “sistemdeki güvenin kökü olarak hizmet vermekten” de sorumludur [4]. Bu, “Güvenlik” adı verilen bir aşamaya atıfta bulunmasa bile, kendi başına yüklü bir ifadedir. Bunun karmaşıklığını anlamak için bağlama ihtiyacımız var: SEC’in sistem için bir güven kökü olarak uygulanabilirliği, varsa hangi platform ürün yazılımı güvenlik mekanizmalarının etkinleştirildiğine bağlı olarak değişir (örneğin, Intel Boot Guard, Intel BIOS Guard.)
Güvenli Önyükleme uygulamalarındaki (UEFI Güvenli Önyükleme, Intel Önyükleme Koruması ve Intel BIOS Koruması) varyasyonları kısa bir süre sonra ele alacağım, ancak şimdilik SEC’in bir şekilde platform ürün yazılımı bütünlüğü doğrulaması için bir güven zincirinde güven kökü olarak hizmet ettiğini söylemek yeterli. Ancak bu güven zincirinin sağlamlığı SEC’in kendisine değil, platform ürün yazılımı güvenlik teknolojilerinin önceden uygulanmasına bağlıdır.
Özetle SEC aşaması, sistem güvenliğini kilitlemek için sağlam bir başlangıç aşaması olmaktan ziyade PEI aşamasının ihtiyaç duyduğu minimum ortamı hazırlamaktan sorumludur. SEC aşaması kodu temel olarak platformun yeniden başlatılmasını sağlar ve PEI için kullanılan geçici RAM’i hazırlar.
PEI için gerekli koşulları yerine getirdikten sonra bu aşamaya devam edelim.
Ön-EFI Başlatma (PEI): İşlerin ilginçleşmeye başladığı yer burasıdır. PEI, UEFI/PI önyükleme sürecinin az takdir edilen ve genellikle ihmal edilen bir aşamasıdır, ancak kendi başına benzersiz ve zengin bir saldırı yüzeyi sağlar.
PEI öncelikle sistemi, kontrolün DXE aşamasına geçebileceği şekilde hazırlamaktan sorumludur. Burada bir tema mı seziyorsunuz? Evet, her aşamanın görevi genellikle sistemi bir önceki yapılandırma üzerine inşa ederek bir sonraki aşama için hazırlamak ve yapılandırmaktır. Bunun PEI aşaması için ne anlama geldiğini biraz daha inceleyelim.
PEI görevleri:
DXE aşaması için kalıcı sistem belleğini başlatır: PEI aşaması kodu, kalıcı sistem belleğini tamamen başlatana kadar SEC aşamasında başlatılan geçici RAM’i kullanır
Platform bileşenlerini başlatın: PEI’deki modüller, ayrık yonga seti bileşenlerinin başlatılmasından sorumludur ve kontrol önyükleme işleminin bir sonraki aşamasına aktarılmadan önce her bir donanım bileşeninin gerekli tüm bağımlılıklarının karşılandığı minimum bir çalışma ortamına sahip olmasını sağlar
Hand-Off Bloklarını (HOB’lar) kullanarak mimari durumu tanımlayın: PEI aşaması, PEI aşaması sırasında bir HOB listesi doldurur ve bu HOB listesi daha sonra PEI’nin sonunda DXE aşamasına aktarılır. HOB listesi, DXE aşamasına DXE başlamadan önce sistemin ve çeşitli bileşenlerinin durumu hakkında bilgi sağlar
Kurtarma modlarının işlenmesi ve S3 özgeçmiş durumunun işlenmesi [13]
PEI faz kodu iki ana gruba ayrılabilir: PEI Foundation ve PEIM’ler (bkz. Şekil 3).
(Figure 3. UEFITool view of Board X58ICH10 UEFI BIOS – PEI phase code)
SEC aşaması kodu gibi PEI kodu da SPI flaş içindeki özel bir ürün yazılımı biriminde bulunur. Ancak, sistem önyükleme sürecinde ilerledikçe, SEC’den PEI’ye, DXE’ye ve ötesine geçtikçe, her aşama için kodun boyutu artar. Kod boyutundaki artış, her bir aşamanın artan kapsamı ve işlevselliğinin yanı sıra UEFI/PI önyükleme sürecinin her bir aşamasında kod tarafından kullanılan sistem kaynaklarına ve yapılandırılmış arayüzlere ve veri yapılarına artan erişimle paralellik gösterdiğinden mantıklıdır. Şekil 3’te görebileceğimiz gibi, SEC aşaması kodu yalnızca SEC çekirdeğinden oluşmasına rağmen, X58ICH10 UEFI BIOS’un PEI aşaması kodu PEI çekirdeğini (PEI Foundation olarak da bilinir) ve çeşitli PEI modüllerini (PEIM’ler) içerir. Daha önce belirtildiği gibi, PEI faz kodunun bir sorumluluğu da S3 devam ettirme durumunu idare etmektir. PEI ürün yazılımı birimindeki son PEIM, tam da bu görevden sorumlu PEIM olan “S3Resume2Pei ”dir (bkz. Şekil 3).
PEI faz kodunun her bir bileşenini inceleyelim.
PEI Foundation: Bu ikili yürütülebilir dosya, diğer tüm PEI bileşenlerini ve PEIM’leri yönetmekten ve bu bileşenler arasındaki iletişim için gerekli ortamı oluşturmaktan sorumludur.
PEI Foundation ayrıca PEI içinde PEIM’lerin bağımlılık ifadelerini değerlendiren ve hangi PEIM’lerin gerekli bağımlılıklarının karşılandığını ve yüklenebileceğini/çalıştırılabileceğini belirleyen özel bir aşama olan PEI dispatcher’ı da kapsüller.
Ön-EFI Başlatma Modülleri (PEIM’ler): Bu ikili yürütülebilir dosyalar yonga seti bileşenlerinin başlatılmasından sorumludur. Her PEIM bir sürücüdür ve tipik olarak belirli bir donanım veya platform bileşeniyle ilişkilidir. Daha önce de belirtildiği gibi, S3 devam durumu için bir PEIM vardır (S3Resume2Pei; bkz. Şekil 3), ancak PEIM’ler diğer platform bileşenlerinin başlatılmasından da sorumludur. Örneğin, Şekil 3’te “CpuIoPei” ve “PlatformInitPreMem” gibi PEIM’lerin dahil edildiği görülmektedir; bu PEIM’ler adlarının ima ettiği görevlerden sorumludur: sırasıyla CPU I/O’nun başlatılması[3] ve bellek denetleyicisinin başlatılmasından önce platformun başlatılması[4].
PEIM-PEIM Arayüzleri (PPI’ler): Bunlar PEI Foundationakfı tarafından sağlanan ve PEIM’ler arasında iletişime izin veren arayüzlerdir. PEI Foundation, PEIM’ler tarafından her bir PPI’yı kaydetmek için kullanılabilecek PPI’ların ve arayüzlerin bir veritabanını tutar [1, s. 214].
PEI, kısıtlı ve minimal ortamı ve PEI ile DXE kapsamındaki sorumluluklardaki farklılıklar nedeniyle DXE’den farklı olsa da, PEI birçok yönden DXE’ye benzer şekilde çalışır. Bunun bir örneği, PPI’ların PEI Foundation tarafından nasıl kaydedildiği ve sürdürüldüğüdür. PI Spec, Bölüm 2.7’de belirtildiği gibi, “Bir ÜFE tüketicisi, ilgilendiği ÜFE’yi keşfetmek için PEI Hizmeti LocatePpi()‘yi kullanmalıdır. Bir ÜFE üreticisi, PEI Hizmetleri InstallPpi() veya ReinstallPpi() kullanarak mevcut ÜFE’leri PEIM’inde yayınlar.” [5]
Bu, protokollerle etkileşim için DXE aşamasında sağlanan hizmetlere benzer olarak görülebilir (örneğin, protokolleri kaydetme, kaldırma, yeniden yükleme, bulma). EFI Önyükleme Hizmetleri Tablosunda sağlanan aşağıdaki hizmetler sırasıyla yukarıda belirtilen protokol hizmetlerinin her birine karşılık gelir:
EFI_BOOT_SERVICES.InstallProtocolInterface(), EFI_BOOT_SERVICES.UninstallProtocolInterface(), EFI_BOOT_SERVICES.ReinstallProtocolInterface(),
EFI_BOOT_SERVICES.LocateProtocol().
PEI ve ilgili PEI güvenlik açıklarına bu serinin ilerleyen bölümlerinde geri döneceğiz. Şimdilik DXE aşamasına geçelim. PEI’nin birçok yönden DXE ile nasıl benzer olduğunu açıkladım, ancak DXE nedir?
Sürücü Yürütme Ortamı (DXE): DXE aşaması UEFI tarafından kapsanan ilk aşamadır ve artık resmi olarak UEFI diyarındayız! DXE aşaması kodu, UEFI ortamındaki her şeyi hazır ve çalışır hale getirir. DXE kodu, UEFI’deki temel UEFI veri yapıları ve işlevlerine işaretçiler içeren üç temel veri yapısı olan EFI Sistem Tablosu, EFI Önyükleme Hizmetleri Tablosu ve EFI Çalışma Zamanı Hizmetleri Tablosunu kurar. Bu üç veri yapısı UEFI ortamını başlatmak için birlikte çalışır.
DXE aşamasının bir parçası olarak, tüm EFI Önyükleme Hizmetleri, EFI Çalışma Zamanı Hizmetleri ve DXE Hizmetleri başlatılır, böylece burada bulunan tüm işlevler UEFI ortamı için erişilebilir hale getirilir (bkz. Şekil 4).
(Şekil 4. DXE Aşaması DXE Aşamasında Başlatılan UEFI Veri Yapıları
Görüntü Kaynağı: UEFI PI Spesifikasyonu, Cilt 2: DXE Foundation
(9.3. DXE Temel Veri Yapıları, Şekil 9.2 UEFI Sistem Tablosu ve İlgili Bileşenler
https://uefi.org/specs/PI/1.8/V2_DXE_Foundation.html#uefi-system-table-and-related-components))
Bu serinin ilerleyen bölümlerinde, UEFI tersine mühendislik ve istismar geliştirmeyi derinlemesine ele alacağız – programlama yapılarına, çağrı kurallarına ve UEFI API’sinin inceliklerine gerçekten gireceğiz. Bununla birlikte, bir başlangıç olarak, aşağıda basit bir UEFI programının kaynak kodunu ekledim. Açıklamalı kaynak kodu, DXE faz kodunun neyi başlattığı ve güçlü oyuncu veri yapılarımız tarafından sağlanan işlevsellik hakkında ek bağlam sağlar: EFI Sistem Tablosu, EFI Önyükleme Hizmetleri Tablosu ve EFI Çalışma Zamanı Hizmetleri Tablosu.
greetings.c
, UEFI kabuğundaki Konsola “Leviathan’dan Selamlar” yazdıran basit bir UEFI uygulaması için C kaynak kodudur.
greetings.c
için örnek kaynak kodu:
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable //[1] Pointer to EFI_SYSTEM_TABLE passed in
)
/*
* UefiMain does the following:
* [2] Calls SystemTable->ConOut->OutputString function to print “Greetings from Leviathan” to console
* [3] Retrieves pointer to EFI_BOOT_SERVICES table from EFI_SYSTEM_TABLE
* [4]Prints address of EFI_BOOT_SERVICES table to console – using the UEFI library function Print().
*/
{
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Greetings from Leviathan\n"); // [2]
EFI_BOOT_SERVICES *gBS=(SystemTable->BootServices); // [3]
Print(L"Boot Services Table address is: %p \n\n", &gBS); // [4]
return EFI_SUCCESS;
}
Sistemin başlatılması sırasında DXE faz kodunun bir diğer önemli sorumluluğu da yonga seti ve donanımın başlatılmasıdır. Bu kafa karıştırıcı olabilir çünkü PEI aynı zamanda donanım gibi platform bileşenlerinin başlatılmasını da kapsar, bu nedenle bunun DXE bağlamında ne anlama geldiğini açıklayalım. DXE aşaması kodu ya PEI aşamasında gerçekleştirilen platform bileşenlerinin önceden başlatılması üzerine inşa edilecek ya da başlatma işlemini kendisi gerçekleştirecek veya bu ikisinin bir kombinasyonunu kullanacaktır.
Bununla birlikte, DXE donanım bileşenlerini başlatmak için PEI aşamasını gerektirmez ve DXE teknik olarak PEI aşamasını hiç gerektirmez. DXE faz kodu, PEI aşaması sırasında oluşturulabilen bir veri yapısı olan HOB listesine ihtiyaç duyar. Yine PI Spec’e göre, “DXE aşaması, yürütülmesi için bir PEI aşaması gerektirmez. DXE aşamasının yürütülmesi için tek gereklilik geçerli bir HOB listesinin varlığıdır. DXE aşamasının yürütülmesi için geçerli bir HOB listesi üretebilen birçok farklı uygulama vardır. Bir PI Mimarisi ürün yazılımı uygulamasındaki PEI aşaması, olası birçok uygulamadan yalnızca biridir.” [6]
DXE faz kodu tek başına bir ikili kod değildir. PEI aşaması gibi, DXE aşaması kodu da iki gruba ayrılabilir: DXE Foundation (DXE Dispatcher adı verilen bir bileşen içerir) ve DXE sürücüleri (bkz. Şekil 5). DXE Foundation ve DXE sürücüleri daha sonra detaylandırılacaktır.
Şekil 5. DXE Temel Bileşenleri DXE Temel Bileşenleri
Görüntü Kaynağı: UEFI PI Spesifikasyonu, Cilt 2: DXE Foundation
(9.4. Gerekli DXE Temel Bileşenleri
https://uefi.org/specs/PI/1.8/V2_DXE_Foundation.html#dxe-foundation-components)
DXE Temeli: DXE Altyapısı (bazı literatürde “DXE Çekirdeği” olarak da anılmaktadır [5]) yukarıda bahsedilen önemli tabloların (yani UEFI Sistem Tablosu, Önyükleme Hizmetleri Tablosu, Çalışma Zamanı Hizmetleri Tablosu) ve bunlara karşılık gelen DXE Hizmetleri, Önyükleme Hizmetleri ve Çalışma Zamanı Hizmetlerinin kurulumundan sorumlu bir önyükleme hizmeti görüntüsüdür. DXE Foundation, DXE sürücülerini keşfetmek ve yürütmekten ve bağımlılıklarının karşılanmasını sağlamaktan sorumlu olan DXE dağıtıcısını kapsüller.
DXE Sürücüleri: Bu sürücüler, yonga seti ve donanım dahil olmak üzere platformu başlatır ve konsol I/O hizmetlerini kurar. DXE Foundation, HOB listesini kullandığından, DXE sürücüleri bu bilgileri önceki başlatma işleminin üzerine inşa etmek ve ek bileşenleri başlatmak için kullanabilir. Dikkate değer bir örnek, DXE sürücülerinin genellikle bu serinin ilerleyen bölümlerinde ele alacağımız Sistem Yönetim Modu’nun (SMM) kurulumundan sorumlu olmasıdır.
PI/UEFI önyükleme sürecinin önceki aşamalarıyla karşılaştırıldığında DXE, büyük ölçüde sistem kaynaklarına, özellikle de PEI aşamasında kurulan yeni başlatılmış kalıcı belleğe erişimi sayesinde mümkün olan geniş bir ortama sahiptir. Platform ürün yazılımı arayüzümüze böylesine geniş ve derin bir işlevsellik kazandırdığı için DXE aşamasını alkışlayabiliriz. greetings.c
örnek UEFI uygulaması kaynak kodunda, UEFI uygulamaları ve sürücüleri için mümkün olanın yüzeyini çizen bir örnek gördük, ancak seride ilerledikçe göreceğimiz gibi, UEFI ortamında bir programcıya sunulan çok daha fazla karmaşıklık ve esneklik var. UEFI ortamının tamamen başlatıldığı DXE aşamasından çıkıp işletim sistemi çalışma zamanı ortamına doğru ilerlerken, bu yeni UEFI ortamını ayrı bir ekosistem olarak düşünmek faydalı olabilir (neredeyse işletim sisteminden önceki bir işletim sistemi, bir proto-OS gibi).
Önyükleme Aygıtı Seçimi (BDS): BDS aşaması UEFI önyükleme yöneticisi olarak düşünülebilir.
BDS aşaması kodu, olası önyükleme aygıtlarını numaralandırma, önyükleme sırasını değerlendirme ve nihayetinde kontrolü önyükleme aygıtına (genellikle işletim sistemi yükleyicisi) aktarmadan önce son UEFI temizlik işlemlerini gerçekleştirme gibi önemli görevleri yerine getirir.
BDS aşamasının sonunda, EFI_BOOT_SERVICES tablosunu yok eden ExitBootServices()
işlevine bir çağrı yapılır. Bu noktadan sonra EFI_BOOT_SERVICES işlevleri artık çağrılamaz. Özellikle, EFI_RUNTIME_SERVICES tablosu korunur ve kullanıcı işletim sistemi çalışma zamanı ortamından EFI_RUNTIME_SERVICES işlevlerine erişebilir. Bu nedenle BDS, UEFI API’sinin önemli bir kısmının artık kullanılamadığı UEFI’nin “son” aşaması olsa da BDS aşaması UEFI ortamını tamamen yok etmez. EFI_RUNTIME_SERVICES tablosu ve ilişkili işlevselliği bir sonraki aşama olan Geçici Aşama Yüklemesi (TSL) ve nihayetinde işletim sistemi kurulumu boyunca korunduğundan, platform ürün yazılımı ile işletim sistemi arasındaki iletişim için bir köprü korunur.
BDS aşaması kod sorumluluklarının daha resmi bir listesi için UEFI Spesifikasyonuna bakın:
“BDS aşaması, BDS Mimari Protokolünün bir parçası olarak uygulanmaktadır. DXE Foundation, bağımlılıkları karşılanan tüm DXE sürücüleri DXE Dispatcher tarafından yüklendikten ve yürütüldükten sonra kontrolü BDS Mimari Protokolüne devredecektir. BDS aşaması aşağıdakilerden sorumludur:
- Konsol cihazlarının başlatılması
- Aygıt sürücülerini yükleme
- Önyükleme seçimleri yüklenmeye ve yürütülmeye çalışılıyor” [7]
Önemli not: UEFI/PI önyükleme akışının aşamalarına ilişkin yukarıdaki genel bakış, önyükleme sürecinin SEC öncesinde gerçekleşen yönlerini kapsamamaktadır, ancak SEC aşamasının ilk komutundan önce bile birçok şey gerçekleşir. Bu durum özellikle Intel Boot Guard ve Intel BIOS Guard gibi teknolojiler kullanıldığında geçerlidir (örneğin, Intel Boot Guard uyumlu bir sistem için etkinleştirildiğinde, sıfırlama vektöründen sonraki ilk komutun yürütülmesinden önce Kimliği Doğrulanmış Kod Modülü [ACM] yüklenir ve yürütülür). Converged Security and Management Engine (CSME) gibi diğer platform bileşenleri Intel önyükleme sürecinde önemli bir rol oynar ancak kısa olması açısından bu blog yazısında ele alınmayacaktır. CSME ve önceki CSME güvenlik açıkları ve istismarları hakkında ek kaynaklar Referanslar bölümünde yer almaktadır.
Güvenli Önyükleme ve Platform Ürün Yazılımı Güvenlik Teknolojileri
UEFI/PI önyükleme akışının ana aşamalarını tartıştığımıza göre, şunu sorabilirsiniz: Bir UEFI BIOS’unu bir tehdit aktörü tarafından değiştirilmekten, kurcalanmaktan veya başka bir şekilde istismar edilmekten nasıl koruruz? Güvenli Önyükleme teknolojilerine girin. “Güvenli Önyükleme teknolojileri”, sağlam ürün yazılımı bütünlüğü doğrulaması sağlamak ve bir UEFI BIOS’u mümkün olduğunca kilitlemek için tasarlanmış çeşitli platform ürün yazılımı güvenlik mekanizmalarını kapsayan bir şemsiye terimdir.
“Güvenli Önyükleme”, uygulandığı önyükleme süreci hiyerarşisinin seviyesine bağlı olarak üç şekilde ortaya çıkar:
- İşletim Sistemi Güvenli Önyükleme: İşletim sistemi önyükleyicisi seviyesinde uygulanır. Bu, işletim sistemi çekirdeği ve önyükleme başlatma sürücüleri gibi işletim sistemi önyükleyicisi tarafından yüklenen bileşenleri doğrular.
- UEFI Güvenli Önyükleme: UEFI ürün yazılımında uygulanır. Bu, UEFI DXE sürücülerini ve uygulamalarını, Seçenek ROM’larını ve OS önyükleyicilerini doğrular.
- Platform Güvenli Önyükleme: Donanıma sabitlenmiştir. Bu, platform başlatma ürün yazılımını doğrular.“
Platform güvenli önyükleme teknolojilerinin farklı çeşitlerinin bu yararlı sınıflandırması, Bölüm 17 “UEFI Güvenli Önyükleme Nasıl Çalışır” [8] içindeki “Rootkits and Bootkits” bölümünden alınmıştır.
Aşağıdaki açıklamalar, birçok Güvenli Önyükleme ve platform ürün yazılımı güvenlik teknolojileri arasındaki temel farklardan bazılarının kapsamlı olmayan bir açıklamasıdır. Bu teknolojilerin nasıl uygulandığını, neleri koruduğunu, neleri koruyamadığını ve kullanımlarının platform ürün yazılımı tehdit ortamını nasıl değiştirdiğini daha iyi anlamanıza yardımcı olmaya çalışacağım.
Not: Bu bölümde sadece Intel işlemciler için Secure Boot teknolojilerine odaklanacağım. Odaklanacağım üç teknoloji UEFI Secure Boot, Intel Boot Guard ve Intel BIOS Guard’dır.
UEFI Güvenli Önyükleme
UEFI Secure Boot en temel katmandır ve DXE’nin sonraki aşamalarından başlayarak UEFI BIOS’u korur. SPI flaştan başlayıp işletim sistemi kurulumuna kadar devam eden sürecin geç bir noktasında koruma ve görüntü doğrulaması sağlar.
UEFI Güvenli Önyükleme etkinleştirilmiş tek platform ürün yazılımı güvenlik mekanizması ise SEC, Ölçüm için Çekirdek Güven Kökü (CRTM) olarak hizmet veren İlk Önyükleme Bloğunun (IBB) bir parçasını oluşturur [12]. UEFI Güvenli Önyükleme, güven kökü olarak iki bileşenin bütünlüğüne dayanır: IBB (SEC ve PEI) ve Platform Anahtarı. PI bileşenleri (SEC ve PEI) SPI flaşta saklanır ve UEFI Secure Boot tarafından dolaylı olarak güvenilir. UEFI Secure Boot, UEFI BIOS ürün yazılımı görüntüsünün belirli bileşenlerinin bütünlüğünü doğrulamak için bir Açık anahtar altyapısı (PKI) kullanır. UEFI Secure Boot’un PKI’sının ana bileşenleri arasında db ve dbx veritabanları (sırasıyla UEFI ikili dosyalarının bilinen-iyi sertifikalarını/hash’lerini ve UEFI ikili dosyalarının bilinen-güvensiz sertifikalarını/hash’lerini depolamak için kullanılır) ile her ikisi de dijital imzaların doğrulanması için kullanılan Anahtar değişim anahtarı (KEK) ve Platform Anahtarı (PK) yer alır [9].
db veritabanı, dbx veritabanı, PK ve KEK’in ayrıntılı bir dökümü ve UEFI Güvenli Önyükleme sürecindeki rolleri bu makalenin kapsamı dışındadır (daha fazla bilgi için bkz. Güvenli Önyükleme ve Platform Ürün Yazılımı Güvenlik Teknolojileri Kaynakları ve Referansları). Bizim amaçlarımız için, UEFI Güvenli Önyükleme’nin yalnızca UEFI bileşenlerini doğruladığını anlamak yeterlidir. Böylece, ürün yazılımı bütünlüğü doğrulamasına DXE aşamasında başlar. UEFI Secure Boot için güven kökünü oluşturduğundan IBB’nin güvenli olduğuna zımnen güvenilir. Bu nedenle, UEFI Secure Boot DXE veya BDS aşamalarında yüklenen herhangi bir UEFI uygulaması veya sürücüsüne karşı ürün yazılımı güvenlik doğrulaması uygulasa da SEC veya PEI bileşenlerinin bütünlüğünü doğrulamaz.
İlk tasarım perspektifinden bakıldığında bile, UEFI Güvenli Önyükleme’deki tasarım kusurları ve dolayısıyla bypass için yollar çok sayıdadır. Örnek olarak, UEFI Secure Boot’un ürün yazılımı görüntü bütünlüğü doğrulama mekanizmalarının potansiyel olarak atlanmasına kapı açan UEFI Secure Boot’un iki ana tasarım özelliğini vurguladım. Bu iki örnek kapsamlı değildir ve Secure Boot’un tanıtımından bu yana bu konuda önemli ve mükemmel araştırmalar yapılmıştır. Güvenli Önyükleme bypass teknikleri hakkında daha fazla bilgi için [Güvenli Önyükleme ve Platform Ürün Yazılımı Güvenlik Teknolojileri Kaynakları ve Referansları] bölümüne bakın.
- UEFI Güvenli Önyükleme için güven kökü, SPI flaştan yüklenen PI ürün yazılımıdır; bir saldırgan SPI yazma erişimi elde edebilir ve flaştaki PI ürün yazılımını değiştirebilirse, UEFI Güvenli Önyükleme güven köküne sahip olarak tüm UEFI Güvenli Önyükleme zincirini etkili bir şekilde tehlikeye atar.
- UEFI Secure Boot, ürün yazılımı güvenlik doğrulamasına DXE aşamasında başlar. Bu mantıklıdır çünkü UEFI DXE aşamasında başlar, bu nedenle UEFI Secure Boot yalnızca kendi bileşenlerinin doğrulanmasından sorumlu olmalıdır. Bununla birlikte, PI ürün yazılımındaki (yani PEI) güvenlik açıkları, SMM’yi (SPI flaşa yazmak için) veya DXE’den önce yüklenen platform ürün yazılımının diğer bileşenlerini hedef almak için istismar edilebilir ve kullanılabilir.
UEFI ürün yazılımı görüntü bütünlüğünün doğrulanmasını ve UEFI/PI kodunun tüm aşamalarının ölçülmesini sağlamak için daha sağlam bir başka teknolojiye başvurabiliriz: Intel Boot Guard.
Intel Önyükleme Koruması
Intel Boot Guard, UEFI Secure Boot’u çevreleyerek, UEFI/PI önyükleme akışının tüm aşamalarını kapsayacak şekilde güven kökünü genişleten bir ürün yazılımı bütünlüğü koruma ve doğrulama katmanı oluşturur. Intel Boot Guard ile platform ürün yazılımı bütünlüğü doğrulaması artık SEC ve PEI faz kodunun yanı sıra UEFI Secure Boot tarafından kapsanan DXE faz kodunu da kapsıyor. Başka bir deyişle, Intel Boot, UEFI BIOS’u SPI flash’tan hareket ederken sürecin en erken noktasından itibaren ve ardından UEFI/PI önyükleme sürecinin önceki aşamalarında aşamalı olarak korur ve son olarak PEI’den DXE’ye geçişten sonra ürün yazılımı görüntüsü doğrulama sürecini devam ettirmek için UEFI Secure Boot ile birlikte çalışır. Boot Guard, UEFI BIOS görüntüsünün bütünlüğünün UEFI/PI önyükleme sürecinin her aşaması boyunca ölçülmesini ve doğrulanmasını sağlar.
Intel Boot Guard güven kökünü daha da yukarı taşır; SPI flaşta saklanan PI ürün yazılımının bütünlüğüne güvenmek yerine (UEFI Güvenli Önyükleme için olduğu gibi), Boot Guard, anakartın üzerindeki Alan Programlanabilir Sigortaya (FPF) yakılan donanımda saklanan bir anahtarı kullanarak ürün yazılımı bileşenlerinin bütünlüğünü doğrulamak için Intel Kimliği Doğrulanmış Kod Modülünü (ACM) kullanır.
Boot Guard etkinleştirildiğinde, ACM CPU üzerinde Cache-as-Ram (CAR) adı verilen korumalı bir bellek bölgesinde çalışır ve IBB’nin (PI ürün yazılımının SEC ve PEI bileşenleri) bütünlüğünü doğrulamak için FPF’ye kilitlenen anahtarı kullanır. Böylece ACM, IBB’deki ilk komutu çalıştırmadan önce ürün yazılımı görüntü ölçümü ve doğrulaması gerçekleştirir [8]. IBB doğrulanırsa, CPU kontrolü IBB’ye geçirir ve ardından sıfırlama vektöründen ilk komutunu yürütmeye başlar. Boot Guard daha sonra UEFI/PI önyükleme akışı SEC’den PEI’ye ve DXE’ye geçerken platform ürün yazılımının sonraki parçalarını doğrulamaya devam edecektir. DXE aşamasına ulaşıldığında, UEFI Secure Boot kendi işini yapabilir ve DXE bileşenleri üzerinde kendi ürün yazılımı bütünlüğü doğrulama işlemini başlatabilir.
Intel Boot Guard’ın avantajları, artık yalnızca UEFI Secure Boot’a güvenmek yerine, donanıma kaynaştırılmış bir anahtar kullanarak IBB’nin tüm bileşenlerini doğrulayarak platformun çok daha geniş bir yelpazesinde platform ürün yazılımı güvenlik doğrulaması sağlamasıdır. Boot Guard, doğru uygulandığı takdirde platform ürün yazılımı saldırı yüzeyini büyük ölçüde daraltır.
Bu alanda Boot Guard bypassları ile ilgili çok fazla çalışma yapılmıştır. Genellikle Boot Guard’daki yanlış yapılandırmalar, donanım yazılımı güvenlik zincirinde boşluklar bırakır ve bu boşluklar bir saldırgan için yeterli açıklık olabilir. Aşağıda Boot Guard bypass teknikleriyle ilgili birkaç araştırma örneğine yer verdim. Bu konuya blog serisinin ilerleyen bölümlerinde UEFI hatalarından bahsederken döneceğiz.
Intel Boot Guard hakkında dikkat edilmesi gereken son bir önemli nokta da SPI flaşa okuma/yazma erişimini engellemediğidir. Intel Boot Guard, güven kökü olarak IBB’den başlayarak UEFI ürün yazılımı görüntüsünün bütünlüğünü doğrular, ancak rolü “CPU IBB’yi çalıştırmak için sıfırlamadan çıkmadan önce bu kodun doğruluğunu [doğrulayarak]” ürün yazılımı bütünlüğü doğrulaması yapmaktır. [10] SPI flash’a okuma/yazma erişimini engellemek ve böylece SPI flash’ta yerleşik ürün yazılımı implantları veya BIOS tabanlı rootkit’ler için saldırı vektörlerini en aza indirmek için başka bir teknolojiye başvurabiliriz: Intel BIOS Guard.
Intel BIOS Koruması
BIOS Guard, birçok ürün yazılımı değişiklik vektörüne karşı koruma sağlayarak ve SPI flaşta saklanan güven kökünü (IBB) ve diğer ürün yazılımı bileşenlerini tehlikeye atılmaya veya kurcalanmaya karşı koruyarak UEFI Secure Boot ve Intel Boot Guard tarafından bırakılan güvenlik boşluklarını doldurur.
Intel BIOS Guard, SPI flash yongasını (ve dolayısıyla SPI flash üzerinde bulunan UEFI BIOS’u) yetkisiz okuma/yazma işlemlerine karşı korur. BIOS Guard özellikle SPI flash modifikasyonu için saldırı yüzeyini azaltmaya odaklanır. Özellikle, SMM kodundan (yani SMI işleyicilerinden) SPI flaşa erişimi kısıtlar. BIOS Guard, Flash okuma/yazma erişimini kısıtlayarak ve yalnızca BIOS Guard’ın AC-RAM modunda çalışan kodun SPI flash’ı değiştirme yetkisine sahip olmasını sağlayarak SMI işleyicilerinden ve çoğu POST kodundan gelen saldırı vektörlerini ortadan kaldırır [10].
UEFI Kabuğu
UEFI Kabuğu, çeşitli UEFI bileşenleriyle (örneğin, diğer UEFI uygulamaları ve sürücüleri ile bunların protokolleri) etkileşim için kabuk benzeri bir arayüz sağlayan bir UEFI uygulamasıdır. Bir üretim cihazında UEFI Kabuğuna sahip olmak nadirdir (ve kesinlikle tavsiye edilmez). Bununla birlikte, test amacıyla, UEFI kabuğu hem açıkları test etmek hem de sistemi daha iyi anlamak için mükemmel bir ortamdır. [6]
UEFI Uygulamaları ve Sürücüleri
UEFI uygulamaları ve sürücülerinin her ikisi de UEFI görüntüleridir ve serinin ilerleyen bölümlerinde UEFI tersine mühendislik ve istismar geliştirmeyi incelerken çalışacağımız birincil UEFI bileşeni olacaklardır. Şimdilik, UEFI uygulamaları ve sürücüleri hakkında dikkat edilmesi gereken önemli noktalar bunlardır:
- UEFI uygulamaları ve sürücülerinin her ikisi de PE/COFF başlığına sahip ikili yürütülebilir dosyalar.
- Bir UEFI uygulaması ile bir UEFI sürücüsü arasındaki tek fark, bir uygulamanın çalıştıktan sonra bellekten kaldırılması ve bir sürücünün kaldırılana kadar yerleşik kalmasıdır.
UEFI Protokolleri
Bu protokoller UEFI’nin et ve patatesleri olarak hizmet vermektedir. Protokollerin rolü UEFI’nin o kadar ayrılmaz bir parçasıdır ki pratikte “Linux’ta her şey bir dosyadır” sözüne benzer. UEFI’de bir protokol, veri ve işlev işaretçilerini kapsülleyen bir arayüzdür. Her platform bileşeni ve ağlar veya diskler gibi her cihaz için, donanım ve ürün yazılımı iletişimi için soyutlama katmanı olarak hizmet vermeye hazır bir veya daha fazla protokol vardır.
Protokollerin diğer UEFI terimleriyle dikkate değer birkaç bağlantısı vardır:
- Bir UEFI sürücüsü bir veya daha fazla UEFI protokolü üretebilir.
- UEFI tanıtıcıları bir veya daha fazla protokolün koleksiyonlarıdır. Tüm tutamaçlar tutamaç veritabanında saklanır. Tanıtıcı veritabanı (şaşırtıcı olmayan bir şekilde) bir tanıtıcı anahtarını protokollerle ilişkilendiren bir sözlük yapısıdır, ancak protokol türleri tanıtıcı türünü belirler (bu durumda değerler anahtarı etkiler). [1, p. 17]
UEFI Veri Yapıları
EFI Sistem Tablosu: UEFI’deki ilk büyük veri yapısı olan EFI Sistem Tablosu, EFI Önyükleme Hizmetleri Tablosu ve EFI Çalışma Zamanı Hizmetleri Tablosu dahil olmak üzere diğer önemli veri yapılarına yönelik önemli veriler ve işaretçiler içerir. Ayrıca konsol I/O hizmetleri ve UEFI Yapılandırma Tablosu için işaretçiler içerir. UEFI Yapılandırma Tablosu bilinen GUID’leri ve karşılık geldikleri işaretçileri içerir ve bu tablo isteğe bağlı olarak ürün yazılımı ekosisteminde farklı rolleri olan diğer tabloları da içerebilir (örn. ACPI Tablosu, HOB Listesi) [6]. Bu veri yapısının UEFI’deki önemi abartılamaz. PI Spec’e göre, “DXE aşamasında mevcut olan tüm hizmetlere UEFI Sistem Tablosuna bir işaretçi aracılığıyla erişilebilir.” [6]
EFI Önyükleme Hizmetleri Tablosu: Bu, işletim sistemi açılmadan önce UEFI ürün yazılımı tarafından kullanılan işlevlere işaret eden bir işlev işaretçileri tablosudur. EFI Önyükleme Hizmetleri Tablosunun işlevleri, UEFI ürün yazılımı kontrolü işletim sistemine aktardıktan ve önyükleme hizmetlerini sonlandırdıktan sonra kullanılamaz. Önyükleme hizmetlerinin sonlandırılması, EFI_BOOT_SERVICES.ExitBootServices() olarak adlandırılan EFI Önyükleme Hizmetleri Tablosuna son bir çağrı yapan UEFI işletim sistemi yükleyicisi tarafından yapılır.
EFI Çalışma Zamanı Hizmetleri Tablosu: Bu, UEFI ürün yazılımı tarafından kullanılan işlevlere işaret eden bir işlev işaretçileri tablosudur. Bu işlevler işletim sistemi yüklendikten sonra kullanılabilir (dolayısıyla “Çalışma Zamanı Hizmetleri tablosu” adı verilir) ve işletim sistemi kodunun aygıt yazılımı bileşenleriyle etkileşime girmesi için bir araç olarak sağlanır.
Sonuç
UEFI’ye genel bakış seminerimizin sonuna geldik ve bu tanıtım seminerine katıldığınız için teşekkür ederiz. Bugünlük dersi sonlandırmadan önce, blog serisinin geri kalan yazılarının yapısını tanıtmak için sizi bir veda düşüncesiyle baş başa bırakacağım. Büyük Donald Knuth’u ve onun bilgisayar bilimlerinde teori ve pratik dengesine ilişkin bilgeliğini hatırlayarak, UEFI 1337 üstünlüğüne ulaşmak için hem teori hem de pratiğin gerekli olduğunu biliyoruz. Başarılı UEFI açıkları yazmak için aşağıdakilere ihtiyacımız var:
- Teori: UEFI ve istismarlara yol açan çeşitli saldırı vektörleri hakkında temel bir anlayış
- Uygulama: UEFI istismar geliştirme deneyimi
Teori gereksinimlerimizi karşılamak için ihtiyacımız olan şeylerin çoğunu belirledik. Gelecek blog yazılarında, UEFI tersine mühendislik, güvenlik açığı bulma ve istismar geliştirmenin pratik bileşenlerine geçmeden önce kalan temel bilgileri (UEFI Güvenlik Açıklarına genel bakış) ele alacağız.
“UEFI yeni BIOS’tur” yazısının bir sonraki bölümünde görüşmek üzere.
Dipnotlar
[1] Donanım yazılımı/donanım hata sınıflarına örnek olarak UEFI modüllerinin, sürücülerinin veya uygulamalarının güvensiz uygulamalarından kaynaklanan bellek bozulması güvenlik açıkları; donanım tasarım kusurlarından, yerleşik güvenlik özelliklerinin (örn. Intel Boot Guard) yanlış yapılandırılmasından veya yanlış uygulanmasından ya da koruma bitlerinin doğru şekilde ayarlanmamasından kaynaklanan güvenlik açıkları; ve donanım yazılımı tedarik zincirindeki yama boşluklarından kaynaklanan güvenlik açıkları verilebilir
[2] (önde gelen UEFI araştırmacısı ve “Beyond BIOS” ve bu alandaki diğer saygın eserlerin yazarı, bu seri boyunca çalışmalarına atıfta bulunacağız)
[3] Bkz. ”
“ referans kodunu edk2 deposunda bulabilirsiniz.[4] Bkz.
“ referans kodunu edk2-platforms deposunda bulabilirsiniz.[5] Örneğin, “Beyond BIOS” ve “Rootkits and Bootkits” bölümlerinin her ikisi de buna DXE Core olarak atıfta bulunmaktadır.
[6] UEFI Kabuğunun da kendi özel spesifikasyonu vardır:
https://uefi.org/sites/default/files/resources/UEFI_Shell_2_2.pdf
Referanslar
[1] “Beyond BIOS,” Vincent Zimmer vd.
[2] “Rootkits and Bootkits,” Alex Matrosov, Eugene Rodionov ve Sergey Bratus, No Starch Press, 2019.
[3] “BIOS Disassembly Ninjutsu Uncovered,” Darmawan Salihun (pinczakko),
https://github.com/pinczakko/BIOS-Disassembly-Ninjutsu-Uncovered
.[4] “UEFI Platform Başlatma Spesifikasyonu, Cilt I: Pre-EFI Initialization Core Interface, Section 13: Security (SEC) Phase Information,” UEFI Platform Initialization Specification, Volume I: Ön-EFI Başlatma Çekirdek Arabirimi, sürüm 1.8,
https://uefi.org/specs/PI/1.8/V1_Security_SEC_Phase_Information.html
.[5] “UEFI Platform Başlatma Spesifikasyonu, Cilt I: Pre-EFI Initialization Core Interface, Section 2.7 PEIM-to-PEIM Interfaces (PPIs),” UEFI Platform Initialization Specification, Volume I: Ön-EFI Başlatma Çekirdek Arayüzü, sürüm 1.8,
https://uefi.org/specs/PI/1.8/V1_Overview.html#peim-to-peim-interfaces-ppis
.[6] “UEFI Platform Başlatma Spesifikasyonu, Cilt II: Sürücü Yürütme Ortamı Çekirdek Arayüzü, Bölüm 2.1. Sürücü Yürütme Ortamı (DXE) Aşaması,” UEFI Platform Başlatma Belirtimi, Cilt II: Sürücü Yürütme Ortamı Çekirdek Arabirimi, sürüm 1.8,
https://uefi.org/specs/PI/1.8/V2_Overview.html#driver-execution-environment-dxe-phase
.[7] “UEFI Platform Başlatma Belirtimi, Cilt II: Sürücü Yürütme Ortamı Çekirdek Arabirimi, Bölüm 3.1 Önyükleme Yöneticisi,” UEFI Platform Başlatma Belirtimi, Cilt II: Sürücü Yürütme Ortamı Çekirdek Arabirimi, sürüm 1.8,
https://uefi.org/specs/PI/1.8/V2_Boot_Manager.html
.[8] “Rootkits and Bootkits, Chapter 17: How UEFI Secure Boot Works, page 320,” Alex Matrosov, Eugene Rodionov ve Sergey Bratus, No Starch Press, 2019.
[9] “Rootkitler ve Bootkitler, Bölüm 17: UEFI Güvenli Önyükleme Nasıl Çalışır, sayfa 321,” Alex Matrosov, Eugene Rodionov ve Sergey Bratus, No Starch Press, 2019.
[10] “Intel® Hardware Shield Overview,” Whitepaper, Information Technology Cybersecurity, Intel,
.[11] “Düşük Seviyeli PC/Sunucu Saldırı ve Savunma Zaman Çizelgesi,” @DarkMentorLLC’den @XenoKovah tarafından
https://darkmentor.com/timeline.html
.
[12] “Understanding modern UEFI-based platform boot,” David Kaplan (@depletionmode), depletionmode, https://depletionmode.com/uefi-boot.html
.[13] “PI Boot Flow,” Brian Richardson, Tianocore, Intel,
https://github.com/tianocore/tianocore.github.io/wiki/PI-Boot-Flow
.