Jednym słowem „nie”.
Linux tak naprawdę nie rozróżnia plików wykonywalnych i skryptów; #!
na początku jest jakiś sposób powiadomić jądro, co program do uruchomienia w celu oceny wkładu, ale nie jest to jedyny sposób skrypt może być wykonywany.
Na przykład, jeśli mam skrypt
$ cat x
#!/bin/sh
echo hello
Następnie mogę uruchomić to za pomocą polecenia
$ ./x
Spowoduje to, że jądro spróbuje go uruchomić, wykryje, #!
a następnie efektywnie uruchomi /bin/sh x
.
Mógłbym jednak również uruchomić dowolny z tych wariantów:
$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x
lub nawet
. ./x
Więc nawet jeśli jądro próbuje wymusić podpisywanie na exec
warstwie, możemy to obejść, uruchamiając interpreter tylko ze skryptem jako parametrem.
Oznacza to, że kod podpisu musiałby znajdować się w samym tłumaczu. A co powstrzymałoby użytkownika przed skompilowaniem własnej kopii powłoki bez kodu wymuszającego podpisanie?
Standardowym rozwiązaniem tego problemu nie jest korzystanie z podpisywania, ale stosowanie obowiązkowej kontroli dostępu (MAC), takiej jak SELinux
. W systemach MAC możesz dokładnie określić, co każdy użytkownik może uruchamiać, i zmieniać warstwy. Na przykład można powiedzieć, że „normalni użytkownicy mogą uruchamiać wszystko, ale serwer WWW i procesy CGI mogą uzyskiwać dostęp tylko do danych z /var/httpd
katalogu; wszystko inne jest odrzucane”.