it-swarm-eu.dev

Mantenere segreti dalla radice su Linux

Sto cercando modi per rafforzare un sistema Linux in modo che anche quando si ottiene l'accesso completo alla radice (con mezzi legittimi o non), alcuni segreti restino inaccessibili. Ma prima un po 'di storia.

Molti dei diversi modelli di sicurezza di Linux (SELinux, TOMOYO, ecc.) Si concentrano sulla limitazione di ciò che i processi possono fare mediante la politica e sull'assicurarsi che non necessitino di un accesso completo alla radice. Mirano a contenere eventuali exploit in modo che altre parti del sistema non possano essere compromesse. Tuttavia, sembra che questi non affrontino direttamente il caso in cui sia già stato acquisito il root completo, o, ancor più, mantenendo i segreti dell'utente root valido. Sembra che di solito questi possano essere semplicemente disattivati ​​dalla radice reale in fase di esecuzione.

Un altro approccio è limitare le modalità per ottenere il root completo senza restrizioni, ad esempio non consentendo tutto l'accesso a un utente root connesso in remoto, ma richiede un accesso dalla console fisica. Tuttavia, questo non è neanche il mio obiettivo: il presupposto è che tali protezioni siano già state superate e che la radice sia il più legittima possibile.

È ovvio che chiunque abbia accesso fisico alla macchina può archiviare tutto sul disco rigido e possibilmente anche tutto ciò che è memorizzato. È anche ovvio che se l'utente root ha il potere di modificare i file binari o le immagini del kernel, dopo il riavvio non è possibile fornire promesse di sicurezza. Sono interessato solo agli attacchi che possono essere eseguiti senza riavviare il sistema.

Inoltre, durante il processo di avvio, molto probabilmente i segreti verranno trasmessi attraverso molti luoghi e sono necessarie molte funzioni critiche per la sicurezza. È ovviamente ottimo se i segreti possono essere protetti anche durante il processo di avvio, ma ciò che è abbastanza per me è un passaggio durante l'avvio in cui è possibile eliminare privilegi elevati e dopo di che non è possibile recuperarli.

Quindi, con queste limitazioni, quali sono i modi su Linux per impedire all'utente root di accedere ad alcuni segreti?

  • Possono esserci file sul filesystem che non sono accessibili nemmeno alla radice completa in alcun modo, ma accessibili ad alcuni processi? Alcuni processi attualmente in esecuzione o anche nuovi processi avviati dai processi che attualmente hanno accesso?

  • I segreti possono essere mantenuti in memoria eseguendo i processi in modo tale che anche l'intera radice non possa accedervi in ​​alcun modo? Questi segreti possono essere trasmessi a nuovi processi in qualche modo che la radice non può influenzare?

Questa è una domanda difficile da scrivere in modo da ottenere risposte pertinenti per me, quindi cercherò di modificare la domanda per essere più specifica se necessario.


Le cose ovvie che vengono in mente che devono essere limitate sarebbero:

  • Disabilita l'accesso a/proc/mem

  • Disabilita l'accesso a/proc/<pid>/mem

  • Disabilita l'accesso a/proc/<pid>/fd/*

  • Disabilita il caricamento del modulo (solo dopo che alcuni moduli sono stati caricati, preferibilmente)

  • Disabilita l'accesso ptrace a qualsiasi processo

56
Nakedible

In realtà, è possibile limitare root if uno è pronto a definire una restrizione come fondamentalmente fidarsi del sistema operativo. Questo può essere fatto usando SELinux (che io conosco) e presumibilmente altri sistemi simili. Il miglior esempio che ho visto di SELinux usato in questo modo è Russell Coker's Play SELinux Machine .

Come breve panoramica di come funziona, il nome "root" non è speciale in Unix. L'UID 0 è. UID 0 significa "fidati di tutto ciò che dico". Questo vale in particolare per il modello di accesso standard utilizzato su Unices, Unixen o comunque si plurale "Unix".

LSM, o Linux Security Modules, ti consente di collegarti a tutto e di controllare/negare le azioni come ritieni opportuno. Nel caso di SELinux, le autorizzazioni SELinux vengono controllate dopo le autorizzazioni Unix, quindi il flusso è simile al seguente:

