Esiste una shell che controlla per assicurarsi che il codice sia firmato?


19

Questa settimana stavo scherzando con PowerShell e ho scoperto che devi firmare i tuoi script in modo che possano essere eseguiti. Esiste una funzionalità di sicurezza simile in Linux relativa alla prevenzione dell'esecuzione degli script bash?

L'unica funzionalità simile a questa, di cui sono a conoscenza, è quella di SSH che richiede una determinata chiave.


2
Sembra un po 'una soluzione ad hoc per firmare il pacchetto. Non so se Windows abbia un pacchetto crittografico che firma come Linux.
Carattere jolly

6
@ leeand00 Uno script è un caso speciale di un pacchetto software e non vedo alcun motivo per individuarlo.
Gilles 'SO- smetti di essere malvagio' il

2
Il meccanismo a cui sono più affezionato è il modo in cui ChromeOS lo fa: mettere l'unico filesystem non contrassegnato noexecsu una partizione di sola lettura su un dispositivo a blocchi con firma dm-verity.
Charles Duffy,

1
source.android.com/security/verifiedboot parla dell'adozione da parte di Android di quella (inizialmente ChromeOS) funzionalità.
Charles Duffy,

1
Puoi considerare bash come un gruppo di comandi che possono essere digitati manualmente nell'interfaccia della riga di comando. Qual è il punto di limitare gli script quando è possibile digitare i contenuti nella riga di comando comunque?
Ding-Yi Chen,

Risposte:


11

Se stai bloccando la capacità degli utenti di eseguire script tramite, sudopuoi utilizzare la digestfunzionalità.
È possibile specificare l'hash di uno script / eseguibile in sudoerscui verrà verificato sudoprima di essere eseguito. Quindi, sebbene non sia uguale alla firma, ti dà una garanzia di base che lo script non è stato almeno modificato senza che anche i sudoer vengano modificati.

Se il nome di un comando è preceduto da Digest_Spec, il comando corrisponderà correttamente solo se può essere verificato utilizzando il digest SHA-2 specificato. Ciò può essere utile in situazioni in cui l'utente che invoca sudo ha accesso in scrittura al comando o alla sua directory principale. Sono supportati i seguenti formati digest: sha224, sha256, sha384 e sha512. La stringa può essere specificata in formato esadecimale o base64 (base64 è più compatto). Esistono diverse utility in grado di generare digest SHA-2 in formato esadecimale come openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.

http://www.sudo.ws/man/1.8.13/sudoers.man.html


Mi tratterrà fino a quando non leggerò SE Linux e lo farò bene.
leeand00,

13

Sì e no.

La distribuzione del software Linux funziona in modo leggermente diverso dalla distribuzione del software Windows. Nel mondo Linux (non incorporato), il metodo principale per distribuire il software è tramite una distribuzione (Ubuntu, Debian, RHEL, Fedora, Arch, ecc.). Tutte le principali distribuzioni hanno firmato i loro pacchetti in modo sistematico per circa un decennio.

Quando il software viene distribuito in modo indipendente, spetta al fornitore decidere come spedire il proprio software. I buoni fornitori forniscono fonti di pacchetti compatibili con le principali distribuzioni (non esiste un meccanismo di distribuzione unificato per tutto Linux: la distribuzione del software è uno dei principali punti di differenziazione tra le distribuzioni) e firmata con la chiave del fornitore. Le distribuzioni Linux raramente fungono da autorità di firma per i fornitori di terze parti (Canonical lo fa con i partner Ubuntu, ma copre pochissimi fornitori), e penso che tutte le principali distribuzioni utilizzino la rete di fiducia PGP anziché l'infrastruttura a chiave pubblica TLS, quindi spetta all'utente capire se vogliono fidarsi di una chiave.

Non esiste alcun meccanismo speciale che individua i pacchetti software costituiti da un singolo script da pacchetti software costituiti da un eseguibile nativo, un file di dati o più file. Né una verifica della firma è integrata in un comune interprete di script, poiché la verifica di un pacchetto software è una preoccupazione completamente ortogonale dall'esecuzione di uno script.

