Domanda:
Il permesso di esecuzione di Unix può essere facilmente bypassato. È superfluo o qual è l'intenzione dietro di esso?
Martin Erhardt
2014-09-02 04:28:07 UTC
view on stackexchange narkive permalink

L'autorizzazione di lettura unix è in realtà la stessa dell'autorizzazione di esecuzione, quindi se ad es. un processo ha accesso in scrittura ed è anche in grado di eseguire lo stesso file.

Questo può essere fatto abbastanza facilmente: prima questo processo deve caricare il contenuto del file, che deve essere eseguito, in un buffer. Successivamente chiama una funzione da una libreria condivisa che analizza l'ELF nel buffer e lo carica negli indirizzi giusti (probabilmente sovrascrivendo il vecchio processo come al solito, quando si chiama execvp). Il codice salta al punto di ingresso del nuovo programma e viene eseguito.

Sono abbastanza sicuro che Dennis Ritchie e Ken Thompson fossero a conoscenza di questo problema. Allora perché hanno inventato questo permesso, qual è l'intenzione dietro di esso e qual è il senso di esso, se non può impedire l'esecuzione di alcun processo di qualsiasi utente con accesso in lettura? C'è anche un tale senso o è superfluo?

Potrebbe anche essere un serio problema di sicurezza, ci sono sistemi che si affidano alla forza dei permessi rw- o r--?

Un punto importante è che _all_ metodi di bypass di -x ignoreranno i privilegi elevati (setuid bit, funzionalità file, regole basate sul percorso) che ha il programma originale.
Sono sbalordito dalla votazione, ecc. Qui. L'unica risposta corretta è un commento.
Perché dovrei fare di tutto per eseguire un file che non voglio eseguire?
jjanes Beh, ho pensato che sarebbe stato un qualche tipo di problema di sicurezza, se gli utenti fossero in grado di eseguire programmi a cui non sono autorizzati.
@MartinErhardt: Diventa un problema di sicurezza solo se il programma può _fare di più_ di quanto l'utente potrebbe normalmente fare con altri metodi. Ad esempio, Wireshark installa `/ usr / bin / dumpcap` con privilegi elevati (setuid bit o privilegio` cap_net_raw`), quindi eseguendolo un utente potrebbe fare cose (catturare il traffico di rete) che il sistema operativo non consentirebbe direttamente. Ovviamente solo i membri del gruppo "wirehark" hanno il permesso + x; tutti gli altri utenti possono solo leggere il programma.
@MartinErhardt: Potresti trovare interessanti [questi post di Old New Thing] (https://www.google.com/search?q=site%3Ablogs.msdn.com%2Fb%2Foldnewthing%2F+airtight+hatchway), in particolare [questo] (http://blogs.msdn.com/b/oldnewthing/archive/2009/04/09/9539191.aspx) o [questo] (http://blogs.msdn.com/b/oldnewthing/archive/2008/ 05/16 / 8510192.aspx), con esempi di cose che sembrano problemi di sicurezza, ma in realtà non ti permettono di fare nulla più del normale.
Sei risposte:
Mark
2014-09-02 06:40:42 UTC
view on stackexchange narkive permalink

Esiste un modo ancora più semplice per bypassare il permesso di "esecuzione": copiare il programma in una directory di tua proprietà e impostare il bit di "esecuzione".

Il permesso di "esecuzione" non è una misura di sicurezza . La sicurezza è fornita a un livello inferiore, con il sistema operativo che limita azioni specifiche. Questo viene fatto perché, su molti sistemi simili a Unix (specialmente ai tempi di Ritchie e Thompson), si presume che l'utente sia in grado di creare i propri programmi. In una situazione del genere, l'utilizzo dell'autorizzazione "esecuzione" come misura di sicurezza è inutile, poiché l'utente può semplicemente creare la propria copia di un programma sensibile.

Come esempio concreto, eseguire fdisk come utente non privilegiato per provare a rimescolare la tabella delle partizioni del disco rigido:

  $ / sbin / fdisk / dev / sda Benvenuto in fdisk (util-linux 2.24.1). rimangono solo in memoria, fino a quando non decidi di scriverli. Fai attenzione prima di usare il comando di scrittura .... Cambiato il tipo di partizione 'Linux' in 'Hidden NTFS WinRE'.Command (m per aiuto): wfdisk: impossibile scrivere disklabel : Descrittore di file errato  

L'ultima riga è fdisk che cerca di ottenere un descrittore di file "in scrittura" per il disco rigido e non riesce, perché l'utente che sto utilizzando perché non ha il permesso per farlo.

Lo scopo del permesso di "esecuzione" è duplice: 1) per dire al sistema operativo quali file sono programmi e 2) per dire all'utente quali programmi possono eseguire. Entrambi sono consultivi piuttosto che obbligatori: puoi creare un sistema operativo perfettamente funzionante senza il permesso, ma migliora l'esperienza dell'utente.