Event ----> Has Unix Permissions? ---> Has SELinux Permissions? ---> Let it happen

La fase successiva da capire è che ci sono, o sono state storicamente, versioni diverse della politica SELinux. Prima di entrare in quello, capire che in SELinux:

  • gli inode hanno tipi, suffissi _t, che potrebbe anche essere chiamato domini; e
  • gli utenti hanno ruoli, con suffisso _r.

Combinati, controllano quale azione può fare un utente in un determinato ruolo e cosa può fare un processo in un determinato dominio.

Ora, ci sono tre principali politiche SELinux:

  1. target. Questa è la politica di default per desktop come Fedora. L'idea del target è che i servizi di sistema e i demoni critici siano eseguiti in domini, ma molto di ciò che l'utente finale fa è eseguito in unconfined_u:unconfined_r:unconfined_t. Nessun premio per indovinare cosa significhi: se i permessi Unix funzionano, SELinux è effettivamente pass-through.
  2. strict. Questa norma prevede la rimozione di unconfined_u interamente. Questo non è un processo facile, specialmente sul desktop di Linux (ovvero init 5). In particolare, il modello di sicurezza X11 non è eccezionale e spesso richiede unconfined_t per alcune applicazioni. Tu puoi farlo , ma mi aspetto che lavorare con X11 sia più difficile (anche se non impossibile) soprattutto quando si eseguono applicazioni GUI che richiedono root. È in corso un progetto per fornire supporto per funzionalità simili a SELinux in X, chiamato XACE (X Access Control Extensions) .
  3. MLS. MLS è sinonimo di sicurezza multilivello e indica la fine della stringa di autorizzazione: user_u:system_r:httpd_content_t.s0-s2:c5-c7, ovvero quei numeri s e c in realtà significano qualcosa. Nello specifico formano un'impostazione nessuna lettura, nessuna scrittura in modo tale che, a meno che il processo non sia eseguito a un certo livello, le informazioni che possono vedere saranno limitate. L'idea di questo livello di informazione è di proteggere le risorse classificate: SELinux è stato originariamente sviluppato dalla NSA, presumibilmente per questo scopo.

Questo è il tuo background. Ora, secondo le pagine web (vedi FAQ ) root is UID 0 sulla macchina da gioco; tuttavia, root è impostato per funzionare come user_r e non sysadm_r nel rigoroso strict politica. Ciò significa che all'utente non sarà consentito eseguire funzioni amministrative dalla Shell.

Ciò che sarebbe interessante sapere, quindi, è lo stato degli altri processi che richiedono il root. Presumibilmente tali processi sono stati opportunamente etichettati e dispongono di politiche che consentono loro l'accesso richiesto. La domanda diventa quindi come amministrare il sistema e uno di questi processi può avviare una Shell nel contesto dell'utente. Se ciò può accadere, puoi comunque gestire un exploit.

Dato che la play machine è attualmente inattiva (al momento della stesura), sto lavorando su ipotesi qui; ma essenzialmente, avresti bisogno di un processo in esecuzione in sysadm_r e con UID 0 come target per un exploit. Supponendo che un tale processo esista ed è sfruttabile, potresti ancora arrivare al root. Per quanto riguarda ancora essere in grado di amministrare tramite root, ci sono due opzioni a cui posso pensare:

  • O esiste una transizione attendibile di qualche tipo che significa che root può quindi passare a sysadm_r (meno sicuro) oppure
  • Su diversi runlevel, si applica una politica diversa, quindi per amministrare la macchina si imposta il runlevel su 1 e la politica non limita root. Sto indovinando qui.

Sommario

Se la tua domanda è "posso farlo ora in modo semplice e sicuro?" la risposta è no. Se la tua domanda è "Sono pronto a conoscere SELinux, rimettermi in gioco con la mia distribuzione e sopportare un sacco di cose che non funzionano", la risposta è che è possibile vincolare root molto più della tua installazione media. Detto questo, ciò non ti rende in alcun modo invulnerabile agli exploit, non rende impossibile per un utente eludere questo controllo di accesso aggiuntivo né nel software né fisicamente.

Quindi sì, puoi rendere le cose invisibili alla radice; tuttavia, a parte l'onere tecnico aggiuntivo, valgono le stesse avvertenze per qualsiasi impostazione di controllo di accesso su qualsiasi utente normale: non esiste un proiettile d'argento.

