Czy skrypt może być wykonywalny, ale nieczytelny?


65

Czy można wykonać skrypt, jeśli nie ma pozwolenia na jego odczytanie? W trybie root utworzyłem skrypt i chcę, aby inny użytkownik wykonał ten skrypt, ale go nie przeczytał. Zrobiłem chmodzabronić odczytu i zapisu, ale zezwoliłem na wykonanie, jednak w trybie użytkownika zobaczyłem komunikat: odmowa uprawnień.


Odpowiedzi:


68

Problem jest, że skrypt nie jest to, co jest uruchomiony, ale interpreter ( bash, perl, python, itd.). Tłumacz musi przeczytać skrypt. Różni się to od „zwykłego” programu, na przykład tym ls, że program jest ładowany bezpośrednio do jądra, tak jak zrobiłby to interpreter. Ponieważ samo jądro odczytuje plik programu, nie musi się martwić o dostęp do odczytu. Tłumacz musi odczytać plik skryptu, ponieważ normalny plik musiałby zostać odczytany.


2
Tak, ale w jego przypadku jest jakieś rozwiązanie?
Olivier Pons

13
Jedną z możliwości byłoby posiadanie prostego programu C, który osadza skrypt i wyraźnie wywołuje interpreter. Program AC nie musi mieć uprawnień do odczytu, aby wykonać.
Arcege

1
Ściśle mówiąc, jądro nie dyskryminuje w tym przypadku i będzie w rzeczywistości uruchomić powłokę (tak samo, jak wtedy, gdy plik wykonywalny był binarny). Jednak sama powłoka natychmiast się zawiesi, ponieważ nie może odczytać pliku wejściowego (zawartości pliku skryptu).
Józef

34

Jest to możliwe tylko w przypadku plików binarnych.

$ chown foo:foo bar
$ chmod 701 bar

Jako użytkownik nieuprzywilejowany:

$ ls -lha bar
-rwx-----x 1 foo foo 7.0K 2012-03-15 03:06 bar

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

Teraz jest kicker. Chociaż plik jest nieczytelny w konwencjonalny sposób, nie można tak naprawdę uniemożliwić jego odczytania. Jest to właściwie wyzwanie na http://smashthestack.org/ (poziom 13). Istnieje dobrze znane narzędzie o nazwie, hktracektóre pozwala na odczyt pliku za pomocą ptrace.


Bardzo interesujące (hktrace).
myśliciel

1
czy można przekonwertować skrypt powłoki na format binarny?
ashim

4
Myślę, że można temu zapobiec. Obecne wersje jądra Linuksa ustawiają proces na bez możliwości zrzutu, co oznacza, że ​​żaden normalny użytkownik nie może go już śledzić, jeśli użytkownik nie może odczytać pliku binarnego.
thejh

6

Nie jest to możliwe, przynajmniej w Linuksie (inne Uniksy mogą na to pozwolić); pomyśl o tym, kiedy uruchomisz skrypt, powłoka musi go przeczytać, aby wiedzieć, co robić.


3
Z pewnością jest to możliwe; OpenBSD pozwala na wykonanie dowolnego skryptu bez zgody na odczyt. Pod maską robi to, tworząc duplikat deskryptora pliku do użycia przez interpretera.
eradman

@eradman Włożyłam że (wraz z wyjaśnieniem przykład i niektórych uwag kopalni) w jego odpowiedzi .
mosvy

3

Myślę, że możesz to zrobić setuid.

Tyle że nie możesz, ponieważ większość dystrybucji (najwyraźniej) została setuidwyłączona, ponieważ jest to ogromna dziura w zabezpieczeniach. Moja jest wyłączona, więc tak naprawdę nie wiem, czy ta odpowiedź zadziała, i tak ją publikuję, ponieważ uważam, że powinna .

W każdym razie, gdybym chciał zrobić to, co chciałeś - i miałem dystrybucję z setuidwłączoną obsługą skryptów - zrobiłbym coś takiego:

$ chmod 700 myscript
$ cat > myscript-nonroot
#!/bin/sh
bash myscript
^D
$ sudo chown root:root myscript-nonroot
$ sudo chmod 4755 myscript-nonroot # make SURE this isn't world-writable!

To znaczy, że napisałbym inny skrypt, którego jedynym celem jest wywołanie skryptu tylko do odczytu root, zmiana go na własność roota i udzielenie mu uprawnień setuid. (Wraz z towarzyszącym temu niepisywalnym statusem przez wszystkich innych).

