bugün rss feedime düştü
yeni bir kernel exploiti detaylar için:
kernelden anladığımdan değil uzun araştırmalar yaptım
ama daha yeni (dün) kaynak yok pek
public exploit yok - bu ayın sonuna kadar da gelmiycekmiş
eğer normal bir insan varlığı iseniz (ya da cc'ci bir skid)
gerisini okumaya gerek yok burda bırakabilrsiniz
haberiniz olsun diye dedim sadece
okumaya devam ediceksiniz ha, o halde başlıyorum hazır olun
yazarın da söylediği gibi exploit etmesi biraz "challenging"
"sebep?" derseniz postu okursanız da göreceğiniz
gibi RCU'lara dayanıyor, eleman "use-after-free-by-RCU"
olarak adlandırmış
bilmeyenler için, cpu birden fazla threadden okuduğundan
paylaşılan sturctların birinin objeyi doğrudan update
etmesi mümkün değil birşeyin threadler arası sekronizasyon
sağlaması lazım bunu RCU (read copy update) gerçekleştiriyor
sorun şu RCU'ların debug etmesi imkansız zamanlama
tabanlı full diğer uaf ctf oyuncakları
değil yani
hadi az daha detay girelim
şimdi siz mmap ile anlık işlemin VMA'sına bir dosya
fln maplediğiniz zaman kernel vm_area_struct diye
bir arkadaş oluşturuyor (yazarında açıkladığı gibi)
eskiden bu VMAlar red-black treeler ile
yönetiliyordu (adlandırmayı ben yapmadım amk)
ama işte page fault gibi memory ile alakalı sorunlar
işin içine girince kernelin hızlıca bu tree'yi okuması lazım
o yüzden 6.1de mapple treelere geçmişler
(linusa sorun adlandırma valla benim değil), sırf
bu amaç için optimize edilmiş bir yapı
asıl bug bunla ilgili, maple treeler, red-blackler gibi
kernelde VMAları (virtual memory area) yönetmek
için bir yapı, ancak onlardan farklı olarak
bellek yönetim subsystemi tarafından
binary search tree olarak kullanılıyor
bu treedeki her node bir VMA ve bilgilerini içeriyor
(başlangıç ve bitiş adresleri vs.)
bu treeye bir thread yazarken diğer threadin
teki de yazmasın diye MM write lock
kullanılıyor (memory management'ın MM'i)
okumak içinse iki seçenek var, ya MM read lock
(yazmayı kilitliyor) ya da mapple treeler
RCU-safe olduğundan (RCU ile beraber sorunsuz
kullanıldığından) direk RCU call'ları ile
hiçbir reader'ın eski veriye erişmediğinden emin
olarak gerçekleştirilebilir
çoğu durumda readerlar ilk seçeneği kullanıyor,
ikincisi sadece ikincisi bir iki performans gerektiren
senaryo dışı kullanılmıyor (bu seçenekte reader/writer beraber
çalışabiliyor o yüzden performans için tercih ediliyor)
ama bizim dikkat ediceğimiz yer şu:
eğer bir VMA'nın MAP_GROWSDOWN
flag'i varsa o zaman VMA'daki işlem stacki
otamatik olarak genişletiliyor, ve bu yapılırken
write lock kullanılmıyor
iki VMA arasında stack guarddan kaynaklı bir
boşluk söz konusu, şöyle göründüğünü söyleyebiliriz:
diyelim stack'in MAP_GROWSDOWN'ı var (bu flagi setlenmiş yani)
ama VMA'nın yok, o halde sorun yok
ancak ikisinin de MAP_GROWSDOWN'u varsa
stack guard zorlanmıyor, bu yüzden eğer bir stack genişlemesi aradaki boşluğu
yerse, VMAdaki herhangi bir alanın'ın burayı (gapi) işaret
etmemesi lazım, bunun yapmanın yolu, node'un değerlerini değiştirmek
ama eleman yazmış ki:
neden derseniz RCU'nun mantığından kaynaklı, eğer dümdüz
nodeun üzerine yazarsanız o sırada node'u okuyan bir thread
sizin yazdığınızı göremez, RCU gereği anlık objenin bir kopyasını
oluşturmanız lazım, ardından bunu doğru şekilde linklemeniz
son olarak da hiç kimsenin okuyup/yazmadığından
emin olduktan sonra eski nodeu silemeniz lazım
bu yüzden yapılacak şey bu nodeu silmek ve yeni bir node oluşturmak,
eski node'u silmek için bir RCU callback'i kullanılıyor
işte sonuca ve soruna geldik, eğer bu callback çağrılmadan
önce bir thread bu VMA'nın pointerını almış ise
callback bu pointerı freeledikten sonra kullanırsa bizim bu
bug ortaya çıkıyor (use-after-free)
bu threadler objenin freelendiğini neden bilmiyor derseniz
obje okunurken çoğunlukla MM read lock yöntemi kullanılıyor, önceden
bahsettiğim gibi bu sadece yazmayı önlüyor
işte bu kadar
eğer bir hatam varsa düzeltmekten çekinmeyin kernel işlerine
o kadar aşina değilim
her neyse buraya kadar okuyan ve açığı anlamaya çalışan tüm
kernel hekırlarımıza teşekkürler
iyi akşamlar!
yeni bir kernel exploiti detaylar için:
kernelden anladığımdan değil uzun araştırmalar yaptım
ama daha yeni (dün) kaynak yok pek
public exploit yok - bu ayın sonuna kadar da gelmiycekmiş
eğer normal bir insan varlığı iseniz (ya da cc'ci bir skid)
gerisini okumaya gerek yok burda bırakabilrsiniz
haberiniz olsun diye dedim sadece
okumaya devam ediceksiniz ha, o halde başlıyorum hazır olun
yazarın da söylediği gibi exploit etmesi biraz "challenging"
"sebep?" derseniz postu okursanız da göreceğiniz
gibi RCU'lara dayanıyor, eleman "use-after-free-by-RCU"
olarak adlandırmış
bilmeyenler için, cpu birden fazla threadden okuduğundan
paylaşılan sturctların birinin objeyi doğrudan update
etmesi mümkün değil birşeyin threadler arası sekronizasyon
sağlaması lazım bunu RCU (read copy update) gerçekleştiriyor
sorun şu RCU'ların debug etmesi imkansız zamanlama
tabanlı full diğer uaf ctf oyuncakları
değil yani
hadi az daha detay girelim
şimdi siz mmap ile anlık işlemin VMA'sına bir dosya
fln maplediğiniz zaman kernel vm_area_struct diye
bir arkadaş oluşturuyor (yazarında açıkladığı gibi)
eskiden bu VMAlar red-black treeler ile
yönetiliyordu (adlandırmayı ben yapmadım amk)
ama işte page fault gibi memory ile alakalı sorunlar
işin içine girince kernelin hızlıca bu tree'yi okuması lazım
o yüzden 6.1de mapple treelere geçmişler
(linusa sorun adlandırma valla benim değil), sırf
bu amaç için optimize edilmiş bir yapı
asıl bug bunla ilgili, maple treeler, red-blackler gibi
kernelde VMAları (virtual memory area) yönetmek
için bir yapı, ancak onlardan farklı olarak
bellek yönetim subsystemi tarafından
binary search tree olarak kullanılıyor
bu treedeki her node bir VMA ve bilgilerini içeriyor
(başlangıç ve bitiş adresleri vs.)
bu treeye bir thread yazarken diğer threadin
teki de yazmasın diye MM write lock
kullanılıyor (memory management'ın MM'i)
okumak içinse iki seçenek var, ya MM read lock
(yazmayı kilitliyor) ya da mapple treeler
RCU-safe olduğundan (RCU ile beraber sorunsuz
kullanıldığından) direk RCU call'ları ile
hiçbir reader'ın eski veriye erişmediğinden emin
olarak gerçekleştirilebilir
çoğu durumda readerlar ilk seçeneği kullanıyor,
ikincisi sadece ikincisi bir iki performans gerektiren
senaryo dışı kullanılmıyor (bu seçenekte reader/writer beraber
çalışabiliyor o yüzden performans için tercih ediliyor)
ama bizim dikkat ediceğimiz yer şu:
eğer bir VMA'nın MAP_GROWSDOWN
flag'i varsa o zaman VMA'daki işlem stacki
otamatik olarak genişletiliyor, ve bu yapılırken
write lock kullanılmıyor
iki VMA arasında stack guarddan kaynaklı bir
boşluk söz konusu, şöyle göründüğünü söyleyebiliriz:
Kod:
stack VMA
(boşluk/gap)
VMA
diyelim stack'in MAP_GROWSDOWN'ı var (bu flagi setlenmiş yani)
ama VMA'nın yok, o halde sorun yok
ancak ikisinin de MAP_GROWSDOWN'u varsa
stack guard zorlanmıyor, bu yüzden eğer bir stack genişlemesi aradaki boşluğu
yerse, VMAdaki herhangi bir alanın'ın burayı (gapi) işaret
etmemesi lazım, bunun yapmanın yolu, node'un değerlerini değiştirmek
ama eleman yazmış ki:
mapple tree RCU-safe olduğundan zaten var olan node'un üzerine yazmak
mümkün değil
neden derseniz RCU'nun mantığından kaynaklı, eğer dümdüz
nodeun üzerine yazarsanız o sırada node'u okuyan bir thread
sizin yazdığınızı göremez, RCU gereği anlık objenin bir kopyasını
oluşturmanız lazım, ardından bunu doğru şekilde linklemeniz
son olarak da hiç kimsenin okuyup/yazmadığından
emin olduktan sonra eski nodeu silemeniz lazım
bu yüzden yapılacak şey bu nodeu silmek ve yeni bir node oluşturmak,
eski node'u silmek için bir RCU callback'i kullanılıyor
işte sonuca ve soruna geldik, eğer bu callback çağrılmadan
önce bir thread bu VMA'nın pointerını almış ise
callback bu pointerı freeledikten sonra kullanırsa bizim bu
bug ortaya çıkıyor (use-after-free)
bu threadler objenin freelendiğini neden bilmiyor derseniz
obje okunurken çoğunlukla MM read lock yöntemi kullanılıyor, önceden
bahsettiğim gibi bu sadece yazmayı önlüyor
işte bu kadar
eğer bir hatam varsa düzeltmekten çekinmeyin kernel işlerine
o kadar aşina değilim
her neyse buraya kadar okuyan ve açığı anlamaya çalışan tüm
kernel hekırlarımıza teşekkürler
iyi akşamlar!