Soru:
SUID neden kabuk betikleri için devre dışı bırakılırken ikili dosyalar için devre dışı bırakılmaz?
Cyker
2018-09-20 23:13:27 UTC
view on stackexchange narkive permalink

SUID fikrinin ayrıcalıklı olmayan bir kullanıcının bir programı ayrıcalıklı bir kullanıcı olarak çalıştırmasına izin vermek olduğunu anlasam da, SUID'nin genellikle bazı geçici çözümler olmadan bir kabuk komut dosyası üzerinde çalışmadığını fark ettim. Sorum şu ki, bir kabuk betiği ile bir ikili program arasındaki ikilemi gerçekten anlamıyorum. Görünüşe göre bir kabuk betiği ile ne yaparsanız yapın, bunu C ile de yapabilir ve bir ikili dosyada derleyebilirsiniz. SUID bir kabuk betiği için güvenli değilse, ikili dosyalar için de güvenli değildir. Öyleyse neden kabuk komut dosyalarının SUID'i kullanması ancak ikili dosyaların olmaması yasak olsun?

BTW.Bu "binfmt_misc" için nasıl çalışır?
@el.pescado Bkz. Https://manpages.debian.org/jessie/binfmt-support/update-binfmts.8.en.html (^ F setuid).
Iki yanıtlar:
Gilles 'SO- stop being evil'
2018-09-21 01:10:11 UTC
view on stackexchange narkive permalink

Shebang'ın ( #! ) tipik olarak uygulanma şekline özgü bir yarış koşulu vardır:

  1. Çekirdek çalıştırılabilir dosyayı açar ve #!.
  2. Çekirdek çalıştırılabilir dosyayı kapatır ve bunun yerine yorumlayıcıyı açar.
  3. Çekirdek, komut listesine giden yolu argüman listesine ekler ( argv [1] ) ve yorumlayıcıyı çalıştırır.

Bu uygulamayla setuid komut dosyalarına izin verilirse, saldırgan sembolik bir bağlantı oluşturarak rastgele bir komut dosyası çağırabilir. var olan bir setuid betiği, onu çalıştırır ve çekirdek 1. adımı gerçekleştirdikten sonra ve yorumlayıcı ilk argümanını açmadan önce bağlantıyı değiştirmeyi düzenler. Bu nedenle, tüm modern aygıtlar bir shebang algıladıklarında setuid bitini yok sayarlar.

Bu uygulamayı güvenli hale getirmenin bir yolu, çekirdeğin komut dosyası dosyasını yorumlayıcı açana kadar kilitlemesidir (şunu unutmayın: yalnızca dosyanın bağlantısının kaldırılmasını veya üzerine yazılmasını değil, aynı zamanda yoldaki herhangi bir dizini yeniden adlandırmayı da engellemelidir). Ancak unix sistemleri zorunlu kilitlerden uzak durma eğilimindedir ve sembolik bağlantılar doğru bir kilit özelliğini özellikle zor ve istilacı hale getirir. Kimsenin bunu bu şekilde yaptığını sanmıyorum.