Ponieważ funkcja myscript-nonroot jest czytelna dla wszystkich, można ją odczytać i wykonać, a do czasu uzyskania dwóch wierszy, w którym faktycznie wykonujesz skrypt ( bash myscript), jest uruchamiany jako root (lub ktokolwiek inny, dokładny użytkownik nie ma znaczenia, o ile plik opakowania jest własnością tego samego użytkownika).


Co oznacza 4755? Jestem w tym nowy, więc chciałbym wiedzieć, co to znaczy. Rozumiem część 755. Dzięki
Kevdog777,

2
gdy 4ustawia setuid bit. Zobacz sekcję Tryby na stronie podręcznika użytkownika chmod na manpagez .
quodlibetor

Ok, nadal nie całkiem rozumiem, ale zajęło mi to trochę czasu, aby zrozumieć 755trochę.
Kevdog777,

tak, faktycznie chmod 755jest taki sam jak ósemkowy 0775. wokół tego jest wiele zamieszania .. Ta strona ( manpagez.com/man/1/chmod ) ma okropny i nieposiadający poziomego zwoju, którego nie rozumiem ...
erm3nda

2

W poprzednich stwierdzeniach jest połowa prawdy. Możesz skonfigurować skrypt, aby nie był czytelny dla użytkownika, ale nadal był wykonywalny. Proces ten jest trochę przeciągnięty, ale można go zrobić, robiąc wyjątek w / etc / sudoer, aby użytkownik mógł tymczasowo uruchomić skrypt jak sam, bez pytania o hasło. Ta metoda: - omija łatkę setuid dla innych dystrybucji. - pozwala tymczasowo przyznać podwyższone uprawnienia dla określonego skryptu, nie dając użytkownikowi prawa sudo do wszystkiego.

Postępuj zgodnie z instrukcjami w tym poście: Zezwól tylko na plik


1

W tej sytuacji użyłem sudo z opcją NOPASSWD, aby użytkownicy mogli uruchomić skrypt bez możliwości jego odczytania.


0

Działa na OpenBSD

Jak już wspomniano w komentarzu @eradman, jest to możliwe na OpenBSD.

Jako root:

hzy# cat <<'EOT' >/tmp/foo; chmod 001 /tmp/foo
#! /bin/sh
: this is secret
echo done
EOT

Jako zwykły użytkownik:

hzy$ cat /tmp/foo
cat: /tmp/foo: Permission denied
hzy$ /tmp/foo
done

Działa to poprzez przekazanie /dev/fd/3(lub cokolwiek innego otwartego fd do skryptu) do tłumacza. Ta sztuczka nie działałaby w systemie Linux, gdzie /dev/fd/Nnie są specjalne urządzenia znakowe, które zwracają a dup(2)fd po otwarciu, ale „magiczne” dowiązania symboliczne do oryginalnego pliku / dentry, które otwierają plik od zera [1]. To mogłoby być realizowane Wolny / NetBSD lub Solaris ...

Ale to nie jest to, czym się spieprzyło

Zasadniczo udzielenie uprawnienia x(wykonania) oznacza również udzielenie uprawnienia r(odczytu) do dowolnego pliku, który ma shebang [2]:

hzy$ cat /tmp/foo
cat: /tmp/foo: Permission denied
hzy$ ktrace -ti /tmp/foo
done
hzy$ kdump | tail -n8
 70154 sh       GIO   fd 10 read 38 bytes
       "#! /bin/sh
        : this is secret
        echo done
       "
 70154 sh       GIO   fd 1 wrote 5 bytes
       "done

ktraceto nie jedyny sposób; jeśli interpreter jest dynamicznie połączony z plikiem wykonywalnym, takim jak perllub python, można zamiast tego użyć LD_PRELOADed hacka, który przesłania read(2)funkcję.

I nie, ustawienie setuid nie uniemożliwi zwykłemu użytkownikowi oglądania jego zawartości; mogłaby po prostu go uruchomić ptrace(2), co spowoduje ignorowanie bitów setuid:

Jako root:

hzyS# cat <<'EOT' >/tmp/bar; chmod 4001 /tmp/bar
#! /bin/sh
: this is secret
id
EOT

Jako zwykły użytkownik:

hzyS$ ktrace -ti /tmp/bar
uid=1001(duns) euid=0(root) gid=1001(duns) groups=1001(duns)
hzyS$ kdump
    ... nothing, the kernel disabled the ktrace ...
hzyS$ cc -Wall -xc - -o pt <<'EOT'
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <signal.h>

