- Mart 2024’te keşfedilen
xzarka kapısı, etkilenensshdortamlarında uzaktan kod çalıştırmaya yol açabilirdi; NixOS örneği ise tekrarlanabilir derlemelerin tedarik zinciri kurcalamasını mekanik olarak ortaya çıkarabileceğini gösteriyor - Kötücül unsur,
xzGit deposunun tamamında değil,5.6.0ve5.6.1sürümlerinin bakımcı tarafından sağlanan release tarball dosyalarında saklıydı; derleme sırasında sahte.xztest dosyalarından kabuk betiği ve nesne dosyası üretiyordu - Saldırı,
liblzmayüklenirken kod çalıştırmak içinglibc’nin ifunc özelliğini kullanıyor vesshd’ninlibsystemdüzerindenliblzmaya geçişli olarak bağımlı olduğu Debian/Fedora tabanlı ortamları hedefliyordu - NixOS normalde GitHub’ın otomatik ürettiği kaynak arşivlerini tercih eder; ancak
xz,nixpkgsbootstrap aşamasında yer aldığındanautoconfbağımlılık döngüsünden kaçınmak için bakımcı tarball’ına güvenmek zorundaydı - Önerilen savunma, bootstrap sonrasında
xzyi GitHub kaynaklarından yeniden derleyip mevcut tarball çıktısıyla karşılaştırmak; koşul etkinleştirildiğindeliblzma.soboyut farkı ve_get_cpuidsembolünün eklendiği ortaya çıktı
xz arka kapısının gizlenme biçimi
xz, Linux dağıtımlarının kritik yollarında kaynak tarball’larını açmak için sık kullanılan bir sıkıştırma/açma yazılımıdır- Mart 2024’te
xziçinde bir arka kapı keşfedildi; kötü niyetli bakımcı Jia Tan, yaklaşık 3 yıl boyunca güven kazanıp depoya push yetkisi elde ettikten sonra meşru katkıların arasına parça parça obfuscate edilmiş kod ekledi - Andres Freund, birkaç Debian unstable makinesinde yaşadığı
sshtarafındaki 500 ms’lik performans düşüşünü araştırırken iziliblzmaya kadar sürdü ve arka kapıyı tespit edip belgeledi - Arka kapının amacı,
sshyi ele geçirerek belirli bir RSA anahtarıyla giriş yapıldığında saldırganın kurban makinede keyfi komut çalıştırabilmesini sağlamaktı
Kötücül tarball ve derleme sırasında üretilen nesne
- Kötücül bileşenler doğrudan
xzGit deposundaki kodun tamamına yerleştirilmemişti; Jia Tan tarafından derlenip imzalanarak dağıtılanxz5.6.0 ve 5.6.1 release tarball’larına dahil edilmişti - Git deposundaki bazı test amaçlı
.xzdosyalarının içine makine kodu gizlenmişti; release tarball’ına ise bunu çıkarmak için kamufle edilmiş bir değişiklik eklenmişti - Özellikle
m4/build-to-host.m4değişikliği dışarıdan zararsız görünüyor ve yorum satırları içeriyordu; ancak gerçekte birden çok sahte.xztest dosyasını çözüp obfuscation’ını kaldıran bir komut zincirini gizliyordu - Bu sürecin iki çıktısı vardı
xzderlemesi sırasında çalıştırılan bir kabuk betiği- Kötücül bir ikili nesne dosyası
- Derleme sırasında çalıştırılan kabuk betiği iki rol üstleniyordu
- Belirli Linux dağıtımı,
glibcözellikleri,sshkurulu olup olmadığı gibi arka kapı çalıştırma koşullarını kontrol etmek - Normal nesne olan
liblzma_la-crc64_fast.odosyasını, arka kapı nesne dosyasının_get_cpuidsembolünü kullanacak şekilde değiştirmek
- Belirli Linux dağıtımı,
- Russ Cox’un
xzbetik analizi, derleme sırasında kötücül kaynakların nasıl üretildiğini ayrıntılı biçimde ele alır
sshdye uzanan ifunc ele geçirmesi
- Dinamik bağlanan programlarda, çalışma anında dinamik yükleyici paylaşımlı kütüphaneleri belleğe yükler ve sembol adreslerini Global Offset Table(GOT) içine doldurur
glibc’nin ifunc özelliği, dinamik yükleme sırasında aynı fonksiyonun birden çok uygulamasından birini seçmeye yarar;xzarka kapısı bunu kötücül kod yürütme yolu olarak kullandı- Debian ve Fedora gibi bazı dağıtımlarda
ssh,systemdbildirim desteği içinlibsystemdile linklenir;libsystemdde tekrarliblzmaile linklenir- Bu ortamda
sshd,liblzmaya geçişli bağımlı olur
- Bu ortamda
sshdçalıştırıldığında dinamik yükleyicilibsystemdveliblzmayı yükler; arka kapı kurulmuşsaliblzmayüklenirken kötücül kod çalışır- Arka kapı, ifunc resolver’ın kötücül
_get_cpuidsembolünü çağırmasını sağlar ve henüz salt okunur olmayan GOT üzerinde oynayarakRSA_public_decryptadresini kötücül fonksiyonla değiştirir - Securelist’in ayrıntılı analizi ile saldırı vektörü ve azaltma önlemlerini özetleyen araştırma yazısı referans olarak incelenebilir
Güvenilir kaynaklar ve NixOS’un bootstrap kısıtı
- Birçok dağıtım
xzyi Git forge’daki özgün kaynak yerine bakımcı tarafından sağlanan tarball ile derlediği için bu saldırı etkili olabildi - Tarball iş akışının tarihsel ve pratik nedenleri vardır
gitten daha eski olan ilk Linux dağıtımlarının yöntemidir- Release anındaki kaynak durumunu kendi içinde eksiksiz bir arşiv olarak korur
- manpage ve configure betiği gibi ara çıktıları dahil ederek derleme yükünü azaltabilir
- Sıkıştırma sayesinde depolama verimliliği sağlar
- Güvenlik açısından, teknik olarak mümkün olduğunda en güvenilir tarafın doğruladığı kaynaktan derleme yapılmalıdır
- GitHub’da geliştirilen bir proje için GitHub’ın her release için otomatik ürettiği arşivler kullanılabilir
- Aynı mantık Codeberg, SourceHut, GitLab gibi güvenilir üçüncü taraf platformlara da uygulanabilir
- NixOS fonksiyonel paket yönetimi modeli kullanır; paketler derleme tariflerini Nix ifadeleriyle tanımlar
- NixOS bakımcılarında mümkün olduğunda
fetchFromGitHubile GitHub’ın otomatik ürettiği kaynak arşivlerini kullanma kültürü vardır; ancakxzpaketifetchurlile elle yüklenmiş bakımcı tarball’ını alıyordu - Bunun nedeni,
xzninnixpkgsbootstrap aşamasına dahil olmasıdır- bootstrap, küçük bir seed binary kümesinden
nixpkgspaketlerinin tamamını yeniden derleyebilmeyi sağlayan süreçtir stdenv, diğer paketlerin kullandığı temel derleme ortamıdırstdenvçalışma zamanındaxzye bağımlıdır;coreutilsgibi paketler de.tar.xzkaynak arşivlerini açmak içinxzye ihtiyaç duyar
- bootstrap, küçük bir seed binary kümesinden
- GitHub kaynaklarından
xzderlemek için configure betiğini oluşturacakautoconfgerekir; ancakautoconfdaxzye bağımlıdır- Bakımcı tarafından sağlanan tarball’da configure betiği zaten oluşturulmuş olduğundan bu bağımlılık döngüsü kırılabilir
- Bu nedenle
nixpkgsgrafiğindexznin derlendiği noktada GitHub kaynak arşivini kullanmak zordu ve bakımcı tarball’ına güvenmek gerekiyordu
Kaynak karşılaştırmasındansa çıktı yakınsamasını karşılaştırmak
- Bakımcı tarball’ı ile GitHub kaynak tarball’ının aynı olup olmadığını karşılaştırmak doğal görünebilir; ancak pratikte pek iyi işlemez
- Daniel Stenberg, release tarball’ının kaynaktan farklı olmasının bir özellik olduğunu açıklıyor
- manpage ve configure betiği gibi ara çıktılar tarball’a dahil edilebilir
- Dağıtımların
autoconfbağımlılığından kaçınmak istediği durumlarda özellikle kullanışlıdır
- Tedarik zinciri güvenliği açısından bu esneklik, bakımcının dürüst olduğuna güvenme yüküne dönüşür
- Tekrarlanabilir derleme, aynı koşullarda iki kez derleme yapıldığında bit düzeyinde aynı çıktıların üretilmesi özelliğidir
- reproducible-builds grubu mümkün olduğunca çok paketi tekrarlanabilir hale getirmeyi hedefler; Reproducible Builds: Increasing the Integrity of Software Supply Chains bunu ikili çıktı dağıtımına duyulan güveni artıran bir özellik olarak ele alır
- Tarball üretiminin kendisini tekrarlanabilir hale getirme yaklaşımını PostgreSQL projesi benimsedi
- Kullanıcılar, bakımcı tarball’ının özgün kaynaktan dürüstçe üretilip üretilmediğini bağımsız olarak doğrulayabilir
- Ancak bunu upstream proje bakımcısının uygulaması gerektiğinden FOSS topluluğunda benimsenme hızı yavaş olabilir
NixOS’ta önerilen tespit prosedürü
xzbit düzeyinde tekrarlanabilirse ve bakımcı tarball’ı derleme sürecini etkileyen değişiklikler içermiyorsa, GitHub tarball derlemesi ile bakımcı tarball derlemesi aynı çıktıları üretmelidir- Önerilen yöntem,
xzyi bootstrap sonrasında bir kez daha derlemek; bu kezfetchFromGitHubile GitHub kaynak arşivini kullanmak ve mevcut bootstrap aşamasındakixzçıktısıyla karşılaştırmaktır - Uygulama örneği,
pkgs/tools/compression/xzaltınaafter-bootstrap.nixkoyupxz5.6.1 sürümünü GitHub kaynaklarından derler- Bakımcı tarball’ında configure betiği zaten vardır; GitHub kaynağından derlemede ise
autoconf,libtool,automakevb. kullanılarak./autogen.shçalıştırılmalıdır
- Bakımcı tarball’ında configure betiği zaten vardır; GitHub kaynağından derlemede ise
- Karşılaştırma adımı olarak, derlemenin sonunda
liblzma.soyu karşılaştırancompareArtifactseklenir- Örnekte yalnızca arka kapının değiştirdiği dosya olan
liblzma.sokarşılaştırıldı; ancak bu, tüm ikili ve kütüphane çıktıları için genelleştirilebilir
- Örnekte yalnızca arka kapının değiştirdiği dosya olan
- Normal master revizyonunda
xz-after-bootstrapderlemesi başarılı oldu ve iki çıktı aynıydı - Arka kapı içeren
c53bbe3revizyonunda başlangıçta aynı görünüyordu- NixOS’ta arka kapı etkinleşmemişti; bunun nedenlerinden biri, kurulum betiğinin
RPM_ARCHdeğişken ayarını kontrol etmesiydi env.RPM_ARCH = true;ayarlanarak koşul etkinleştirildiğindeliblzma.soikilisindeki fark ortaya çıktı
- NixOS’ta arka kapı etkinleşmemişti; bunun nedenlerinden biri, kurulum betiğinin
- İki
liblzma.sodosyası kaydedilip karşılaştırıldığında, arka kapı içeren çıktı 258 KB, bootstrap sonrası GitHub kaynak derlemesinin çıktısı 210 KB idi; arada yaklaşık 48 KB fark vardı nmile semboller karşılaştırıldığında_cpuid,_get_cpuid,__tls_get_addr@GLIBC_2.3eklenmişti;_get_cpuid, birçokxzarka kapısı teknik raporunda belgelenmiş bir semboldür
Uygulama yolları ve sınırlamalar
- Önerilen koruma, bootstrap aşamasında derlenen ve güvenilir kaynak arşivi kullanmayan tüm paketlere uygulanacak bir mekanizmadır
*-after-bootstrappaketleri channel blocker’a eklenirse, derleme başarısızlığı bakımcı müdahalesi gerektiren büyük bir alarm haline getirilebilirxzvakasına yönelik kavram kanıtı olaraknixpkgsdeposunda bir pull request açıldı- Bu yöntem, hedef paketin bit düzeyinde tekrarlanabilir olduğu varsayımını gerektirir
- 2017’den 2023’e kadar
nixpkgs-unstablerevizyonlarından 17’si örneklenerekstdenviçindeki non-fixed-output derivation’larnix-build --checkile yeniden derlendi - Tüm revizyonlarda
xzbit düzeyinde tekrarlanabilirdi - 17 revizyonun 12’sinde derlenebilen ama tekrarlanamayan 1-2 paket vardı; örneğin
gcc2017-2021 arasında,bashise 2019’a kadar tutarlı biçimde tekrarlanamıyordu
- 2017’den 2023’e kadar
- Bu yöntem tüm
stdenvpaketlerine uygulanamaz; ancak uzun vadede tekrarlanabilirliği iyi olan paketlerde seçici olarak etkinleştirilebilir - Ken Thompson’ın trusting trust sorunu, bu yaklaşımın teorik sınırı olarak kalır
- Bootstrap aşamasındaki güvenilmeyen
xzninxz-after-bootstrapderlemesini dolaylı olarak kirletip çıktıları aynıymış gibi gösteremeyeceği varsayımı gerekir - Böyle bir saldırı çok karmaşık olabilir; ancak yöntemin kendisi bu varsayıma dayanır
- Bootstrap aşamasındaki güvenilmeyen
- Bu tespit yöntemi yalnızca tarball değişikliği nihai çıktıyı etkilediğinde algılama yapar
- NixOS çalıştırılabilir dosyalarında arka kapı bulunmadığı için, koşul ayrıca etkinleştirilmemiş olsaydı bu vakadaki arka kapı keşfedilemeyebilirdi
1 yorum
Hacker News yorumları
NixOS ve tekrarlanabilir derlemelerin xz arka kapısını tespit edemediğini belirtmek gerek. Aslında NixOS da kötü amaçlı xz derlemesini kullanıcılarına dağıttı; yalnızca kötü amaçlı yazılım NixOS’u hedeflemediği için çalışmadı.
Bir NixOS geliştiricisi de “arka kapı ortaya çıktığında, xz’nin kötü amaçlı sürümünün kullanıcılarımıza dağıtılmış olmasına şaşırdım” demişti. Her zamanki gibi teori ile gerçeklik farklı; xz’yi mümkün kılan şey teknik bir zaaftan çok gerçek dünyadaki insan zafiyetiydi. Topluluk, bu tür sorunların her zaman daha iyi yazılımla yamalanamayacağını kabul etmekte pek iyi değil.
Tüm süreçleri sınırlı yetkilerle çalıştırıp, iş için gerekli dizinler dışında
~/dizinine bile erişemeyecek hâle getirebilirsek, örneğin kötü amaçlı birpippaketinin SSH anahtarlarını çalmasını engelleyebiliriz. Yine de xz arka kapısının NixOS’ta çalışmamasının nedeninin NixOS’un alışılmadık FHS dışı dosya sistemi yapısı olduğunu düşünüyorum.Günümüzde fiilî gerçeklik, nesnel gerçekliğe dair kişinin duyguları ya da değerleriyle uyuşmadığında sık sık küçümseniyor. Kişisel değerlerim var, ama fiilî gerçekliğin ona dair hislerimden daha az önemli olduğunu düşünmüyorum. Söylemeyi sevdiğim gibi: teori ile pratik arasındaki fark, teoride ikisinin aynı olması ama pratikte öyle olmamasıdır. NixOS’un tekrarlanabilir derlemelerinin xz saldırısını yakalayabilecek olup yakalayamamış olması gerçeğinin, ileride bu derlemeleri analiz ederek başka saldırıları daha erken bulacak gelişmelere yol açmasını umarım.
Yazarın, bu olayın tesadüfen gerçekleştiği biçime fazla dar bir açıdan baktığı hissine kapıldım. Jia Tan olayı tek örnekten ibaret; bu nedenle yalnızca o yöntemin mümkün olduğunu düşünmek dar görüşlülük olur.
Burada önerilen savunmanın işe yaramayacağı pek çok senaryo rahatlıkla hayal edilebilir. Bir Nix kullanıcısı olarak bile NixOS’un bunu yakalamış olma ihtimalinin düşük olduğunu düşünüyorum. Nitekim gerçekten de yakalayamadı. Az önce bir dahaki sefer farklı gerçekleşebilir dedim, ama kanıt olmadan Nix’e güvenmek de aptallık olur.
Burada NixOS pek ilgili değil. Çünkü xz arka kapısı özellikle Red Hat ve Debian’ı hedefliyordu.
Aynı mantıkla xz arka kapısının Windows’u etkilemediğini söylemek de benzer ölçüde ilgili olurdu. İronik biçimde bu arka kapıyı nihayetinde bir Microsoft çalışanı keşfetti; bu nokta sık sık gözden kaçırılıyor.
Yazıda, dağıtımların geleneksel kurulum tarball’ları yerine sürüm kontrol sisteminden, örneğin doğrudan Github’dan kaynak kod alması gerektiği söyleniyor.
Ama bunun neyi çözdüğünü pek anlamıyorum. Kötü niyetli bir bakımcı ikili blob’u doğrudan kaynak kod deposuna ekleyemez mi? Yazar, Github’ı kodu doğruluyormuş gibi güvenilir görüyor; elbette Github böyle bir doğrulama yapmıyor.
Doğrulanmış tekrarlanabilir derlemeler, xz utils ihlali ve SolarWinds Orion tahrifatı gibi vakaları önlemeye yardımcı olabilirdi; bu da kesinlikle uğraşmaya değer.
Github release’inden bir ikili indirip çalıştırıyorsanız bakımcıya tamamen güvenmekten başka seçeneğiniz yoktur. Nix bunu yalnızca kapalı kaynak paketlerde yapıyor.
Argüman, XZ bakımcısının kötü amaçlı kodu Git’e işlenmemiş bir tarball’ın içine saklamış olmasına dayanıyor.
Yazar, Nix’in Git’ten tarball üretip bunu ikili derlemeye koyacak şekilde ayarlanabileceğini gösteriyor. Ama bunun neden Nix ya da NixOS gerektiren bir özellik olduğunu anlamıyorum. RPM veya Deb’e girenler dâhil herhangi bir derleme sistemi, ara adım olarak tarball üretecek şekilde ayarlanabilir. Aslında Debian uzun zamandır tekrarlanabilir derlemeleri önemli bir hedef olarak ele alıyor. https://wiki.debian.org/ReproducibleBuilds
Birincisi, NixOS derleme sürecinde xz bootstrap’in çok erken aşamasında gerektiği için xz’nin tam kaynak derlemesini yapmak mümkün değildi. İkincisi, bootstrap’in erken aşamasında gereken nixpkgs bağımlılıklarının ele geçirilip geçirilmediğini otomatik olarak tespit etmek için nixpkgs’te yapılacak düzenlemeler öneriyor. Elbette başka ekosistemler de tam kaynak derlemeyi deneyip uyuşmazlıkları bulabilir. Yazının özü, mevcut nixpkgs’in bunu yapamaması.
NixOS’un engelleyebileceği örneklere odaklanmak istiyorsanız CrowdStrike olayına bakmalısınız. Bugünün yapılandırması çalışmazsa dünkü yapılandırmayla önyükleme yapabilmek bile zararın büyük bölümünü hafifletirdi.
Güvendiğiniz bir framework kullanırsanız, o framework saldırıya uğrayana kadar güvendesinizdir. xz arka kapısı keşfedilmiş olabilir, ancak Nix ekosisteminde çalışacak şekilde tasarlanmış değildi.
Bir gün Nix’in çekirdek geliştiricilerinden biri casus olursa ya da benzer bir durum yaşanırsa, Nix ekosistemini hedefleyen saldırılar da ortaya çıkacaktır. Nix doğası gereği güvenlidir gibi bir yanıt verilmemesini isterim. 1-2 yıl içinde Nix başarılı şekilde saldırıya uğrarsa, gidip yanıldığınızı kabul ettirmek isteyecek kadar.
Daha güçlü iddia şudur: “Nix’e saldırmak geleneksel derleme sistemlerine saldırmaktan daha zor ve daha maliyetlidir.” Bu yüzden Nix’e ucuza saldırmanın bir yolunu bulursanız o zaman gelin. O zamana kadar, teknik düzeyde Nix’in alternatif sistemlere göre saldırılması daha zor olduğu sözü en azından makul, hatta pratikte de oldukça yüksek olasılıklıdır.
NixOS biraz daha ileri gitse de, diğer dağıtımların çoğu da her şeyi kaynaktan derler, kullanılan kaynağın değiştirilmediğini kriptografik olarak doğrular ve paketler arasında sürüm belirtilmiş bağımlılıklar kullanır. Debian’da da yeniden üretilebilir derlemeler var.
Sorun, derleme sisteminin kaynaktan derlemeden önce önceden derlenmiş nesne dosyalarını kaldırmamış olmasıydı. Bunu düzeltseniz bile kimse kaynak kodu incelemezse istediğiniz kadar arka kapı ekleyebilirsiniz; NixOS da başka bir dağıtım da bunu engelleyemez.
Harika bir teknik analiz, ama başlık yanlış ve yanıltıcı. “Teknik olarak doğru” denebilse bile, en iyi ihtimalle arka kapının yerleştirildiği anlamına daha yakın.
Union filesystem katmanlarının ötesine geçen derleme yöneticisi araçlarına ihtiyaç olduğunu iyi gösteriyor. Örneğin testlerin derleme çıktısını kirletmesini izlemeli ve bunu engellemeliyiz. Derleme sürecinde dosyaların dosyaları nasıl etkilediğini gösteren bir nedensel izleme grafiği oluşturmak, bu grafiği açıkça üretmek ve ardından bunu zorunlu kılmak ya da önceki izleme grafiğiyle farklarını raporlamak gibi bir yönteme ihtiyaç var.
Doğru. Arka kapıyı gizlemek kesinlikle daha zor olurdu. Ama imkânsız olmaktan çok uzak.
İsterseniz kaynak kodun içine her zaman bir arka kapı gizleyebilirsiniz. Sadece bunu makul görünen bir hata gibi göstermeye daha fazla emek harcanır ve tespit edilme olasılığı da artar.