Uno script può essere eseguibile ma non leggibile?


65

È possibile eseguire uno script se non si dispone dell'autorizzazione per leggerlo? In modalità root, ho creato uno script e voglio che l'altro utente esegua questo script ma non lo legga. Ho chmodvietato la lettura e la scrittura, ma consenti l'esecuzione, tuttavia in modalità utente ho visto il messaggio che dice: autorizzazione negata.


Risposte:


68

Il problema è che lo script non è ciò che è in esecuzione, ma l'interprete ( bash, perl, python, etc.). E l'interprete deve leggere la sceneggiatura. Questo è diverso da un programma "normale", come ls, in quanto il programma viene caricato direttamente nel kernel, come farebbe l'interprete. Poiché il kernel stesso sta leggendo il file di programma, non deve preoccuparsi dell'accesso in lettura. L'interprete deve leggere il file di script, in quanto dovrebbe essere letto un file normale.


2
Sì, ma nel suo caso c'è una soluzione?
Olivier Pons il

13
Una possibilità sarebbe quella di avere un semplice programma C che incorpori lo script e chiami esplicitamente l'interprete. Per eseguire il programma CA non è necessario disporre delle autorizzazioni di lettura.
Arcege,

1
A rigor di termini, il kernel non discrimina in questo caso e sarà infatti eseguito il guscio (allo stesso modo come se il file eseguibile è stato un binario). Tuttavia, la shell stessa si bloccherà immediatamente perché non è in grado di leggere il file di input (il contenuto del file di script).
Jozef

34

Questo è possibile solo per i binari.

$ chown foo:foo bar
$ chmod 701 bar

Come utente non privilegiato:

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

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

Ora, ecco il kicker. Mentre il file è illeggibile con mezzi convenzionali, non puoi effettivamente impedire la lettura del file. Questa è in realtà una sfida su http://smashthestack.org/ (livello 13). Esiste un'utilità ben nota hktraceche consente di leggere il file utilizzando ptrace.


Molto interessante (hktrace).
pensare il

1
è possibile convertire script di shell in formato binario?
ashim,

4
In realtà, puoi prevenirlo, credo. Le attuali versioni del kernel di Linux impostano il processo su non-dumpable, il che significa che nessun utente normale può più seguirlo, se l'utente non è autorizzato a leggere il binario.
thejh

6

Questo non è possibile, almeno su Linux (altri Unice potrebbero consentirlo); pensaci, quando esegui lo script, la shell deve leggerlo per sapere cosa fare.


3
Certamente è possibile; OpenBSD consente l'esecuzione di qualsiasi script senza autorizzazione di lettura. Sotto il cofano lo fa creando un descrittore di file duplicato che l'interprete può usare.
Eradman,

@eradman L'ho inserito (insieme a un esempio, una spiegazione e alcune mie osservazioni) in una risposta .
mosvy,

3

Puoi, credo, farlo con setuid.

Solo che non puoi perché la maggior parte delle distro (apparentemente) ha setuiddisabilitato perché è un enorme buco di sicurezza. È disabilitato sul mio, quindi in realtà non so che questa risposta funzionerà, la sto pubblicando comunque perché penso che dovrebbe .

Comunque, se volessi fare quello che volevi fare - e avessi una distro con setuidabilitato per gli script - farei qualcosa del tipo:

$ 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!

Vale a dire che scriverei un altro script il cui unico scopo è quello di chiamare lo script di sola lettura root, cambiarlo in proprietà di root e dargli il permesso setuid. (Insieme allo status di operatore non scrivibile di tutti gli altri.)

