Linux, yorumlanmış tüm çalıştırılabilir dosyalardaki (örneğin bir #!
satırdan başlayarak çalıştırılabilen çalıştırmalar) ayar bileşenini yok sayar . Comp.unix.questions SSS setuid kabuk komut ile güvenlik sorunlarını açıklar. Bu problemler iki türdür: shebang ve shell ile ilgili; Aşağıda daha fazla ayrıntıya giriyorum.
Güvenliği umursamıyorsanız ve setuid komut dosyalarına izin vermek istiyorsanız, Linux altında çekirdeği düzeltmeniz gerekir. 3.x çekirdeklerin olarak sana bir çağrı eklemek gerektiğini düşünüyorum install_exec_creds
içinde load_script
çağrısı önce, işlevi open_exec
, ama ben test etmedim.
Setuid Shebang
Shebang ( #!
) 'nin tipik olarak uygulanma biçimine özgü bir yarış koşulu vardır :
- Çekirdek yürütülebilir dosyayı açar ve onunla başladığını bulur
#!
.
- Çekirdek yürütülebilir dosyayı kapatır ve bunun yerine yorumlayıcıyı açar.
- Çekirdek betiğe yolu argüman listesine (as
argv[1]
) ekler ve yorumlayıcıyı çalıştırır.
Bu uygulamayla setuid komut dosyalarına izin verilirse, bir saldırgan mevcut bir setuid komut dosyasına sembolik bir bağlantı oluşturarak, uygulayarak ve çekirdeğin adım 1'i tamamladıktan sonra ve tercüman dolaşmadan önce bağlantıyı değiştirerek düzenleme yaparak rasgele bir komut dosyası çalıştırabilir ilk argümanını açıyor. Bu nedenle, çoğu sendika bir shebang tespit ettiklerinde setuid bitini yok sayarlar .
Bu uygulamayı güvence altına almanın bir yolu, çekirdeğin yorumlayıcı açılıncaya kadar komut dosyasını kilitlemesi olacaktır (bunun yalnızca dosyanın bağlantısını kesmesini veya üzerine yazmasını değil, aynı zamanda yoldaki herhangi bir dizini yeniden adlandırmasını da engellemesi gerektiğini unutmayın). Ancak, unix sistemleri zorunlu kilitlerden uzak durma eğilimindedir ve sembolik bağlantılar özellikle zor ve istilacı olarak doğru bir kilitleme özelliği sağlar. Kimsenin böyle yaptığını sanmıyorum.
Birkaç unix sistemi (temel olarak OpenBSD, NetBSD ve Mac OS X, hepsi etkin olmak üzere bir çekirdek ayarı gerektirir) , ek bir özellik kullanarak güvenli setuid shebang uygular : yol , önceden tanımlayıcı N'de açılmış olan dosyaya atıfta bulunur (açılış , kabaca eşittir ). Pek çok unix sistemi (Linux dahil) ayarlanmış komut dosyalarına sahiptir ancak bu komutları kullanmamıştır./dev/fd/N
/dev/fd/N
dup(N)
/dev/fd
- Çekirdek yürütülebilir dosyayı açar ve onunla başladığını bulur
#!
. Çalıştırılabilir dosya tanımlayıcısının 3 olduğunu varsayalım.
- Çekirdek tercümanı açar.
- Çekirdek
/dev/fd/3
bağımsız değişken listesini (as argv[1]
) ekler ve yorumlayıcıyı yürütür.
Sven Mascheck'in shebang sayfası , setuid desteği de dahil olmak üzere, sendikalar arasında shebang hakkında birçok bilgi içermektedir.
Setuid tercümanlar
İşletim sisteminizin setuid shebang'ı desteklediğinden veya yerel bir ikili sarmalayıcı kullandığınızdan (örneğin sudo
) , programınızın root olarak çalışmasını sağladığınızı varsayalım . Bir güvenlik deliği açtın mı? Belki . Buradaki sorun, derlenmiş programların yorumlanmasıyla ilgili değildir . Sorun, çalışma zamanı sisteminizin ayrıcalıklarla yürütüldüğünde güvenli davranıp davranmamasıdır.
Dinamik olarak bağlanmış herhangi bir yerel ikili çalıştırılabilir program, program tarafından istenen dinamik kütüphaneleri yükleyen dinamik yükleyici (örn. /lib/ld.so
) Tarafından yorumlanır . Birçok ünitede, ortamdaki dinamik kitaplıklar için arama yolunu yapılandırabilir ( LD_LIBRARY_PATH
ortam değişkeni için ortak bir addır) ve hatta yürütülen tüm ikili dosyalara ek kitaplıklar yükleyebilirsiniz ( LD_PRELOAD
). Programın invoker özel hazırlanmış bir yerleştirerek bu programın bağlamında rasgele kod yürütebilir libc.so
içinde $LD_LIBRARY_PATH
(diğer taktik arasında). Tüm mantıklı sistemler LD_*
, setuid çalıştırılabilir değişkenlerini görmezden gelir .
Gelen kabukları gibi sh csh'ın ve bunların türevleri gibi, çevre değişkenleri otomatik olarak kabuk parametresi olur. Gibi parametreler aracılığıyla PATH
, IFS
ve daha birçok senaryonun invoker kabuk dosyalarınızın en bağlamında rasgele kod çalıştırmak için birçok fırsat vardır. Bazı mermiler, betiğin ayrıcalıklarla çağrıldığını algılarlarsa, bu değişkenleri varsayılan değerlere ayarlarlar, ancak güvenebileceğim herhangi bir uygulama olduğunu bilmiyorum.
Çoğu çalışma zamanı ortamı (yerel, bayt kodu veya yorumlanmış olsun) benzer özelliklere sahiptir. Bazıları setuid çalıştırılabilir işlemlerinde özel önlemler alır, ancak yerel kodu kullananlar genellikle dinamik bağlantıdan (bu önlemleri alır) daha fazla bir şey yapmazlar.
Perl önemli bir istisnadır. Bu açıkça Setuid komut dosyalarını destekleyen güvenli bir şekilde. Aslında, işletim sisteminiz komut dosyalarındaki setuid bitini dikkate almamış olsa bile betiğiniz setuid komutunu çalıştırabilir. Bunun sebebi perl'in gerekli kontrolleri yapan ve tercümanı istenen komut dosyası üzerinde istenen yetkilerle yeniden dizginleyen bir setuid root yardımcı ile birlikte gönderilmesidir. Bu perlsec kılavuzunda açıklanmıştır . Eskiden #!/usr/bin/suidperl -wT
bunun yerine gerekli olan setuid perl scriptleriydi #!/usr/bin/perl -wT
, ancak çoğu modern sistemde #!/usr/bin/perl -wT
yeterliydi.
Yerel bir ikili sarmalayıcı kullanmanın bu sorunları önlemek için kendi içinde hiçbir şey yapmadığını unutmayın . Aslında, durumu daha da kötüleştirebilir , çünkü çalışma zamanı ortamınızın ayrıcalıklarla başlatıldığını algılamasını ve çalışma zamanı yapılandırılabilirliğini atlamasını engelleyebilir.
Yerel bir ikili sarmalayıcı, sarmalayıcı çevreyi temizlediğinde kabuk kodunu güvenli hale getirebilir . Senaryo çok fazla varsayımda bulunmamaya özen göstermelidir (örn. Mevcut dizin hakkında), ancak bu geçerli. Bunun için sudo'yu, çevreyi sterilize edecek şekilde ayarlanması koşuluyla kullanabilirsiniz. Kara liste değişkenleri hataya açıktır, bu nedenle her zaman beyaz listedir. Sudo ile env_reset
seçeneğin açık setenv
, kapalı, env_file
ve env_keep
sadece zararsız değişkenleri içerdiğinden emin olun .
TL, DR:
- Setuid Shebang güvensiz ama genellikle göz ardı edilir.
- Ayrıcalıklı bir program çalıştırıyorsanız (sudo veya setuid aracılığıyla), yerel kod veya perl yazın veya çevreyi dezenfekte eden bir sarmalayıcıyla (
env_reset
seçenekle sudo gibi) programı başlatın .
Discussion “setuid” yerine “setgid” yerine geçtiyseniz, bu tartışma aynı şekilde geçerlidir; ikisi de Linux çekirdeği tarafından senaryolarda yoksayılır