Penso che Windows annota i file con la loro origine e richiede la conferma dell'utente per eseguire un file la cui origine è "scaricata" anziché "locale". Linux non ha davvero un meccanismo simile. La cosa più vicina è l'autorizzazione all'esecuzione: un file scaricato non ha l'autorizzazione all'esecuzione, l'utente deve abilitarlo esplicitamente ( chmod +xsulla riga di comando o l'azione equivalente in un file manager).


2
FWIW, in aggiunta a questo PowerShell può essere configurato (dalle impostazioni dei criteri) per eseguire solo script firmati e questo criterio può essere configurato in modo che tutti gli script debbano essere firmati o solo script "origine remota" o nessun script. Funziona meglio in un ambiente AD con gestione delle chiavi e gestione delle politiche centrale. Si può essere bypassato :-)
Stephen Harris

@StephenHarris Beh sì, se lo imposti su bypass ...
leeand00

@ leeand00 - Apparentemente la codifica base64 funziona anche come bypass ma non so se sia stato chiuso nelle versioni più recenti di PowerShell.
Stephen Harris,

1
@ leeand00 - vedi darkoperator.com/blog/2013/3/5/… per un po 'di divertimento :-) Fondamentalmente passa lo script con codifica base64 come parametro sulla riga di comando :-) Abbastanza facile da avvolgere!
Stephen Harris,

2
SeLinux annota i file con la loro origine. È una delle sue premesse principali.
loa_in_

10

Linux non offre la possibilità di limitare l'esecuzione di script bash basati su firme digitali.

C'è del lavoro sull'autenticazione degli eseguibili binari. Vedi https://lwn.net/Articles/488906/ per informazioni.


Ottieni la risposta diretta senza suggerire una soluzione alternativa.
user394

8

In una parola, "no".

Linux non fa realmente distinzioni tra eseguibili e script; l' #!all'inizio è un modo per dire al kernel quale programma da eseguire per valutare l'ingresso ma non è l'unico modo in cui uno script può essere eseguito.

Quindi, per esempio, se ho una sceneggiatura

$ cat x
#!/bin/sh 
echo hello

Quindi posso eseguirlo con il comando

$ ./x

Ciò indurrà il kernel a tentare di eseguirlo, individuare #!e quindi eseguire effettivamente /bin/sh x.

Tuttavia, potrei anche eseguire una di queste varianti:

$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x

o anche

. ./x

Quindi, anche se il kernel ha cercato di imporre la firma a execlivello, possiamo bypassarlo eseguendo solo l'interprete con lo script come parametro.

Ciò significa che il codice di firma dovrebbe trovarsi nell'interprete stesso. E cosa impedirebbe a un utente di compilare la propria copia di una shell senza il codice di applicazione della firma?

La soluzione standard a questo non è usare la firma, ma usare i controlli di accesso obbligatori (MAC), come SELinux. Con i sistemi MAC è possibile specificare esattamente ciò che ogni utente può eseguire e livelli di transizione. Quindi, ad esempio, puoi dire "gli utenti normali possono eseguire qualsiasi cosa tranne che i processi del server Web e CGI possono accedere solo alle cose dalla /var/httpddirectory; tutto il resto viene rifiutato".


1
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?Non permettere l'esecuzione di eventuali eseguibili non firmati avrebbe fatto, se l'utente non ha la chiave di firma. Ci sono già diversi progetti * nix per questo.
Alzee,

2

Le distribuzioni Linux di solito hanno gnupg . Mi sembra che tutto ciò che desideri sia un semplice wrapper bash che controlla una firma gpg distaccata rispetto allo script dell'argomento e procede all'esecuzione dello script solo se il controllo ha esito positivo:

#!/bin/sh
gpgv2 $1.asc && bash "$@"

L'unica cosa che questo non presenta è l'esecuzione di una sceneggiatura che qualcuno ha appena realizzato ... da solo ...
leeand00

2