Poiché la funzione myscript-nonroot è leggibile da tutti, può essere letta ed eseguita, e quando ne ottieni due sulla riga in cui esegui effettivamente il tuo script ( bash myscript) viene eseguita come root (o chiunque tu voglia, l'utente esatto non importa, purché il file wrapper sia di proprietà dello stesso utente.)


Cosa significa 4755? Sono nuovo di questo, quindi vorrei sapere cosa significa. Capisco la parte 755. Grazie
Kevdog777 il

2
i 4set il setuid bit. Vedi la sezione Modalità nella pagina man di chmod su manpagez .
quodlibetor,

Ok, ancora non capisco del tutto, ma mi ci è voluto un po 'di tempo per capire un 755po'.
Kevdog777,

sì, in realtà chmod 755è uguale a 0775 ottale. c'è molta confusione in tutto ciò ... Questa pagina ( manpagez.com/man/1/chmod ) ha una pergamena orizzontale terribile e senza segni che non riesco a capire ...
erm3nda

2

In questa situazione ho usato sudo con un'opzione NOPASSWD in modo che gli utenti possano eseguire lo script senza essere in grado di leggerlo.


2

C'è una mezza verità nelle dichiarazioni precedenti. È possibile impostare uno script in modo che non sia leggibile dall'utente, ma comunque eseguibile. Il processo è un po 'elaborato, ma è possibile fare un'eccezione in / etc / sudoer in modo che l'utente possa eseguire lo script come se stesso temporaneamente senza che venga richiesta una password. Questo metodo: - aggira la patch setuid per altre distro. - consente di concedere temporaneamente autorizzazioni elevate per uno script specifico senza fornire all'utente i diritti sudo su tutto.

Seguire le istruzioni in questo post: solo l'autorizzazione per i file viene eseguita


0

Funziona su OpenBSD

Come già accennato in un commento di @eradman, questo è possibile su OpenBSD.

Come root:

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

Come utente normale:

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

Funziona passando /dev/fd/3(o qualunque sia la fd aperta allo script) all'interprete. Quel trucco non funzionerebbe su Linux, dove /dev/fd/Nnon sono dispositivi a caratteri speciali che restituiscono una dup(2)delle fd quando vengono aperti, ma collegamenti simbolici "magici" al file / dentry originale, che aprono il file da zero [1]. Si potrebbe essere implementato in libero / NetBSD o Solaris ...

Ma non è quello che è crackato per essere

Fondamentalmente dare il xpermesso (di esecuzione) significa anche dare il rpermesso (di lettura) su qualsiasi file che ha un 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

ktracenon è l'unico modo; se l'interprete è eseguibile dinamicamente collegato come perlo python, si potrebbe usare invece un LD_PRELOADhack ed che sovrascrive la read(2)funzione.

E no, renderlo setuid non impedirà a un utente normale di vederne il contenuto; potrebbe semplicemente eseguirlo ptrace(2), il che farà ignorare i bit setuid:

Come root:

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

Come utente normale:

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
       "

(scusate se questo non è il modo più diretto per dimostrarlo)

[1] questo potrebbe essere emulato su Linux usando binfmt_misc, ma l'interprete dovrà essere modificato, o dovrà essere usato un wrapper; vedi l'ultima parte di questa risposta per un esempio reso deliberatamente ridicolmente insicuro.

[2] o in generale, qualsiasi file che non causerà la execve()restituzione ENOEXEC.


-2

Sì, se sei un utente root, puoi eseguire il file senza autorizzazione di lettura

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

Ma se accedi con altri utenti, non puoi eseguire questo file

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

3
Questo in realtà non risponde alla domanda, perché root può ancora leggere il file anche senza autorizzazione.
wjandrea,

-5

Per rendere i tuoi script illeggibili ma eseguibili, hai 3 opzioni principali:

Prima opzione

Utilizzare il comando openssl per crittografarlo manualmente. E in futuro, quando si desidera eseguire lo script, è necessario eseguire di nuovo openssl manualmente e fornire la password per la decrittografia.

Crittografia con openssl:

cat yourscript.sh | openssl aes-128-cbc -a -salt -k yourpassword> yourscript.enc

Decrittazione con openssl:

cat yourscript.enc | openssl aes-128-cbc -a -d -salt -k yourpassword> yourscript.dec

yourscript.dec sarà lo stesso del tuo script originale yourscript.sh

Seconda opzione

Utilizzare un sito come www.Enscryption.com per crittografare automaticamente lo script e rendere eseguibile la versione crittografata dello script. Questo sito utilizza entrambe le funzionalità di crittografia di openssl e alcuni altri metodi di offuscamento per rendere abbastanza difficile per gli intrusi fare leva sui tuoi script o svelare i segreti che vuoi nascondere. Con questo sito, è possibile crittografare gli script di shell e gli script della riga di comando perl, python, ruby. Penso anche a PHP.

Terza opzione

Utilizzare uno strumento come shc . Sembra che non sia stato aggiornato dal 2012. Ma l'ho usato in passato. Devi compilare lo script per ciascun sistema operativo su cui desideri utilizzarlo, se il sistema operativo è diverso da quello che hai usato per compilarlo.

Sommario:

Se nascondere il codice è di grande importanza per te, fare affidamento solo su autorizzazioni e proprietà ti aiuterà, poiché chiunque abbia il root può accedervi. Questo è solo un dato di fatto. Quello che puoi fare, se vuoi davvero impedire a utenti non autorizzati di visualizzare il tuo codice è scrivere uno script attorno al comando openssl. Fai in modo che, prima dell'esecuzione dello script, richieda una password E dopo che è stata data la password, eseguirà lo script senza scriverlo in un file temporaneo. Se questo sembra troppo lavoro, le opzioni 2 e 3 dovrebbero essere sufficienti per i tuoi scopi.


Il link "shc" punta anche a una pagina di prima. Sei per caso affiliato con questa pagina / servizio?
phk,

3
Se digiti il ​​tuo script non sarà possibile eseguirlo senza chiave. Se hai inviato la chiave a un utente per eseguirla, sarà in grado di vederne il contenuto. Questa risposta è così stupida ...
erm3nda
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.