Come sottolinea R .., c'è un caso particolare in cui il "execute L'autorizzazione "viene utilizzata per la sicurezza: quando un programma ha anche impostato il bit" setuid ". In questo caso, l'autorizzazione "esecuzione" può essere utilizzata per limitare chi è autorizzato a eseguire il programma. Qualsiasi metodo per aggirare il permesso "execute" eliminerà anche lo stato "setuid", quindi non ci sono rischi per la sicurezza qui.

Nota `bash script.sh` non necessita dell'autorizzazione di esecuzione su` script.sh`. Il file viene semplicemente letto dalla shell, tecnicamente.
Volker Siegel più precisamente la shell esegue il fork da sola e dup2 il file di script dato come argomento a 0, se c'è il permesso di esecuzione e nessuna magia ELF.
Quindi lo scopo più importante nella pratica del permesso di esecuzione oggi è quello di dire alla shell che un file è uno script eseguibile, anche se non può essere eseguito come binario con execve.
Mentre un altro scopo importante è impostare il permesso di esecuzione senza il permesso di lettura per impedire agli utenti di leggere o copiare il binario, come affermato da Guntram Blohm.
Il bit di esecuzione consente anche di rendere leggibile un file con il bit `setuid` senza consentire all'utente di eseguirlo come proprietario del file. Non sono sicuro del motivo per cui vorresti farlo, ma in questo caso funge da misura di sicurezza.
@AaronDufour: Puoi avere il processo `setuid` eseguibile dal gruppo e non da altri.
In realtà l'uso dell'autorizzazione di esecuzione con setuid è forse l'uso più importante del bit + x. È un peccato che la risposta accettata non lo menzioni nemmeno.
@R .., c'è qualche motivo per avere un file con il bit setuid ma * non * il bit di esecuzione?
@Mark: Sono disponibili più bit di esecuzione: utente, gruppo e mondo. Come ha notato Jan Hudec, è pratica molto comune creare binari setuid eseguibili solo da un particolare gruppo. Ovviamente su un sistema con ACL potresti anche usare un ACL esplicito per controllare chi ha il permesso + x.
Bene Simon Richter lo ha sottolineato già nella nostra discussione sudo di seguito, ma è bene averlo nella risposta accettata conclusiva, perché sembra essere uno scopo molto importante di tale autorizzazione.
@JanHudec Volevo implicarlo come un caso utile. I voti rendono chiaro che ho comunicato male, quindi grazie per averlo reso esplicito.
"Qualsiasi metodo per aggirare l'autorizzazione" execute "eliminerà anche lo stato" setuid ", quindi non ci sono rischi per la sicurezza qui." - Questo è vero, ma non importante, poiché l'utente che effettua la copia può reimpostare il bit `setuid`. La cosa importante è che la copia è di proprietà di un utente diverso (cioè, l'utente che copia), quindi anche con il bit `setuid` impostato, non consente a quell'utente di eseguirlo come proprietario del file originale.
Come Helfire ha appena sottolineato, il permesso di esecuzione può essere molto importante in termini di sicurezza, perché uno mancante impedisce agli utenti di passare a una directory.
Sarebbe bello se potessi enumerare tutti questi casi d'uso nella tua risposta principale (1., 2.).
Non ho considerato + x applicato alle directory perché la domanda riguardava + x applicato ai file.
Guntram Blohm supports Monica
2014-09-02 13:07:24 UTC
view on stackexchange narkive permalink