La contro-domanda che viene subito in mente è "Perché mai vorresti impedire agli utenti di eseguire i programmi che hanno scritto? " Esistono diverse possibilità:

  1. È letteralmente impossibile rilevare chi ha creato il codice in primo luogo. Il proprietario del file di script è chiunque abbia effettivamente salvato il contenuto di quel file, indipendentemente da dove provenga. Quindi far rispettare una firma è solo un complicato sostituto di una finestra di dialogo di conferma: "Sei sicuro di volerlo fare?" In Linux parte di questo problema viene risolto in modo trasparente con pacchetti firmati e mitigato dal fatto che gli utenti hanno accesso limitato per impostazione predefinita. Si prevede inoltre che l'utente sappia che l'esecuzione del codice altrui può essere pericolosa *.
  2. Allo stesso modo, firmare uno script è un'operazione molto più complessa rispetto al salvataggio di un file. Nel migliore dei casi, ciò spinge l'utente a rendersi conto che stanno eseguendo un'azione simile alla firma di un documento e deve ispezionare ciò che dice prima di continuare. Molto probabilmente garantisce semplicemente un livello minimo di competenza tecnica da parte dell'utente per poter eseguire lo script. Nel peggiore dei casi dimostra la volontà di saltare attraverso una lunga serie di cerchi per eseguire ciò che volevano. La competenza tecnica è assunta su Linux *.
  3. È più probabile che le persone rileveranno ovviamente codice dannoso quando digitano / incollano una serie di comandi sulla loro riga di comando. I frammenti di testo in chiaro che devono essere copiati e incollati di solito sono più piccoli della serie di comandi necessari per fare qualcosa di propriamente nefasto. L'utente può anche copiare e incollare attentamente ogni riga separatamente, comprendendo cosa succede mentre succede. Con uno script è possibile che l'utente non abbia mai visto il codice. Questa potrebbe essere una utile applicazione di script firmati, al costo fin troppo comune di compiacenza dopo la dodicesima volta che devi farlo.

* Questo probabilmente sta diventando sempre più vero man mano che sempre più persone iniziano a usare Linux


1

Il motivo per cui i sistemi si sono evoluti in modo diverso è che Linux ha l'attributo 'exec' e Windows utilizza le estensioni dei file per determinare l'eseguibilità.

Quindi in Windows è facile indurre l'utente a scaricare un file con estensione ".exe", ".bat", ".scr", che verrà nascosto per impostazione predefinita . Facendo doppio clic su quel file ti darebbe l'esecuzione di codice arbitrario. Quindi è stato creato un ampio meccanismo di tracciamento dell'origine e firma eseguibile / script per mitigare questo rischio.

Su Linux, potresti essere in grado di ottenere un file per l'utente, ma non puoi forzare facilmente l'impostazione del bit 'exec'. Inoltre, è possibile rendere "noexec" interi filesystem.

È comunque possibile eseguire esplicitamente uno script invocando l'interprete. È anche possibile creare script di shell in fase di esecuzione e convogliarli in "sh" o eseguire "sh -c".


0

Per impostazione predefinita, molti programmi di archiviazione non conservano i bit di esecuzione sui file contenuti. Ciò rende impossibile eseguire eseguibili arbitrari. Be 'quasi.

Il punto è, ciò che è stato descritto in un'altra risposta che la mancanza del bit di esecuzione non impedisce di passare tale script direttamente a bash. Mentre è discutibile che la maggior parte di tali script siano bashscript, lo shebang può specificare qualsiasi programma come interprete. Ciò significa che spetta all'utente eseguire l'interprete appropriato se decidono di ignorare la semantica eseguibile.

Anche se questo non è molto, copre praticamente la prevenzione dell'esecuzione di eseguibili non attendibili su * nix con solo kernel e shell .

Come ho accennato in uno dei commenti, c'è un altro livello di protezione SeLinux- che tiene traccia dell'origine dei file in base a una serie di regole. Un setup, SeLinuxad esempio, non consentirebbe a root di eseguire un eseguibile con set di bit eseguibili che è stato scaricato da Internet, anche se si copia e si sposta il file. Si può aggiungere una regola secondo cui tali file possono essere eseguiti solo attraverso un altro file binario che verificherebbe la firma, non diversamente da quanto menzionato nella domanda.

Quindi, alla fine, è una questione di configurazione di strumenti comunemente preinstallati e la risposta è .


molti programmi di archiviazione non conservano bit di esecuzione su file contenuti .. beh, questo è un po 'un handicap quando si desidera effettivamente usarlo per l'archiviazione. Fortunatamente tar non conservano il bit di esecuzione.
pjc50,

Devi usare tar -p source
loa_in_

-p, --preserve-permissions, --same-permissionssignifica estrarre informazioni sui permessi dei file (impostazione predefinita per superutente)
loa_in_

No, NON è necessario -p. Vedo cosa dice la pagina man, ma non è quello che succede. touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest- è eseguibile qui, e io non sono root.
domen,

Proverò a migliorare la mia risposta allora.
loa_in_
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.