int main(int ac, char **av){
        int s; pid_t pid;
        if((pid = fork()) == 0){
                ptrace(PT_TRACE_ME, 0, 0, 0);
                execvp(av[1], av + 1);
        }
        while(wait(&s) > 0 && WIFSTOPPED(s)){
                s = WSTOPSIG(s);
                ptrace(PT_CONTINUE, pid, (caddr_t)1, s == SIGTRAP ? 0 : s);
        }
}
EOT
hzyS$ ./pt ktrace -ti /tmp/bar
uid=1001(duns) gid=1001(duns) groups=1001(duns)
hzyS$ kdump | tail -5
 29543 sh       GIO   fd 10 read 31 bytes
       "#! /bin/sh
        : this is secret
        id
       "

(przepraszam, jeśli nie jest to najłatwiejszy sposób na wykazanie tego)

[1] można to emulować w systemie Linux za pomocą binfmt_misc, ale interpreter będzie musiał zostać zmodyfikowany lub będzie konieczne użycie opakowania; patrz ostatnia część tej odpowiedzi na przykład celowo uczyniony absurdalnie niepewnym.

[2] lub ogólnie dowolny plik, który nie spowoduje execve()zwrotu ENOEXEC.


-2

Tak, jeśli jesteś użytkownikiem root, możesz wykonać plik bez pozwolenia na odczyt

# echo "echo hello" > test
# chmod 100 test
# ll test
---x------ 1 root root 10 Nov 29 12:13 test
# ./test
hello

Ale jeśli zalogujesz się z innym użytkownikiem, nie możesz uruchomić tego pliku

$ ./test
-bash: ./test: Permission denied

3
To tak naprawdę nie odpowiada na pytanie, ponieważ root może nadal czytać plik nawet bez pozwolenia.
wjandrea

-5

Aby Twoje skrypty były nieczytelne, a jednocześnie wykonywalne, masz 3 główne opcje:

Pierwsza opcja

Użyj polecenia openssl, aby ręcznie go zaszyfrować. W przyszłości, gdy chcesz uruchomić skrypt, będziesz musiał ponownie uruchomić openssl ręcznie i podać hasło do odszyfrowania.

Szyfrowanie za pomocą openssl:

cat yourscript.sh | openssl aes-128-cbc -a -salt -k twoje hasło> twój skrypt.enc

Deszyfrowanie za pomocą openssl:

cat yourscript.enc | openssl aes-128-cbc -a -d -salt -k twoje hasło> twój skrypt.dec

yourscript.dec będzie taki sam jak oryginalny skrypt yourscript.sh

Druga opcja

Skorzystaj z witryny takiej jak www.Enscryption.com, aby automatycznie zaszyfrować skrypt i umożliwić wykonanie zaszyfrowanej wersji skryptu. Ta strona wykorzystuje zarówno funkcje szyfrowania openssl, jak i niektóre inne metody zaciemniania, aby utrudnić intruzom włamanie się do skryptu lub ujawnienie tajemnic, które chcesz ukryć. Za pomocą tej strony możesz szyfrować skrypty powłoki i wiersze poleceń perl, python, ruby. Myślę też, że php.

Trzecia opcja

Użyj narzędzia takiego jak shc . Wygląda na to, że nie był aktualizowany od 2012 roku. Ale korzystałem z niego w przeszłości. Musisz skompilować skrypt dla każdego systemu operacyjnego, na którym chcesz go używać, jeśli system operacyjny jest inny niż ten, którego użyłeś do kompilacji.

Podsumowanie:

Jeśli ukrywanie twojego kodu jest dla ciebie bardzo ważne, poleganie tylko na uprawnieniach i prawie własności pomoże ci, ponieważ każdy z rootem może się do niego dostać. To tylko fakt. Co możesz zrobić, jeśli naprawdę chcesz zapobiec nieautoryzowanemu przeglądaniu twojego kodu przez kogokolwiek, jest napisanie skryptu wokół polecenia openssl. Spraw, aby przed uruchomieniem skryptu pojawił się monit o podanie hasła, a po podaniu hasła uruchomi skrypt bez zapisywania go w pliku tymczasowym. Jeśli wydaje ci się, że to za dużo pracy, opcje 2 i 3 powinny wystarczyć do twoich celów.


Link „shc” wskazuje również na jedną stronę z poprzedniej strony. Czy przypadkiem jesteś powiązany z tą stroną / usługą?
phk

3
Jeśli zaszyfrujesz skrypt, nie będzie on mógł działać bez klucza. Jeśli wysłałeś klucz do użytkownika, aby go uruchomić, będzie mógł zobaczyć jego zawartość. Te odpowiedzi są takie głupie ...
erm3nda
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.