Birkaç unix sistemi ek bir özellik kullanarak güvenli setuid shebang uygular: / dev / fd / N , N dosya tanımlayıcısında zaten açılmış olan dosyayı ifade eder (bu nedenle /dev/fd/N 'nin açılması kabaca ile eşdeğerdir dup ( N ) ).

  1. Çekirdek çalıştırılabilir dosyayı açar ve #! ile başladığını bulur. Çalıştırılabilir dosyanın dosya tanımlayıcısının 3 olduğunu varsayalım.
  2. Çekirdek, yorumlayıcıyı açar.
  3. Çekirdek, / dev / fd / 3 argüman listesini ekler ( argv [1] olarak) ve yorumlayıcıyı çalıştırır.

Linux dahil tüm modern unix varyantları / dev / fd uygular, ancak çoğu setuid komut dosyalarına izin vermez. Varsayılan olmayan bir çekirdek ayarını etkinleştirirseniz OpenBSD, NetBSD ve Mac OS X bunu destekler. Linux'ta insanlar buna izin vermek için yamalar yazdılar ama bu yamalar hiçbir zaman birleştirilmedi. Sven Mascheck'in shebang sayfasında, setuid desteği de dahil olmak üzere, unices'daki shebang hakkında pek çok bilgi var.


Ayrıca, yükseltilmiş ayrıcalıklarla çalışan programlar tercüman özel olarak bunun için tasarlanmadıkça, genellikle daha yüksek seviyeli programlama dillerinde kontrol edilmesi daha zor olan doğal risklere sahiptir. Bunun nedeni, programlama dili çalışma zamanının başlatma kodunun, programın kendi kodu bu verileri temizleme fırsatına sahip olmadan önce, düşük ayrıcalıklı arayandan miras alınan verilere dayalı olarak yükseltilmiş ayrıcalıklarla eylemler gerçekleştirebilmesidir. C çalışma zamanı programcı için çok az şey yapar, bu nedenle C programları, kötü bir şey olmadan önce kontrolü ele alma ve verileri temizleme fırsatına sahiptir.

Programınızı kök olarak çalıştırmayı başardığınızı varsayalım, ya işletim sisteminiz setuid shebang'ı desteklediği için ya da yerel bir ikili sarmalayıcı ( sudo gibi) kullandığınız için. Bir güvenlik deliği açtınız mı? Olabilir. Buradaki sorun, yorumlanmış programlarla derlenmiş programların değildir . Sorun, çalışma zamanı sisteminizin ayrıcalıklarla çalıştırıldığında güvenli bir şekilde davranıp davranmayacağıdır.

  • Dinamik olarak bağlı herhangi bir yerel ikili yürütülebilir dosya, programın gerektirdiği dinamik kitaplıkları yükleyen dinamik yükleyici (ör. /lib/ld.so ) tarafından yorumlanır. Birçok aygıtta, dinamik kitaplıklar için arama yolunu ortam aracılığıyla yapılandırabilirsiniz ( LD_LIBRARY_PATH ortam değişkeni için ortak bir addır) ve hatta yürütülen tüm ikili dosyalara ( LD_PRELOAD ). Programın çağırıcısı, özel olarak hazırlanmış bir libc.so 'u $ LD_LIBRARY_PATH içine (diğer taktiklerin yanı sıra) yerleştirerek, o programın bağlamında rastgele kod çalıştırabilir. Tüm mantıklı sistemler, setuid çalıştırılabilirlerindeki LD_ * değişkenlerini göz ardı eder.

  • sh, csh ve türevleri gibi kabuklarda, ortam değişkenleri otomatik olarak kabuk parametreleri haline gelir. PATH , IFS ve çok daha fazlası gibi parametreler aracılığıyla, komut dosyasının çağırıcısı, kabuk komut dosyalarının bağlamında rastgele kod yürütmek için birçok fırsata sahiptir. Bazı kabuklar, komut dosyasının ayrıcalıklarla çağrıldığını algılarlarsa bu değişkenleri mantıklı varsayılanlara ayarlar, ancak güvenebileceğim belirli bir uygulama olduğunu bilmiyorum.

  • Çoğu çalışma zamanı ortamı (yerel, bayt kodu veya yorumlanmış) benzer özelliklere sahiptir. Yerel kodu çalıştıranlar genellikle dinamik bağlamadan daha süslü bir şey yapmasa da (önlem alır) setuid çalıştırılabilir dosyalarında çok az kişi özel önlemler alır.

  • Perl, dikkate değer bir istisnadır. Setuid betiklerini güvenli bir şekilde açıkça destekler. Aslında, işletim sisteminiz komut dosyalarındaki setuid bitini yok saysa bile komut dosyanız setuid'i çalıştırabilir. Bunun nedeni, perl'in gerekli kontrolleri yapan ve yorumlayıcıyı istenen yetkilere sahip istenen komut dosyalarında yeniden çağıran bir setuid kök yardımcısı ile birlikte gönderilmesidir. Bu, perlsec kılavuzunda açıklanmıştır. Eskiden setuid perl betikleri #! / Usr / bin / perl -wT yerine #! / Usr / bin / suidperl -wT gerektiriyordu, ancak çoğu modern sistemler, #! / usr / bin / perl -wT yeterlidir.

Yerel bir ikili sarmalayıcı kullanmanın kendi başına bu problemler. Aslında, durumu daha da kötüleştirebilir, çünkü çalışma zamanı ortamınızın ayrıcalıklarla çağrıldığını algılamasını ve çalışma zamanı yapılandırılabilirliğini atlamasını engelleyebilir.

Yerel bir ikili sarmalayıcı, bir kabuk komut dosyasını güvenli hale getirebilir. sargı, ortamı sterilize eder. Komut dosyası çok fazla varsayımda bulunmamaya dikkat etmelidir (örneğin mevcut dizin hakkında) ama bu devam eder. Ortamı sterilize edecek şekilde ayarlanmış olması koşuluyla, bunun için sudo'yu kullanabilirsiniz. Kara listeye alma değişkenleri hataya açıktır, bu nedenle her zaman beyaz listeye alın. Sudo ile, env_reset seçeneğinin açık olduğundan, setenv 'in kapalı olduğundan ve env_file ve env_keep yalnızca zararsız değişkenler içerir.

Tüm bu hususlar herhangi bir ayrıcalık yükseltmesi için eşit derecede geçerlidir: setuid, setgid, setcap.

https: / 'den geri dönüştürüldü. /unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts/2910#2910

Şunu söyleyecektim (sonuna doğru değinmiş olsanız da) - Geçmişte güvenliğe duyarlı ortamlarda ikili sarmalayıcılar alışkanlığı edindim, ancak yalnızca açık bir ortamı geçmek için `execve () 'kullanırken (vekomut dosyası, ayrıcalıklı olmayan kullanıcılar tarafından yazılamayan tam nitelikli, sabit kodlanmış bir yol)."* E" "exec *" olmayan bir çağrıyı kullanmak bir sorundur, ancak ortamı çok fazla değiştiren çağrılar mevcuttur.
İtiraf etmeliyim ki, #! / Usr / bin / suidperl'in, ona sahip olmak için tasarlanmamış bir betiğe yanlışlıkla suid biti yerleştirmesini önlemek için gerekli olmadığı için hayal kırıklığına uğradım.
GNU dinamik bağlayıcısının en azından LD_ * değişkenlerini yok saymakla kalmayıp aynı zamanda onları kaldırmadığını da unutmayın; bu, bir `setuid (geteuid ()) 'yapsanız bile setuid programınızdan / betiğinizden yürüttüğünüz diğer programlar anlamına gelir.bunlardan etkilenmeyecektir.
Yürütme () boyunca iletilen / korunan tek şey çevre değişkenleri değildir (bu da ayrıcalık yükseltmesini getirir).Ayrıca sinyal dağıtımı (örneğin SIGPIPE veya SICHLD'yi görmezden geldiğinizde ne olacağını görün), açık (ve 0,1,2 gibi kapalı) fds, kontrol terminali, cwd, limitler (bunların çoğunu düşürerek birçok yazılımı açabilirsiniz), umask... Yükseltilmiş ayrıcalıkla çalışan kodu en aza indirmek ve çok dikkatli yazmak istiyorsunuz.Komut dosyası içinde bütün bir kabuğu ve tüm komutları çalıştırmak, yapmak isteyeceğiniz son şeydir.
gowenfawr
2018-09-21 00:43:38 UTC
view on stackexchange narkive permalink

Öncelikle çünkü

Birçok çekirdek, yeni çalıştırılan zamanlar arasında kabuk komut dosyasını seçtiğiniz başka bir yürütülebilir dosya ile değiştirmenize olanak tanıyan bir yarış koşulundan muzdariptir. () ed işlemi setuid'e gider ve komut yorumlayıcısı başlatıldığında. Yeterince ısrarcıysanız, teoride çekirdeği istediğiniz herhangi bir programı çalıştıracak şekilde alabilirsiniz.

ve bu bağlantıda bulunan diğer nedenler (ancak çekirdek yarış durumu en tehlikeli olanıdır) ). Elbette, komut dosyaları ikili programlardan farklı şekilde yüklenir, bu da hatanın içeri girdiği yerdir.

Bu 2001 Dr. Dobb'un makalesini okuyabilirsiniz - 6. daha güvenli SUID kabuk komut dosyaları yazmaya yönelik adımlar, yalnızca 7. adıma ulaşmak için:

Yedinci Ders - SUID kabuk komut dosyalarını kullanmayın.

Tüm çalışmalarımızdan sonra bile, güvenli SUID kabuk komut dosyaları oluşturmak neredeyse imkansız. (Çoğu sistemde imkansızdır.) Bu sorunlar nedeniyle, bazı sistemler (örneğin, Linux) kabuk komut dosyalarında SUID'e uymayacaktır.

Bu geçmiş yarış durumu için hangi varyantların düzeltildiğinden bahsediyor; liste düşündüğünüzden daha büyük ... ancak setuid komut dosyalarının hala büyük ölçüde başka sorunlar nedeniyle veya onları cesaretini kırmak, güvenli veya güvenli olmayan bir varyantta çalışıp çalışmadığınızı hatırlamaktan daha kolay olduğu için cesaret kırılıyor.

Bu, o günlerde yeterince büyük bir sorundu ve Perl 'in bunu telafi etmeye ne kadar agresif bir şekilde yaklaştığını okumak öğreticiydi.



Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 4.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...