Shebang'ın ( #!
) tipik olarak uygulanma şekline özgü bir yarış koşulu vardır:
- Çekirdek çalıştırılabilir dosyayı açar ve
#!
. - Çekirdek çalıştırılabilir dosyayı kapatır ve bunun yerine yorumlayıcıyı açar.
- Ç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 )
).
- Ç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. - Çekirdek, yorumlayıcıyı açar.
- Ç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