Oh e palese autopromozione: potrebbe piacerti il ​​mio post sul blog memorizzazione dei segreti nel software . È sul blog di sicurezza stackexchange, quindi non mi sento così male nel promuoverlo. Essenzialmente, come puoi vedere, ci sono meccanismi per rendere la vita molto più difficile per un attaccante (e te), ma alla fine, è un caso di "tartarughe completamente giù", cioè fondamentalmente impossibile da fare.

33
user2213

Ho dovuto affrontare questo problema in precedenza, quando mi hanno avvicinato un cliente che voleva proteggere i "messaggi privati" tra gli utenti di un sito Web. È possibile proteggere alcuni dati in alcune circostanze, ma ciò è ragionevolmente limitato.

Il mio approccio era semplicemente quello di archiviare una versione crittografata della nota sul server e di inviarla (una volta autenticata ovviamente), quindi di decrittografarla interamente sul lato client. Ciò significa che, anche in caso di compromissione totale della sicurezza del server (ovvero accesso alla radice), le note sono rimaste sicure. I limiti di questo tuttavia:

  • I dati protetti sono protetti solo fino al punto di compromesso e non oltre. A seconda del metodo utilizzato per crittografare le informazioni, un server rootato può indurre l'utente a rivelare le chiavi di decrittazione (iniezione JavaScript o per client GUI nativi, emettere un aggiornamento client compromesso) o intercettare in altro modo le chiavi di decrittazione (se le chiavi sono basate allo stesso modo dell'autenticazione dell'utente, come una password, possono essere intercettati durante il processo di autenticazione lato server).
  • La trasmissione richiede un perfetto segreto in avanti, altrimenti i dati crittografati potrebbero essere intercettati, archiviati e quindi decifrati dopo il compromesso come discusso sopra.
  • Questo non protegge nulla se anche il client è compromesso. A meno che tu non stia elaborando i dati crittografati interamente nella tua testa (e se puoi, meriti un trofeo o qualcosa del genere), fornirai dati sensibili a qualcosa, e nulla è - perfettamente senza compromessi.
  • Non è possibile utilizzare questi dati lato server (ovvero a fini di indicizzazione) a meno che non vengano archiviati metadati decriptabili/in chiaro, che potrebbero rivelare ulteriori informazioni.

Fondamentalmente questo limita i potenziali usi per questo scenario e ci sono ancora punti deboli, ma è possibile che funzioni in alcune situazioni. L'hash delle password è un esempio (ragionevolmente riuscito) di "protezione contro i compromessi di root", in quanto anche l'accesso fisico non rivelerà le password di un utente (tranne ovviamente se tale password viene trasmessa dopo il compromesso).

Ci sono altri esempi in questo thread che vale la pena esaminare anche, ma riflettono sullo scenario di elaborazione lato client, usando il server semplicemente come un servizio di archiviazione sicuro.

TC

14
TC Fox

Possono esserci file sul filesystem che non sono accessibili nemmeno alla radice completa in alcun modo, ma accessibili ad alcuni processi? Alcuni processi attualmente in esecuzione o anche nuovi processi avviati dai processi che attualmente hanno accesso?

No. Quando un processo può accedervi, anche root. Se vuoi fare queste cose, dovrai modificare pesantemente l'intero sistema, possibilmente un sistema che avvia un kernel immutabile da qualche dispositivo di sola lettura e che nega il root a determinati accessi di file/memoria consentendo loro per altri utenti che root può " impersonare.

I segreti possono essere mantenuti in memoria eseguendo i processi in modo tale che anche l'intera radice non possa accedervi in ​​alcun modo? Questi segreti possono essere trasmessi a nuovi processi in qualche modo che la radice non può influenzare?

No. Vedi la risposta sopra.

Non puoi, per definizione, limitare l'accesso per il root. Se limiti l'accesso di root, non è più un utente root.

Se volessi negare l'accesso root ai segreti, allora proverei a nasconderli. Contenitori crittografici, forse nascosti nella memoria di swap o da qualche altra parte e accessibili solo con una password o qualche altro tipo di steganografia. È dannatamente difficile trovare un ago in un pagliaio, anche se non impossibile.