È possibile impostare il bit di esecuzione, ma non il bit di lettura, su un file eseguibile. In questo modo, nessuno sarà in grado di copiare il file, ma le persone possono eseguirlo comunque.

Questo è abbastanza inutile oggi, perché a) funziona solo per i programmi compilati, non con gli script (sulla maggior parte dei sistemi) ; b) oggigiorno, con il 90% di tutti gli Unix che è Linux, le persone possono copiare gli eseguibili praticamente da qualsiasi luogo, ec) lo spazio su disco occupato da un eseguibile copiato non ha molta importanza.

Tuttavia, c'erano lo utilizzava ai vecchi tempi.

Il sistema Unix che usavo a scuola, 30 anni fa, era molto limitato in RAM e spazio su disco. In particolare, il file system / usr / tmp era molto piccolo, il che causava problemi quando qualcuno cercava di compilare un programma di grandi dimensioni. Naturalmente, gli studenti non avrebbero dovuto scrivere comunque "programmi di grandi dimensioni"; i programmi di grandi dimensioni erano tipicamente codici sorgente copiati da "qualche parte". Molti di noi hanno copiato / usr / bin / cc in / home / <myname> / cc e hanno utilizzato dd per patchare il binario in modo che utilizzi / tmp invece di / usr / tmp , che era più grande. Naturalmente, questo ha solo aggravato il problema: lo spazio su disco occupato da queste copie era importante in quei giorni, e ora / tmp si riempiva regolarmente, impedendo anche ad altri utenti di modificare i propri file. Dopo aver scoperto cosa era successo, gli amministratori di sistema hanno eseguito un chmod go-r / bin / * / usr / bin / * che ha "risolto" il problema e cancellato tutte le nostre copie del compilatore C.

