Değişkenleri kök etkinleştirilmiş komut dosyalarına güvenli bir şekilde nasıl aktarabilirim?


13

Bu soru tamamen genel ve sadece benim durumum için geçerli değildir, ama ... Kök olmayan bir kullanıcının kök ayrıcalıklarıyla belirli bir komut dosyasını yürütmesini istediğim küçük bir meşgul kutusu cihazım var. Örneğin $1, cmdline (!!) üzerinde gönderilecek tek değişkenin ( ) hangi ana bilgisayar adı gönderileceği DHCP'yi etkinleştirmek için bu küçük komut dosyası gibi bir şey :

#!/bin/bash
udhcpc -b -i eth0 -h $1

böyle udhcpc çalıştırmak kök erişimi gerektirir, bu nedenle bunu yapmak /etc/sudoersiçin bu satırı içerecek şekilde değiştirmeyi planlıyorum :

joe ALL = NOPASSWD: /path/to/enable_dhcp.sh

"joe" komutunun bu komut dosyasını kök ayrıcalıklarla kolayca çalıştırabilmesini sağlar:

sudo /path/to/enable_dhcp.sh

ve bir parola istenmemesi (joe bunu yazabilmeyi istediğim için istediğim budur).

Şimdi .. Kök ayrıcalıkları ile kolayca çalıştırılabilen bir komut dosyasında kullanmanın KORKUNÇ bir fikir olduğunu biliyorum (ya da en azından benim yaptığımı düşünüyorum) $1.

Peki ... bununla başa çıkmanın en iyi yolu nedir? Enjeksiyon saldırılarına açık olmasa da, joe'nin kök ayrıcalıklarıyla istediğimi yapmasına, bir değişkeni geçirmesine (ya da bir ortam değişkeninde olduğu gibi etkili bir şekilde yapmasına) nasıl izin verebilirim?

Yanıtlar:


14

Çevreyi sıfırlamak için yapılandırılmış olması koşuluyla kabuk komut dosyalarının altında çalıştırılması sudogüvenlidir . Tersine, ortamı sıfırlamazsa, komut dosyanız parametrelerini kullanmasa bile bir kabuk komut dosyası çalıştırmak güvenli değildir (bkz . Kabuk komut dosyalarında setuid'e izin verme ). İçinde bulunduğunuzdan veya bu seçeneğin derleme zamanı varsayılanı ( içermelidir ) olduğundan emin olun .sudosudoDefaults env_reset/etc/sudoerssudo sudo -V | grep envReset the environment to a default set of variables

Komut dosyası parametrelerini kullanmanın belirli bir tehlikesi yoktur. $1bir dizedir, emin olmak için tek yapmanız gereken dize olarak kullanmaktır. (Örneğin, yapmayın eval "$1".) Açıkçası, burada değişkenin içeriği hakkında varsayımlar yapmamak ve tüm değişken ikamelerin etrafına çift tırnak koymak (yani yazma "$1"değil $1) özellikle önemlidir . Değişken ikamelerinin etrafına çift tırnak işareti koymanın ayrıcalıklarla çalışan komut dosyalarına özgü olmadığını, her zaman yapmanız gereken bir şey olduğunu unutmayın.

udhcpcAna bilgisayar adı gibi görünmeyen bir şeyle ne yaptığına bağlı olarak parametreyi daha fazla doğrulamak isteyebilirsiniz . Örneğin, bu bir ilk sözdizimsel denetimi gerçekleştirir:

#!/bin/sh
case "$1" in
  *[!:-.0-9A-Za-z]*|-*) echo 1>&2 "Badly formed host name!"; exit 3;;
esac
udhcpc -b -i eth0 -h "$1"

Bu komutun davranışı üzerinde etkili olabileceği düşünülecek diğer şeyler: mevcut çalışma dizini ve stdin, stdout, stderr'nin işaret ettiği, sinyal işleyicileri ve ulimitler. Örneğin, çekirdek dökümlerine izin vererek (<kbd> Ctrl- \ </kbd> üzerine), kullanıcının sistemimde çok sınırlı boyutta bir tmpfs olan ve bir DoS'ye izin verebilecek çöp / çalıştırma / kilitlemesine izin verebilirsiniz.
Stéphane Chazelas

5

Geçirilen girişi bilinen iyi bir kalıpla eşleştirmelisiniz.

Örneğin, bir IP adresi sizin için geçerli bir giriş olabilir. Yani böyle bir şey kullanabilirsiniz:

if [[ "$1" =~ ^[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9]$ ]]
then
  udhcpc -b -i eth0 -h "$1"
else
  echo "Don't mess with me pork chop."
fi

Normal ifade test edilmediğini, normal ifadenizin tehlikeli bir şeye izin vermemesini sağlamakla yükümlüsünüz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.