6
Falcon

Esistono diversi modi indiretti attraverso i quali root può finire per eseguire codice arbitrario. È possibile disabilitarli e in effetti alcuni framework di sicurezza potrebbero disabilitarli, ma compromettono la capacità di root di eseguire attività amministrative.

Ad esempio, root può leggere e scrivere direttamente sui dischi, ignorando qualsiasi tipo di autorizzazione del filesystem. Puoi togliere questa capacità, ma root non sarà in grado di spostare un filesystem completo su un nuovo disco in caso di emergenza.

Il root può caricare i moduli del kernel, e quindi può fare tutto ciò che il kernel può fare. Puoi togliere questa capacità, ma poi precludi il caricamento dei driver per supporti hot plug. (Ciò può essere auspicabile nel 0,001% delle installazioni unix, ma non è il caso generale.)

La radice può aggiornare i file eseguibili che consentono agli utenti di accedere, come login o sshd. Questi daemon gestiscono l'autenticazione dell'utente, quindi se controlli il loro codice, puoi iniettare una backdoor. Puoi togliere questa capacità, ma root non sarà in grado di eseguire aggiornamenti di sicurezza.

La radice può creare e rimuovere utenti e modificare le credenziali di autenticazione: se puoi modificare /etc/passwd per aggiungere un account, puoi anche modificarlo per rendere temporaneamente un account senza password. Puoi rimuovere questa capacità rendendo alcuni file di sola lettura anche per root, ma poi finirai con un sistema in cui non puoi creare o rimuovere account utente senza riavviare.

I framework di sicurezza creano effettivamente utenti con radice limitata che sono root solo in un sottoinsieme del sistema - root solo in una macchina virtuale, non nel sistema "reale". Questa radice limitata perde la possibilità di eseguire attività amministrative sul sistema reale. Penso che la virtualizzazione sia ciò che stai cercando.

Questo è relativamente facile da ottenere usando un sistema selinux a "due chiavi": root non ha permessi per fare nulla, e qualche altro utente senza permessi di root fa, quindi per cambiare roba, devi prima essere il non root altro utente, quindi "su" su root per apportare la modifica.

Nessuno degli utenti in isolamento può fare o vedere nulla.

Sto usando questo. Funziona davvero bene.

3
cnd

L'esigenza effettiva non è ben definita nella domanda, ma non sono state menzionate due potenziali soluzioni a cui si fa allusione:

  • Contenitori
  • HSM

I contenitori - che sono ovviamente solo un approccio più sensibile dal punto di vista architettonico a ciò che è stato fatto frammentariamente con strumenti come jail e SELinux - possono essere rilevanti nel contesto di una riformulazione della domanda - esiste un modo in cui un logico unix-like il sistema può essere esposto agli aggressori in modo tale da poter essere compromesso da root ma i segreti del sistema fisico sono ancora protetti. Con i container ci stiamo avvicinando a questo obiettivo. Un recente documento del gruppo di sicurezza NCC merita una lettura: https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/june/container_whitepaper.pdf

Gli HSM sono dispositivi di crittografia hardware che impediscono il recupero delle chiavi di decodifica tramite metodi fisici o logici, quindi potrebbe essere una risposta alla domanda riformulata poiché ho segreti che devo decrittografare in modo sicuro, cosa devo fare con le chiavi.

2
Jonah Benton

Come ha detto Falcon, l'utente root per definizione ha accesso a tutte queste cose, o non è più l'utente root.

Il kernel controlla tutto l'hardware, quindi una volta che sei root hai lo stesso accesso. Hai davvero bisogno della virtualizzazione, quindi il tuo utente root è solo root per il sistema operativo virtualizzato su cui è in esecuzione e alcuni Hypervisor si trovano al di fuori di questo root. (per non dire che gli hypervisor non sono sfruttabili, ma quello che stai cercando di fare è equivalente a questo).

2
Bradley Kreider

Hai provato Grsecurity? Può limitare efficacemente gli utenti root in ogni modo possibile. https://grsecurity.net/

Grsecurity, abbinato a PaX, rende la tua scatola una fortezza inespugnabile ... se lo fai nel modo giusto

2
Jauzsika