Un altro uso è dire alla shell quali file devono essere eseguiti e quali no. Non vuoi che venga eseguito un file di testo casuale perché hai digitato il suo nome; il bit x fornisce un modo per evitare ciò. (In questi giorni, la shell poteva solo guardare l'inizio del file ed eseguirlo solo se inizia con #! , ma questo è stato introdotto molto più tardi). Anche la funzione di completamento di bash suggerirà file con bit eseguibili solo quando digiti un comando.

Il file che inizia con "#!" si chiama shebang non è vero?
Shebangs dichiara solo quale interprete deve essere usato per interpretare, non dice alla shell che il programma è affatto uno script e può essere eseguito, anche se non può essere eseguito dal sistema operativo usando exec *. Quindi il permesso di esecuzione è ancora necessario in questo caso.
Sì, almeno concedo sempre a [Noone] (http://en.wikipedia.org/wiki/Peter_Noone) i permessi di lettura sui sistemi che gestisco.
E il problema dell'esecuzione accidentale era aggravato dal fatto che a quei tempi era considerato normale avere `.` in` $ PATH`, quindi i programmi nella directory corrente potevano essere eseguiti digitando i loro nomi senza `. /` prefisso.
Si noti che le shell (e execvp (), env, xargs, find -exec ...) sono _meant_ per eseguire file di testo eseguibili senza "#!" Con "sh". In realtà questo è l'unico modo per eseguire gli script specificato da POSIX e dalle specifiche Unix. Nota che su Linux, `.` è ancora davanti al PATH predefinito che ottieni (per execvp ()) quando PATH env var non è impostato.
Non potresti collegare un debugger al processo o anche avviare l'eseguibile con `LD_PRELOAD` e scaricare l'immagine principale da lì, anche se il bit di lettura non è impostato?
Simon Richter
2014-09-02 20:46:22 UTC
view on stackexchange narkive permalink

Esiste un modo già pronto per eseguire un file arbitrario: passarlo come argomento al linker dinamico (che è l'interprete appropriato per un eseguibile caricato dinamicamente). Per esempio. sotto Linux,

  cp / bin / ls / tmp / chmod -x /tmp/ls/lib/ld-linux.so.2 / tmp / ls  

Tuttavia, questo ha la stessa limitazione della lettura del file e del salto nel codice: i bit setuid non vengono valutati.

Ai vecchi tempi, spesso hanno binari come /bin/su:

  -rwsr-xr-- root wheel ... / bin / su  

Solo i membri del gruppo wheel , che gli amministratori di sistema tenevano tagliato alle persone che conoscono la password root sarebbero persino in grado di eseguire il comando su , quindi, anche se in quel binario esistesse un buffer overflow, consentendo ai chiamanti di aggirare la sicurezza, l'exploit sarebbe comunque utilizzabile solo da persone che conoscono la password.

Conosco questa cosa della ruota da quando ho configurato archlinux la prima volta. Una cosa che non capisco della tua domanda è, perché è necessario eseguire un overflow del buffer in su. Ho pensato che potesse essere facilmente eseguito da ogni utente che utilizza il metodo del linker dinamico sopra menzionato?
Sì, ma verrebbe eseguito senza setuid, come utente chiamante, rendendolo inutile per l'attacco.
user54909
2014-09-03 23:42:55 UTC
view on stackexchange narkive permalink

Sono sorpreso che nessun altro abbia fatto riferimento a un altro uso di + x bit: directory. Forse stai cercando di eseguire (esempio) qualcosa in / bin (script di shell o altro), ma c'è di più per eseguire bit che file (ovviamente, una directory È un file ma è un diverso tipo di file).

Se hai accesso + x su una directory ma -r su quella stessa directory, avrai le seguenti capacità:

  • Se conosci il nome di un file ( o directory) in quella directory, puoi elencarla (ad esempio, ls su di essa). Tuttavia, devi conoscere il nome.
  • Non puoi modificarlo (tramite il comando cd o la chiamata di sistema chdir).

Se invece hai -x e + r, puoi fare quanto segue:

  • Non puoi passare alla directory (come sopra).
  • Puoi elencare i file. Ma poiché non hai + x l'accesso alla directory, non puoi accedere ai file stessi.
  • Questo significa anche che non puoi aggiornare (solo timestamp o altro) e nemmeno puoi aprirli in un editor di testo (o cat, o ...).

Se hai + rx allora puoi fare tutto questo (tranne che hai bisogno + w per scrivere nella directory stessa, vale a dire creare nuovi file; la modifica dei file funziona, la rimozione no, la creazione no)

E sì, questo significa che è possibile che alcune persone visualizzino o modifichino i file ma solo se conoscono il percorso esatto ad esso ( fintanto che hanno i diritti di modifica, comunque). E sì: ls è list e questo vale per la ricerca nelle directory. Quindi, in sintesi: l'esecuzione di una directory sta cambiando in essa (per qualsiasi motivo). Ovviamente i bit tutti insieme sono ciò che conta davvero.

kasperd
2014-09-02 17:40:28 UTC
view on stackexchange narkive permalink

Se per qualche motivo desideri mantenere segreto il codice binario, puoi rendere il programma eseguibile senza che sia leggibile. Ciò non è utile se quegli utenti hanno accesso fisico alla macchina. Inoltre non è utile se il codice sorgente o binario è ampiamente disponibile. Quindi questo è un caso d'uso abbastanza limitato.

Se il programma ha un bit setuid o setgid, l'accesso in esecuzione fa qualcosa di più di quello che può essere ottenuto leggendo il binario. Un approccio consiste nel creare un eseguibile setuid che sia eseguibile solo per un gruppo specifico. Se era leggibile in tutto il mondo, le persone al di fuori di quel gruppo non potevano ancora copiarlo e utilizzare il bit setgid sull'eseguibile originale. (Sebbene nella maggior parte dei casi preferirei usare setgid piuttosto che setuid, e quindi usare il gruppo sulla directory per controllare chi può accedere all'eseguibile.)

Di solito il bit eseguibile è semplicemente usato per indicare quali file sono programmi innanzitutto. In questo modo il completamento può funzionare meglio e non si eseguono accidentalmente eseguibili indesiderati.

Se si desidera impedire agli utenti di copiare un eseguibile e di eseguirlo, è possibile montare le directory home con noexec . Affinché ciò abbia senso, devi usare noexec su ogni file system, dove l'utente può scrivere qualsiasi cosa.

Anche questo non è utile se l'utente sa come usare un debugger.
@NateEldredge Ovviamente solo root ha il permesso di allegare un debugger a un eseguibile suid o sgid. Se si collega il debugger prima di eseguire l'eseguibile, suid e sgid vengono semplicemente ignorati. Se si esegue prima l'eseguibile suid o sgid e si tenta di collegare un debugger in un secondo momento, l'eseguibile non potrà collegarsi. Per i file senza autorizzazioni di lettura, la situazione è meno chiara.
@NateEldredge Per un eseguibile in esecuzione per il quale non si dispone delle autorizzazioni di lettura, non è consentito allegare un debugger. Ma se colleghi prima un debugger e poi esegui un eseguibile che hai il permesso di eseguire ma non di leggere, viene eseguito. Ma questo significa che il debugger potrebbe accedere banalmente a tutte le pagine mappate dall'eseguibile. Questa sembra una chiara violazione della mancanza di autorizzazioni di lettura. È un bug o è specificato da qualche standard?
http://unix.stackexchange.com/questions/153471/tracing-executable-without-read-permissions
* No * misure di sicurezza sono utili se l'utente ha accesso fisico alla macchina.Bene, voglio dire che sono utili per mantenere le persone oneste oneste (come un lucchetto su un cancello che si rompe facilmente) ma se qualcuno vuole davvero entrare non lo fermerà.Ma questo è vero per tutte le misure tecniche di sicurezza, non solo per `-r + x`.
Luis Colorado
2014-09-04 17:07:46 UTC
view on stackexchange narkive permalink

Il permesso di esecuzione del bit viene controllato dal kernel durante l'esecuzione della chiamata di sistema exec (2) (e cugini). Ne avrai bisogno solo per eseguire programmi a livello di kernel.

Solo i programmi con quel bit attivo (qualunque sia quello che ti colpisce come proprietario, gruppo o altri è ciò che viene controllato) possono essere exec () edito dal kernel.

Un'altra cosa diversa è ciò che fa la shell quando interpreta uno script di shell o perl, o qualsiasi altro interprete possiate avere. Sugli script, il kernel controlla il #! ... all'inizio del file come un numero magico, e lancia la shell indicata lì (avrai bisogno anche del permesso di esecuzione per la shell), e tu sono necessari i permessi di lettura su quello script, poiché la shell deve aprirlo e leggerlo per essere interpretato. Per gli script di shell avrai bisogno del permesso di lettura e del permesso di esecuzione. Ma per gli script di shell hai solo bisogno dei permessi di lettura, poiché puoi sempre eseguire uno script di shell eseguendo la shell e passando lo script di shell come parametro (o file di input )

Ovviamente, come è stato sottolineato, il bit di esecuzione può essere circoscritto copiando il programma e rendendolo eseguibile, ma non sarai in grado di copiarlo se non lo hai letto permessi per fare quella copia (continui ad essere in grado di eseguirla).

Prova a cambiare (come root ovviamente) i permessi a ls (1) e rendilo 0111 ( --- x - x - x ) e prova a farne una copia eseguibile, e vedi come non riesci a ottenere la tua copia eseguibile, anche se continui a essere in grado di eseguirlo.

Nelle directory, eseguire bit significa una cosa diversa. Il kernel usa il permesso ' x ' quando iterando attraverso il percorso (nella funzione kernel namei () ) quindi se non hai i permessi di esecuzione su una directory, non puoi o usarlo, né i file accessibili attraverso di esso. Anche tu puoi leggere il contenuto di una directory con permessi di lettura, ma non puoi accedere ai file in essa contenuti. Oppure, al contrario, puoi avere i permessi di esecuzione su una directory ma non l'accesso in lettura e sarai in grado di usare i file all'interno, ma non sarai in grado di vedere il contenuto della directory.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...