TL; DR
Kaporta güvenlik açığı tamamen
- Bash-2.05b dalında: 2.05b.10 ve üzeri (yama 10 dahil)
- Bash-3.0 dalında: 3.0.19 ve üzeri (19 eki dahil)
- Bash-3.1 şubesinde: 3.1.20 ve üzeri (yama 20 dahil)
- Bash-3.2 şubesinde: 3.2.54 ve üzeri (yama 54 dahil)
- Bash-4.0 dalında: 4.0.41 ve üzeri (yama 41 dahil)
- Bash-4.1 şubesinde: 4.1.14 ve üzeri (14 numaralı yama dahil)
- Bash-4.2 şubesinde: 4.2.50 ve üzeri (yama 50 dahil)
- Bash-4.3 dalında: 4.3.27 ve üzeri (yama 27 dahil)
Bash'iniz eski bir sürümü gösteriyorsa, işletim sistemi satıcınız hala kendi başlarına yamalı olabilir, bu nedenle kontrol etmeniz en iyisidir.
Eğer:
env xx='() { echo vulnerable; }' bash -c xx
"savunmasız" gösteriyor, hala savunmasızsın. İlgili olan tek test budur (bash ayrıştırıcısının hala herhangi bir ortam değişkeninde koda maruz kaldığı durumlarda ).
Ayrıntılar.
Hata 5 tanıtılan ithal / ihraç fonksiyonun ilk uygulamasında olduğu th Brian Fox tarafından Ağustos 1989 ve ilk güvenlik öncesinde, daha sonra bash böyle yaygın kullanımda değildi bir anda yaklaşık bir ay bash-1.03 yılında piyasaya endişe ve HTTP ve web ya da Linux bile var olsaydı.
Dan 1.05 yılında ChangeLog :
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel)
* readline.c: rl_insert (). Optimized for large amounts
of typeahead. Insert all insertable characters at once.
* I update this too irregularly.
Released 1.03.
[...]
Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel)
* variables.c: make_var_array (), initialize_shell_variables ()
Added exporting of functions.
Bu süre zarfında gnu.bash.bug ve comp.unix.questions'daki bazı tartışmalar da özellikten bahseder.
Oraya nasıl gittiğini anlamak kolaydır.
bash env değişkenindeki fonksiyonları ihraç eder
foo=() {
code
}
İthalatta ise, yapması gereken tek şey =
bir boşlukla değiştirildiği ... ancak bunu kör bir şekilde yorumlamaması gerektiği şeklinde yorumlamak.
Ayrıca bash
(Bourne kabuğunun aksine), skaler değişkenlerin ve fonksiyonların farklı bir ad alanına sahip olması da bozuldu . Aslında eğer varsa
foo() { echo bar; }; export -f foo
export foo=bar
bash
her ikisini de mutlu bir şekilde ortaya koyacaktır (evet, aynı değişken ismine sahip girişler) ancak birçok araç (birçok mermi dahil) onları yaymayacaktır.
Biri ayrıca, BASH_
bash'ın sadece bash'dan bash ile ilgili olduğu için bunun için bir ad alanı öneki kullanması gerektiğini savunur . benzer bir özellik için önek rc
kullanır fn_
.
Uygulamanın daha iyi bir yolu, dışa aktarılan tüm değişkenlerin tanımını aşağıdaki gibi bir değişkene koymak olabilirdi:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Bunun hala sterilize edilmesi gerekir, ama en azından bundan daha fazla yararlanılamaz $BASH_ENV
veya $SHELLOPTS
...
bash
Buradaki işlev tanımından başka bir şeyi yorumlamasını engelleyen bir düzeltme eki var ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ) ve bu olan Çeşitli Linux dağıtımlarındaki tüm güvenlik güncellemelerinde uygulanmıştır.
Ancak, bash hala oradaki kodu yorumlar ve tercümandaki herhangi bir hatadan yararlanılabilir. Etkisi çok daha küçük olmasına rağmen, böyle bir hata (CVE-2014-7169) zaten bulunmuştu . Yani yakında başka bir yama olacak.
Bash'ın herhangi bir değişkende kodu yorumlamasını engelleyen bir sertleştirme düzeltmesi yapılıncaya kadar ( BASH_FUNCDEFS
yukarıdaki yaklaşımı kullanmak gibi), bash ayrıştırıcısındaki bir hataya karşı savunmasız olup olmadığımızdan emin olamayız. Ve er ya da geç serbest bırakılan böyle bir sertleşme düzeltmesi olacağına inanıyorum.
Düzenle 2014-09-28
Ayrıştırıcıda iki ek hata bulundu (CVE-2014-718 {6,7}) (çoğu mermilerin köşe davaları için ayrıştırıcılarında böcek olması gerektiğine, bu ayrıştırıcının olmasaydı endişelenmeyeceğine dikkat edin) güvenilmeyen verilere maruz kalmadı).
Her 3 hata 7169, 7186 ve 7187 takip eden yamalar için sabitlenirken, Red Hat sertleştirme düzeltmesi için bastırdı. Yamalarında, davranışları değiştirdiler; böylece işlevler, BASH_FUNC_myfunc()
Chet'in tasarım kararını az çok önleyen denilen değişkenlerde dışa aktarıldı.
Chet daha sonra resmi düzeltme olarak bash yaması olarak bu düzeltmeyi yayınladı .
Bu sertleştirme yaması ya da değişkenleri çoğu Linux dağıtımı için mevcut ve sonunda onu Apple OS / X'e getirdi.
Bu, artık herhangi bir env için endişeyi gideren , daha sonra Michał Zalewski (CVE-2014-6278 tarafından neredeyse açıklanacak olan ) ayrıştırıcıdaki (CVE-2014-627 {7,8}) diğer iki güvenlik açığı da dahil olmak üzere, çözümleyici tarafından bu vektör üzerinden istismar edilebilir; CVE-2014-6271 kadar kötü) neyse ki çoğu insan sertleştirme yamasını kurmak için zaman buldu.
Ayrıştırıcıdaki hatalar da düzeltilecektir, ancak artık ayrıştırıcının artık güvenilmeyen girdilere bu kadar kolay maruz kalmaması nedeniyle artık bir sorun olmadı.
Güvenlik açığı düzeltilmiş olsa da, bu alanda bazı değişiklikler göreceğimizi unutmayın. CVE-2014-6271 için yapılan ilk düzeltme, islevleri isimleri ile .
ya :
da /
isimleriyle almalarını engellemesi için geriye dönük uyumsuzluğu bozdu . Bunlar yine de tutarsız bir davranışa yol açan bash tarafından açıklanabilir. Adında .
ve ismindeki işlevler :
yaygın olarak kullanıldığı için, en azından bir ortamdan gelenleri kabul etmek bir düzeltme eki oluşturacaktır.
Neden daha önce bulunmadı?
Bu da merak ettiğim bir şey. Birkaç açıklama yapabilirim.
Birincisi, eğer bir güvenlik araştırmacısı (ve ben profesyonel bir güvenlik araştırmacısı değilim), özellikle bash'taki güvenlik açıklarını araştırmış olsaydı, muhtemelen bulabileceklerini düşünüyorum.
Örneğin, bir güvenlik araştırmacısı olsaydım, yaklaşımlarım şunlar olabilirdi:
- Nereden
bash
girdi alacağına ve bununla ne yaptığına bak . Ve çevre çok açık.
bash
Tercümanın hangi yerlere çağrıldığı ve hangi verilerle ilgili olduğuna bakın. Yine, öne çıkacaktı.
- Dışa aktarılan işlevlerin içe aktarılması
bash
, setuid / setgid olduğunda devre dışı bırakılan özelliklerden biridir;
Şimdi, kimsenin bash
(tercümanı) bir tehdit olarak görmeyi düşünmediğinden veya tehdidin bu şekilde olabileceğinden şüpheleniyorum .
bash
Tercüman güvenilmeyen giriş işlemek için tasarlanmamıştır.
Kabuk komut dosyaları (tercüman değil) genellikle güvenlik açısından yakından bakılır. Kabuk sözdizimi çok garip ve güvenilir komut dosyaları (örneğin, beni veya split + glob operatöründen bahseden başkalarını veya neden değişkenler alıntı yapmalısınız? güvenilmeyen veri.
Bu nedenle çoğu zaman CGI kabuk komutları yazmamanız gerektiğini ya da setuid komut dosyalarının çoğu Unices'de devre dışı bırakıldığını duyarsınız. Veya dosyaları dünyaca yazılabilir dizinlerde işlerken çok dikkatli olmanız gerekir ( örneğin CVE-2011-0441 ).
Odak noktası tercüman değil, kabuk komut dosyasıdır.
Bir kabuk yorumlayıcısını güvenilmeyen verilere (yorumlamak için yabancı verileri kabuk kod olarak beslemek) kullanarak eval
veya .
kullanıcı tarafından sağlanan dosyalar üzerinde arayarak maruz bırakabilirsiniz , ancak bash
bu durumda onu kullanmak için bir güvenlik açığına ihtiyacınız yoktur . Bir kabuğun yorumlayabilmesi için doğrulanmamış verilerden geçerseniz, yorumlayacağı açıktır.
Böylece kabuk güvenilir bağlamlarda denir. Sabit veriyi yorumlaması ve daha sık (çoğu zaman güvenilir betikler yazması zor olduğu için) sabit verileri işlemesi için verilir.
Örneğin, bir web bağlamında, bir kabuk şöyle bir şeyle çağrılabilir:
popen("sendmail -oi -t", "w");
Bunda yanlış olan ne olabilir? Yanlış bir şey öngörülürse, bu, o kabuk komut satırının kendisinin nasıl ayrıştırıldığı ya da o kabuğa ne kadar fazla veri beslendiğinin değil, o gönderene gönderilen veri ile ilgilidir. Bu kabuğa iletilen ortam değişkenlerini göz önünde bulundurmak için hiçbir neden yok. Ve yaparsanız, hepsinin adı "HTTP_" ile başlayan ya da CGI env'nin kabuk ya da sendmail'in yapabileceği hiçbir işle aynı olmadığı ya SERVER_PROTOCOL
da QUERYSTRING
hiç olmadığı gibi env değişkenlerinin olduğunun farkındasınız .
Ayrıcalık / setgid veya sudo aracılığıyla çalıştırırken olduğu gibi ayrıcalık yükselmesi bağlamında, ortam genel olarak kabul edilir ve geçmişte yine kabuğun kendisine karşı değil, ayrıcalıkları yükselten şeylere karşı birçok güvenlik açığı vardır sudo
(örneğin CVE'ye bakın). -2011-3628 ).
Örneğin, bash
setuid veya setuid komutu tarafından çağrıldığında çevreye güvenmiyor ( mount
örneğin, yardımcıları çağıran birini düşünün ). Özellikle, verilen fonksiyonları dikkate almaz.
sudo
çevreyi temizlemek yapar: tüm beyaz listeye hariç varsayılan olarak ve eğer en az kara listelerinde de yer aldığı bilinen birkaç bir kabuk ya da başka (gibi etkileyecek şekilde yapılandırılmış PS4
, BASH_ENV
, SHELLOPTS
...). Ayrıca, içeriği ile başlayan çevre değişkenlerini de kara listeye alır ()
(bu nedenle CVE-2014-6271, üzerinden ayrıcalık yükselmesine izin vermez sudo
).
Fakat yine de, ortamın güvenilir olamayacağı bağlamlar için: herhangi bir isim ve değere sahip herhangi bir değişken, bu bağlamda kötü niyetli bir kullanıcı tarafından ayarlanabilir. Bu, web sunucuları / ssh veya ortamın kontrol edildiği CVE-2014-6271'den yararlanan tüm vektörler için geçerli değildir (en azından ortam değişkenlerinin adı kontrol edilir ...)
Bu gibi bir değişken engellemek için önemlidir echo="() { evil; }"
, fakat HTTP_FOO="() { evil; }"
, çünkü, HTTP_FOO
herhangi bir kabuk veya komut satırı ile bir komut olarak çağrılacak gitmiyor. Ve apache2 hiçbir zaman bir echo
veya BASH_ENV
değişken ayarlamayacak .
Oldukça açıktır bazı çevre değişkenleri siyah-listelenen onların dayalı bazı bağlamlarda olmalıdır isim , ama kimse onların dayalı siyah-listelenmiş olması gerektiğini düşündük içerik (hariç sudo
). Başka bir deyişle, hiç kimse keyfi env'nin kod enjeksiyonunda bir vektör olabileceğini düşünmedi.
Özellik eklendiğinde yapılan kapsamlı testlerin bunu yapıp yapamayacağı konusunda, olası olmadığını söyleyebilirim.
Özelliği test ederken işlevsellik testi yaparsınız. İşlevsellik iyi çalışıyor. İşlevi bir bash
çağrıda dışa aktarırsanız, başka bir başkasına aktarılır. Çok kapsamlı bir test, aynı adı taşıyan bir değişken ve işlev dışa aktarıldığında veya işlev dışa aktarıldığından farklı bir yerel ayarda içe aktarıldığında sorunları tespit etmiş olabilir.
Ancak güvenlik açığını tespit edebilmek için, yapmanız gereken bir işlevsellik testi değildir. Güvenlik yönü ana odak noktası olmak zorunda kalacaktı ve işlevselliği test etmeyecektiniz, ancak mekanizma ve nasıl kötüye kullanılabileceği.
Bu, geliştiricilerin (özellikle 1989'da) sık sık zihninin arkasında olduğu bir şey değildir ve bir kabuk geliştiricisinin, yazılımının ağın sömürülebilir olma ihtimalinin düşük olduğunu düşünmek için bahanesi olabilir.